Class: SidenavResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/nexmo_developer/app/presenters/sidenav_resolver.rb

Constant Summary collapse

IGNORED_PATHS =
['..', '.', '.DS_Store'].freeze

Instance Method Summary collapse

Constructor Details

#initialize(path:, language:, namespace: nil) ⇒ SidenavResolver

Returns a new instance of SidenavResolver.



4
5
6
7
8
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 4

def initialize(path:, language:, namespace: nil)
  @path      = path
  @language  = language
  @namespace = namespace
end

Instance Method Details

#directories(path, name = nil) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 18

def directories(path, name = nil)
  data = { title: (name || path), path: path }
  data[:children] = []
  # Find all markdown files on disk that are children
  Dir.foreach(path) do |entry|
    next if entry.start_with?('.')
    next if IGNORED_PATHS.include? entry

    full_path = File.join(path, entry)
    next if documentation_index?(full_path)

    if File.directory?(full_path)
      config = if tabbed_folder?(full_path)
                 YAML.safe_load(File.read("#{full_path}/.config.yml"))
               end

      if config && config['tabbed']
        data[:children] << { title: config['title'], path: full_path, is_tabbed?: true }
      else
        data[:children] << directories(full_path, entry)
      end
    else
      doc_path = Nexmo::Markdown::DocFinder.find(root: @path, document: full_path, language: @language, strip_root_and_language: true).path
      data[:children] << { title: entry, path: doc_path, is_file?: true }
    end
  end

  # Do we have tasks for this product?
  product = path.sub(%r{#{Rails.configuration.docs_base_path}/\w+/\w+/}, '')

  if DocumentationConstraint.products_for_routes.include? product
    tasks = TutorialList.by_product(product)

    # If we have use cases and tutorials, output them
    if tasks['tutorials'].any?
      data[:children] << { title: 'tutorials', path: "/#{product}/tutorials", children: tasks['tutorials'].map(&:as_json) }
    end

    if tasks['use_cases'].any?
      # Otherwise show use_case as the top level
      data[:children] << { title: 'use-cases', path: "/#{product}/use-cases", children: tasks['use_cases'] }
    end
  end

  sort_navigation(data)
end

#document_meta(item) ⇒ Object



114
115
116
117
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 114

def document_meta(item)
  doc = Nexmo::Markdown::DocFinder.find(root: item[:root] || @path, document: item[:path], language: @language, strip_root_and_language: true).path
  YAML.load_file(doc)
end

#item_navigation_weight(item) ⇒ Object



103
104
105
106
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 103

def item_navigation_weight(item)
  key = navigation_key(item)
  Navigation::WEIGHT[key] || 1000
end

#itemsObject



10
11
12
13
14
15
16
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 10

def items
  if @path.starts_with?('app/views')
    directories(@path)[:children]
  else
    directories("#{@path}/#{I18n.default_locale}")[:children]
  end
end


108
109
110
111
112
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 108

def navigation_weight_from_meta(item)
  return 1000 unless item[:is_file?]

  document_meta(item)['navigation_weight'] || 1000
end

#path_to_url(path) ⇒ Object



99
100
101
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 99

def path_to_url(path)
  strip_namespace(path).gsub('.md', '')
end

#sort_navigation(context) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 65

def sort_navigation(context)
  # Sort top level
  context[:children].sort_by! do |item|
    configuration_identifier = url_to_configuration_identifier(path_to_url(item[:path]))
    options = configuration_identifier.split('.').inject(Navigation::OVERRIDES) { |h, k| h[k] || {} }

    sort_array = []
    sort_array << (options['navigation_weight'] || 1000) # If we have a path specific navigation weight, use that to explicitly order this
    sort_array << (item[:is_file?] ? 0 : 1) if context[:path].include? 'code-snippets' # Directories *always* go after single files for Code Snippets (priority 1 rather than 0). This even overrides config entries
    sort_array << item_navigation_weight(item) # If we have a config entry for this, use it. Otherwise put it at the end
    sort_array << (item[:is_file?] ? 0 : 1) # If it's a file it gets higher priority than a directory
    sort_array << navigation_weight_from_meta(item) # Use the config entry if we have it. Otherwise it goes to the end
    sort_array
  end

  # Sort children if needed
  context[:children].each do |child|
    sort_navigation(child) if child[:children]
  end

  context
end

#strip_namespace(path) ⇒ Object



92
93
94
95
96
97
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 92

def strip_namespace(path)
  path = path.gsub('.yml', '').sub("#{Rails.configuration.docs_base_path}/_use_cases/", 'use-cases/')
  path = path.gsub('.yml', '').sub('config/tutorials/', '/tutorials/')
  path = path.gsub('.yml', '').sub("#{Rails.configuration.docs_base_path}/", '')
  path.sub(%r{\w+/\w+/}, '')
end

#url_to_configuration_identifier(url) ⇒ Object



88
89
90
# File 'lib/nexmo_developer/app/presenters/sidenav_resolver.rb', line 88

def url_to_configuration_identifier(url)
  url.tr('/', '.')
end