Skip to content

Commit

Permalink
Rewrite documentation URL mapping to use the TOC
Browse files Browse the repository at this point in the history
Upstream builds various guides and each guide is built as a single large
page. That page has many chapters. Technically every guide is also built
into 3 flavors (foreman-deb, foreman-el, katello).

Downstream builds various guides, which mostly come from upstream. Most
guides are a simple translation where they're downcased, but some are
rewritten to something else.

A bigger difference is that each guide is built into multiple pages.
This means we need to find the right page containing the chapter. The
Table of Content contains a complete mapping with this information, so
it can be looked up dynamically.

If this still can't be found, we use the html-single where everything is
built into a single page. We then just hope it exists. Otherwise the
browser will just show the whole page. This is an unexpected case, so a
warning is logged.

The result is that a lot less maintenance is needed, because in most
cases it will "just work". A downside is that it becomes hard to verify
links are correct. It becomes needed to crawl through all of the source
code for any documentation links, similar to how we crawl through it for
translations.
  • Loading branch information
ekohl committed Jul 26, 2024
1 parent 597db36 commit d64fff5
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ def wiki_url(section: '')
# We do not use flavor downstream, but keeping it here for the same method signature
# rubocop:disable Lint/UnusedMethodArgument
def docs_url(guide:, flavor:, chapter: nil)
url = ForemanThemeSatellite::Documentation::DOCS_GUIDES_LINKS.dig(guide, chapter)
url || "#{ForemanThemeSatellite.documentation_root}/#{guide.downcase}/#{chapter}"
ForemanThemeSatellite::Documentation.docs_url(guide, chapter)
end
# rubocop:enable Lint/UnusedMethodArgument
end
File renamed without changes.
59 changes: 44 additions & 15 deletions lib/foreman_theme_satellite/documentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,28 +77,57 @@ module Documentation
'foreman_discovery' => "#{ForemanThemeSatellite.documentation_root}/provisioning_hosts/discovering-hosts-on-a-network_provisioning",
}.freeze

DOCS_GUIDES_LINKS = {
'Managing_Content' => {
'Products_and_Repositories_content-management' => "#{ForemanThemeSatellite.documentation_root}/managing_content/importing_content_content-management#Products_and_Repositories_content-management",
},
# Guide mapping. If no entry is present, it should be assumed that it can
# be downcased
DOCS_GUIDE_MAPPING = {
'Managing_Configurations_Ansible' => 'managing_configurations_using_ansible_integration',
}.freeze

# An upstream chapter mapping, in case downstream another chapter should be
# used. The top level key is the upstream guide name where the value is a
# mapping of upstream chapter to downstream mapping
DOCS_GUIDE_CHAPTER_MAPPING = {
'Managing_Hosts' => {
'registering-a-host_managing-hosts' => "#{ForemanThemeSatellite.documentation_root}/managing_hosts/registering_hosts_to_server_managing-hosts#Registering_Hosts_by_Using_Global_Registration_managing-hosts",
}
'registering-a-host_managing-hosts' => 'Registering_Hosts_by_Using_Global_Registration_managing-hosts',
},
}.freeze

def self.flat_docs_guides_links
nested_to_flat_k_v(nil, DOCS_GUIDES_LINKS).to_h
DOCS_GUIDE_PAGES = JSON.load_file(File.join(__dir__, 'documentation-toc.json'))

# @param guide [String]
# The downstream guide name
# @param chapter [String]
# The downstream chapter name
# @return [String]
# The page where the chapter is located
# @return nil
# If no chapter was found
def self.find_page_for_guide_chapter(guide, chapter)
DOCS_GUIDE_PAGES[guide]&.find { |_page, chapters| chapters.include?(chapter) }&.first
end

private_class_method def self.nested_to_flat_k_v(prefix, source)
key_values = []
source.map do |k, v|
key = "#{prefix}/#{k}"
if v.is_a?(Hash)
key_values.append(*nested_to_flat_k_v(key, v))
def self.docs_url(guide, chapter)
root = ForemanThemeSatellite.documentation_root
downstream_guide = DOCS_GUIDE_MAPPING.fetch(guide) { guide.downstream }

if chapter
downstream_chapter = DOCS_GUIDE_CHAPTER_MAPPING.fetch(guide, chapter) || chapter
page = find_page_for_guide_chapter(downstream_guide, downstream_chapter)

if page
"#{root}/#{downstream_guide}/#{page}##{downstream_chapter}"
else
key_values.append([key, v])
logger.warning("Could not find page for chapter '#{downstream_chapter}' in guide '#{downstream_guide}'")
"#{root}-single/#{downstream_guide}/index##{downstream_chapter}"
end
else
"#{root}/#{downstream_guide}"
end
end

def self.flat_docs_guides_links
DOCS_GUIDE_CHAPTER_MAPPING.inject({}) do |hash, guide, chapters|
hash.update(chapters.keys.to_h { |chapter| ["/#{guide}/#{chapter}", docs_url(guide, chapter)] })
end
end
end
Expand Down
18 changes: 18 additions & 0 deletions test/integration/documentation_controller_branding_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ def test_docs_redirect_branded
assert_redirected_to "https://docs.redhat.com/documentation/en-us/red_hat_satellite/#{ForemanThemeSatellite.documentation_version}/html/managing_hosts/registering_hosts_to_server_managing-hosts#Registering_Hosts_by_Using_Global_Registration_managing-hosts"
end

def test_docs_dynamically_generated
get "/links/docs/Managing_Content?chapter=Products_and_Repositories_content-management"

assert_redirected_to "https://docs.redhat.com/documentation/en-us/red_hat_satellite/#{ForemanThemeSatellite.documentation_version}/html/managing_content/importing_content_content-management#Products_and_Repositories_content-management"
end

def test_docs_with_mapped_guide
get "/links/docs/Managing_Configurations_Ansible?chapter=Importing_Ansible_Roles_and_Variables_ansible"

assert_redirected_to "https://docs.redhat.com/documentation/en-us/red_hat_satellite/#{ForemanThemeSatellite.documentation_version}/html/managing_configurations_using_ansible/getting_started_with_ansible_in_satellite_ansible_integration#Importing_Ansible_Roles_and_Variables_ansible"
end

def test_docs_chapter_does_not_exist
get "/links/docs/Managing_Content?chapter=does-not-exist"

assert_redirected_to "https://docs.redhat.com/documentation/en-us/red_hat_satellite/#{ForemanThemeSatellite.documentation_version}/html-single/managing_content/index#does-not-exist"
end

def test_docs_redirect_unknown_chapter
get "/links/docs/Managing_Hosts"

Expand Down

0 comments on commit d64fff5

Please sign in to comment.