Module: Howdoc::Navigation
- Defined in:
- lib/howdoc/navigation.rb
Overview
The menu, and the links from one guide to the next.
A guide is written the moment its test finishes, when no other guide is known yet -- tests run in forked workers and each one writes its own page -- so a guide cannot draw a menu of guides. It leaves an empty
Filling in rather than re-rendering: the steps a guide was made of are long gone by then, but its page is not, and this gem wrote that page. Running the pass again simply replaces what it wrote the last time.
A template that carries no placeholder is left exactly as it is, so an application with its own page chrome loses nothing by not having one.
Class Method Summary collapse
- .counterpart(record, records) ⇒ Object
- .destination(locale, record, by_locale) ⇒ Object
-
.fill(markup, name) ⇒ Object
Stripped, so that filling a page in a second time leaves it exactly as the first time left it: the pass runs once per suite and again at the end of a run, and a page that grew a blank line each time would show up as changed in a repository for no reason at all.
-
.install(by_locale, root: Howdoc.config.root) ⇒ Object
Writes the menu and the pager into every guide.
-
.label(locale) ⇒ Object
A language names itself in its own language, which is how a reader who cannot read the current page still recognises the way out of it.
-
.languages(current_locale:, by_locale:, record: nil) ⇒ Object
The same guide in the other languages the application publishes.
- .nav(record, records, by_locale) ⇒ Object
- .ordered(locales) ⇒ Object
- .pager(record, records, position) ⇒ Object
- .placeholder(name) ⇒ Object
- .write(record, records:, position:, by_locale:, root:) ⇒ Object
Class Method Details
.counterpart(record, records) ⇒ Object
99 100 101 102 103 |
# File 'lib/howdoc/navigation.rb', line 99 def counterpart(record, records) return records.find { |other| other.id == record.id } unless record.id.nil? records.find { |other| other.permalink == record.permalink } end |
.destination(locale, record, by_locale) ⇒ Object
93 94 95 96 97 |
# File 'lib/howdoc/navigation.rb', line 93 def destination(locale, record, by_locale) counterpart = record && counterpart(record, by_locale[locale] || []) "../#{locale}/#{counterpart ? counterpart.filename : Registry::INDEX_FILENAME}" end |
.fill(markup, name) ⇒ Object
Stripped, so that filling a page in a second time leaves it exactly as the first time left it: the pass runs once per suite and again at the end of a run, and a page that grew a blank line each time would show up as changed in a repository for no reason at all.
49 50 51 |
# File 'lib/howdoc/navigation.rb', line 49 def fill(markup, name) markup.sub(placeholder(name)) { yield.strip } end |
.install(by_locale, root: Howdoc.config.root) ⇒ Object
Writes the menu and the pager into every guide. by_locale is the sorted
records the index was built from, so the menu lists the guides in the same
order the index does.
24 25 26 27 28 29 30 |
# File 'lib/howdoc/navigation.rb', line 24 def install(by_locale, root: Howdoc.config.root) by_locale.each_value.flat_map do |records| records.each_with_index.filter_map do |record, position| write(record, records:, position:, by_locale:, root:) end end end |
.label(locale) ⇒ Object
A language names itself in its own language, which is how a reader who cannot read the current page still recognises the way out of it.
107 108 109 |
# File 'lib/howdoc/navigation.rb', line 107 def label(locale) Narrator.phrase(:languages, locale, locale:, default: locale.to_s.upcase) end |
.languages(current_locale:, by_locale:, record: nil) ⇒ Object
The same guide in the other languages the application publishes.
Matched by identifier rather than by file name: a guide with a translated heading gets a translated file name, so "1.3" is the only thing the two pages are sure to have in common. A guide that was never written in the other language points at that language's index instead of nowhere.
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/howdoc/navigation.rb', line 80 def languages(current_locale:, by_locale:, record: nil) ordered(by_locale.keys).map do |locale| current = locale.to_s == current_locale.to_s { code: locale.to_s, label: label(locale), current:, href: (destination(locale, record, by_locale) unless current) } end end |
.nav(record, records, by_locale) ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/howdoc/navigation.rb', line 57 def nav(record, records, by_locale) Templates.render( 'shared/html/nav.haml', locale: record.locale, records:, current: record, config: Howdoc.config, languages: languages(current_locale: record.locale, record:, by_locale:) ) end |
.ordered(locales) ⇒ Object
111 112 113 114 115 116 |
# File 'lib/howdoc/navigation.rb', line 111 def ordered(locales) configured = Howdoc.config.locales&.map(&:to_s) return locales.map(&:to_s).sort if configured.nil? (configured & locales.map(&:to_s)) | locales.map(&:to_s).sort end |
.pager(record, records, position) ⇒ Object
65 66 67 68 69 70 71 72 |
# File 'lib/howdoc/navigation.rb', line 65 def pager(record, records, position) Templates.render( 'shared/html/pager.haml', locale: record.locale, config: Howdoc.config, previous: (records[position - 1] if position.positive?), next: records[position + 1] ) end |
.placeholder(name) ⇒ Object
53 54 55 |
# File 'lib/howdoc/navigation.rb', line 53 def placeholder(name) %r{<nav[^>]*data-howdoc-#{name}[^>]*>.*?</nav>}m end |
.write(record, records:, position:, by_locale:, root:) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/howdoc/navigation.rb', line 32 def write(record, records:, position:, by_locale:, root:) path = File.join(root, record.locale.to_s, record.filename) return nil unless File.file?(path) markup = File.read(path) filled = fill(markup, :nav) { nav(record, records, by_locale) } filled = fill(filled, :pager) { pager(record, records, position) } return nil if filled == markup File.write(path, filled) path end |