From ae07fc2b38ffe8dc3e5796e1f3e6e57041b5eb36 Mon Sep 17 00:00:00 2001 From: "edd.grant" Date: Thu, 2 Dec 2021 13:30:59 +0000 Subject: [PATCH 01/14] TRG-128 - Generate Table of Content links as relative links. This aims to address https://github.com/alphagov/tech-docs-gem/issues/271 by ensuring that all TOC links are generated as relative links, rather than absolute. The desired outcome being that the site no longer makes assumptions about being deployed at "/" which in turn makes it "portable" (i.e. possible to deploy it at an arbitrary path). --- .../table_of_contents/helpers.rb | 28 +++- spec/table_of_contents/helpers_spec.rb | 129 ++++++++++++++++-- 2 files changed, 145 insertions(+), 12 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index d2cb3730..aa577a5b 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -36,6 +36,29 @@ def list_items_from_headings(html, url: "", max_level: nil) HeadingTreeRenderer.new(tree, max_level: max_level).html end + def get_resource_link_value(config, resource, current_page) + if config[:relative_links] + current_page_segments = current_page.path.split("/").reject(&:empty?)[0..-2] + resource_path_segments = resource.path.split("/").reject(&:empty?)[0..-2] + resource_file_name = resource.path.split("/")[-1] + number_of_ascents_to_site_root = current_page_segments.length + + if number_of_ascents_to_site_root == 0 + ascents = ["."] + else + ascents = number_of_ascents_to_site_root.times.collect { ".." } + end + + link_value = ascents.concat(resource_path_segments) + .push(resource_file_name) + .join("/") + + else + link_value = resource.url + end + link_value + end + def render_page_tree(resources, current_page, config, current_page_html) # Sort by weight frontmatter resources = resources @@ -71,15 +94,16 @@ def render_page_tree(resources, current_page, config, current_page_html) config[:http_prefix] + "/" end + link_value = get_resource_link_value(config, resource, current_page) if resource.children.any? && resource.url != home_url - output += %{
  • #{resource.data.title}\n} + output += %{
  • #{resource.data.title}\n} output += render_page_tree(resource.children, current_page, config, current_page_html) output += "
  • \n" else output += list_items_from_headings( content, - url: resource.url, + url: link_value, max_level: config[:tech_docs][:max_toc_heading_level], ) end diff --git a/spec/table_of_contents/helpers_spec.rb b/spec/table_of_contents/helpers_spec.rb index dd2a63bc..346375cd 100644 --- a/spec/table_of_contents/helpers_spec.rb +++ b/spec/table_of_contents/helpers_spec.rb @@ -126,16 +126,20 @@ def add_children(children) subject { Subject.new } - it "builds a table of contents from several page resources" do + it "builds a table of contents using absolute links from several page resources" do resources = [] resources[0] = FakeResource.new("/index.html", '

    Heading one

    Heading two

    ', 10, "Index"); - resources[1] = FakeResource.new("/a.html", '

    Heading one

    Heading two

    ', 10, "Sub page A", resources[0]); - resources[2] = FakeResource.new("/b.html", '

    Heading one

    Heading two

    ', 20, "Sub page B", resources[0]); - resources[0].add_children [resources[1], resources[2]] + resources[1] = FakeResource.new("/1/2/a.html", '

    Heading one

    Heading two

    ', 20, "Sub page A", resources[0]); + resources[2] = FakeResource.new("/1/2/3/b.html", '

    Heading one

    Heading two

    ', 30, "Sub page A", resources[0]); + resources[3] = FakeResource.new("/1/2/3/4/c.html", '

    Heading one

    Heading two

    ', 40, "Sub page B", resources[0]); + resources[4] = FakeResource.new("/1/5/d.html", '

    Heading one

    Heading two

    ', 50, "Sub page A", resources[0]); + resources[5] = FakeResource.new("/1/5/6/e.html", '

    Heading one

    Heading two

    ', 60, "Sub page A", resources[0]); + resources[0].add_children [resources[1], resources[2], resources[3], resources[4], resources[5]] current_page = double("current_page", data: double("page_frontmatter", description: "The description.", title: "The Title"), - url: "/index.html", + url: "/1/2/3/index.html", + path: "/1/2/3/index.html", metadata: { locals: {} }) current_page_html = '

    Heading one

    Heading two

    '; @@ -152,18 +156,120 @@ def add_children(children)
  • Index +
  • + + } + + expect(subject.multi_page_table_of_contents(resources, current_page, config, current_page_html).strip).to eq(expected_multi_page_table_of_contents.strip) + end + + it "builds a table of contents using relative links from several page resources" do + resources = [] + resources[0] = FakeResource.new("/index.html", '

    Heading one

    Heading two

    ', 10, "Index"); + resources[1] = FakeResource.new("/1/2/a.html", '

    Heading one

    Heading two

    ', 20, "Sub page A", resources[0]); + resources[2] = FakeResource.new("/1/2/3/b.html", '

    Heading one

    Heading two

    ', 30, "Sub page A", resources[0]); + resources[3] = FakeResource.new("/1/2/3/4/c.html", '

    Heading one

    Heading two

    ', 40, "Sub page B", resources[0]); + resources[4] = FakeResource.new("/1/5/d.html", '

    Heading one

    Heading two

    ', 50, "Sub page A", resources[0]); + resources[5] = FakeResource.new("/1/5/6/e.html", '

    Heading one

    Heading two

    ', 60, "Sub page A", resources[0]); + resources[0].add_children [resources[1], resources[2], resources[3], resources[4], resources[5]] + + current_page = double("current_page", + data: double("page_frontmatter", description: "The description.", title: "The Title"), + url: "/1/2/3/index.html", + path: "/1/2/3/index.html", + metadata: { locals: {} }) + + current_page_html = '

    Heading one

    Heading two

    '; + + config = { + http_prefix: "/", + relative_links: true, + tech_docs: { + max_toc_heading_level: 3, + }, + } + + expected_multi_page_table_of_contents = %{ +