From 7e1682872a0a20fbaa4e7b7f5cb53d8d4cfbff71 Mon Sep 17 00:00:00 2001 From: eddgrant Date: Wed, 8 Feb 2023 09:39:30 +0000 Subject: [PATCH] TRG-668: Support sites deployed on a path other than "/" when generating header and footer links. --- govuk_tech_docs.gemspec | 2 +- lib/govuk_tech_docs/path_helpers.rb | 50 ++++++++--- lib/source/layouts/_footer.erb | 2 +- lib/source/layouts/_header.erb | 4 +- spec/govuk_tech_docs/doubles.rb | 5 ++ spec/govuk_tech_docs/pages_spec.rb | 10 ++- spec/govuk_tech_docs/path_helpers_spec.rb | 104 +++++++++++++++++----- spec/table_of_contents/helpers_spec.rb | 4 + 8 files changed, 141 insertions(+), 40 deletions(-) create mode 100644 spec/govuk_tech_docs/doubles.rb diff --git a/govuk_tech_docs.gemspec b/govuk_tech_docs.gemspec index a2ff7f27..7b0035a6 100644 --- a/govuk_tech_docs.gemspec +++ b/govuk_tech_docs.gemspec @@ -37,6 +37,7 @@ Gem::Specification.new do |spec| spec.add_dependency "autoprefixer-rails", "~> 10.2" spec.add_dependency "chronic", "~> 0.10.2" + spec.add_dependency "haml", "< 6.0.0" spec.add_dependency "middleman", "~> 4.0" spec.add_dependency "middleman-autoprefixer", "~> 2.10.0" spec.add_dependency "middleman-compass", ">= 4.0.0" @@ -47,7 +48,6 @@ Gem::Specification.new do |spec| spec.add_dependency "nokogiri" spec.add_dependency "openapi3_parser", "~> 0.9.0" spec.add_dependency "redcarpet", "~> 3.5.1" - spec.add_dependency "haml", "< 6.0.0" spec.add_development_dependency "byebug" spec.add_development_dependency "capybara", "~> 3.32" diff --git a/lib/govuk_tech_docs/path_helpers.rb b/lib/govuk_tech_docs/path_helpers.rb index 8fdad288..3619f298 100644 --- a/lib/govuk_tech_docs/path_helpers.rb +++ b/lib/govuk_tech_docs/path_helpers.rb @@ -1,18 +1,29 @@ +require "uri" module GovukTechDocs module PathHelpers - def get_path_to_resource(config, resource, current_page) - if config[:relative_links] - resource_path_segments = resource.path.split("/").reject(&:empty?)[0..-2] - resource_file_name = resource.path.split("/")[-1] + # Some useful notes from https://www.rubydoc.info/github/middleman/middleman/Middleman/Sitemap/Resource#url-instance_method : + # 'resource.path' is "The source path of this resource (relative to the source directory, without template extensions)." + # 'resource.destination_path', which is: "The output path in the build directory for this resource." + # 'resource.url' is based on 'resource.destination_path', but is further tweaked to optionally strip the index file and prefixed with any :http_prefix. - path_to_site_root = path_to_site_root config, current_page.path - resource_path = path_to_site_root + resource_path_segments - .push(resource_file_name) - .join("/") + # Calculates the path to the sought resource, taking in to account whether the site has been configured + # to generate relative or absolute links. + # Identifies whether the sought resource is an internal or external target: External targets are returned untouched. Path calculation is performed for internal targets. + # Works for both "Middleman::Sitemap::Resource" resources and plain strings (which may be passed from the site configuration when generating header links). + # + # @param [Object] config + # @param [Object] resource + # @param [Object] current_page + def get_path_to_resource(config, resource, current_page) + if resource.is_a?(Middleman::Sitemap::Resource) + config[:relative_links] ? get_resource_path_relative_to_current_page(config, current_page.path, resource.path) : resource.url + elsif external_url?(resource) + resource + elsif config[:relative_links] + get_resource_path_relative_to_current_page(config, current_page.path, resource) else - resource_path = resource.url + resource end - resource_path end def path_to_site_root(config, page_path) @@ -26,5 +37,24 @@ def path_to_site_root(config, page_path) end path_to_site_root end + + private + + # Calculates the path to the sought resource, relative to the current page. + # @param [Object] config Middleman config. + # @param [String] current_page path of the current page, from the site root. + # @param [String] resource_path_from_site_root path of the sought resource, from the site root. + def get_resource_path_relative_to_current_page(config, current_page, resource_path_from_site_root) + path_segments = resource_path_from_site_root.split("/").reject(&:empty?)[0..-2] + path_file_name = resource_path_from_site_root.split("/")[-1] + + path_to_site_root = path_to_site_root config, current_page + path_to_site_root + path_segments.push(path_file_name).join("/") + end + + def external_url?(url) + uri = URI.parse(url) + uri.scheme || uri.to_s.split("/")[0]&.include?(".") + end end end diff --git a/lib/source/layouts/_footer.erb b/lib/source/layouts/_footer.erb index 049eb3f2..1c75bc80 100644 --- a/lib/source/layouts/_footer.erb +++ b/lib/source/layouts/_footer.erb @@ -6,7 +6,7 @@ diff --git a/lib/source/layouts/_header.erb b/lib/source/layouts/_header.erb index 2c442992..0493287f 100644 --- a/lib/source/layouts/_header.erb +++ b/lib/source/layouts/_header.erb @@ -2,7 +2,7 @@