govuk_tech_docs 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of govuk_tech_docs might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b05aaaeb08b75633793f5ede8102ef35d54cedbe6bc419b9fe262a3596d6cfef
4
- data.tar.gz: 30ab85794e056634591d692999364da7644908653e06d2707aa15eeff9b5bfea
3
+ metadata.gz: 06ad063ddc3de387b2bae379df43d4ecd6996a42bdc1f0472e2eb46b404b5701
4
+ data.tar.gz: 23b17f1d49d77303d7acb06be0ee2f30cd8ec9b40407b18689696008bf594b89
5
5
  SHA512:
6
- metadata.gz: 406187054e9b14fd631fb56a2602f8c607ab2abfe8be466673ffee99fba6451ebe684dca40e53270b66b5b1a6b12142336ad26124335b33b02205e13005290e8
7
- data.tar.gz: fc0afcd3567241e487bb75fbfebb26561ee8b6c9dd0a50d5f2d8252ea2d8a95c71976ae2540ff1f58e2d89886234c25b6d6b726fb74e618a1fba05ae97b0303d
6
+ metadata.gz: dfff9af883e1eb613f704789bd55f65947309e5df3a7a1d1280f4a28483a55d38200108d9808279d3985e2fd75bdc86adccea94520bb7469a78cdfa654def53c
7
+ data.tar.gz: '09ae4a42091646b3850af6e4db030a0912e48a10df7b0db296621cdaa58c5df236c17399374201fe2f4af4bd38ce9525837a0811145cfea5fa380b70c5836541'
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 3.2.0
6
+
7
+ ### New features
8
+
9
+ You can now [configure your Tech Docs Template (TDT) to build your documentation site to use relative links to pages and assets](https://tdt-documentation.london.cloudapps.digital/configure_project/global_configuration/#build-your-site-using-relative-links).
10
+
11
+ Thanks [@eddgrant](https://github.com/eddgrant) for contributing this feature and the associated fixes.
12
+
13
+ This change was introduced in [pull request #291: Support sites deployed on paths other than "/" (by generating relative links)](https://github.com/alphagov/tech-docs-gem/pull/291).
14
+
5
15
  ## 3.1.0
6
16
 
7
17
  ### New features
@@ -57,25 +57,31 @@
57
57
  $toggleLabel.text(setOpen ? 'Collapse ' + $heading.text() : 'Expand ' + $heading.text())
58
58
  }
59
59
 
60
+ /**
61
+ * Returns an absolute pathname to $target by combining it with window.location.href
62
+ * @param $target The target whose pathname to return. This may be an anchor with an absolute or relative href.
63
+ * @returns {string} The absolute pathname of $target
64
+ */
65
+ function getAbsolutePath ($target) {
66
+ return new URL($target.attr('href'), window.location.href).pathname
67
+ }
68
+
60
69
  function openActiveHeading () {
61
70
  var $activeElement
62
71
  var currentPath = window.location.pathname
63
- var isActiveTrail = '[href*="' + currentPath + '"]'
64
- // Add an exception for the root page, as every href includes /
65
- if (currentPath === '/') {
66
- isActiveTrail = '[href="' + currentPath + window.location.hash + '"]'
67
- }
68
72
  for (var i = $topLevelItems.length - 1; i >= 0; i--) {
69
73
  var $element = $($topLevelItems[i])
70
74
  var $heading = $element.find('> a')
71
75
  // Check if this item href matches
72
- if ($heading.is(isActiveTrail)) {
76
+ if (getAbsolutePath($heading) === currentPath) {
73
77
  $activeElement = $element
74
78
  break
75
79
  }
76
80
  // Otherwise check the children
77
81
  var $children = $element.find('li > a')
78
- var $matchingChildren = $children.filter(isActiveTrail)
82
+ var $matchingChildren = $children.filter(function (_) {
83
+ return getAbsolutePath($(this)) === currentPath
84
+ })
79
85
  if ($matchingChildren.length) {
80
86
  $activeElement = $element
81
87
  break
@@ -70,13 +70,18 @@
70
70
  function highlightActiveItemInToc (fragment) {
71
71
  // Navigation items for single page navigation don't necessarily include the path name, but
72
72
  // navigation items for multipage navigation items do include it. This checks for either case.
73
- var $activeTocItem = $tocItems.filter(
74
- '[href="' + window.location.pathname + fragment + '"],[href="' + fragment + '"]'
75
- )
73
+ var $activeTocItem = $tocItems.filter(function (_) {
74
+ var url = new URL($(this).attr('href'), window.location.href)
75
+ return url.href === window.location.href
76
+ })
77
+
76
78
  // Navigation items with children don't contain fragments in their url
77
79
  // Check to see if any nav items contain just the path name.
78
80
  if (!$activeTocItem.get(0)) {
79
- $activeTocItem = $tocItems.filter('[href="' + window.location.pathname + '"]')
81
+ $activeTocItem = $tocItems.filter(function (_) {
82
+ var url = new URL($(this).attr('href'), window.location.href)
83
+ return url.hash === '' && url.pathname === window.location.pathname
84
+ })
80
85
  }
81
86
  if ($activeTocItem.get(0)) {
82
87
  $tocItems.removeClass('toc-link--in-view')
@@ -16,6 +16,7 @@
16
16
  var results
17
17
  var query
18
18
  var maxSearchEntries = 20
19
+ var pathToSiteRoot
19
20
 
20
21
  this.start = function start ($element) {
21
22
  $searchForm = $element.find('form')
@@ -25,6 +26,7 @@
25
26
  $searchResults = $searchResultsWrapper.find('.search-results__content')
26
27
  $searchResultsTitle = $searchResultsWrapper.find('.search-results__title')
27
28
  $searchHelp = $('#search-help')
29
+ pathToSiteRoot = $element.data('pathToSiteRoot')
28
30
 
29
31
  changeSearchAction()
30
32
  changeSearchLabel()
@@ -38,7 +40,7 @@
38
40
  query = s.getQuery()
39
41
  if (query) {
40
42
  $searchInput.val(query)
41
- doSearch(query)
43
+ doSearch(query, pathToSiteRoot)
42
44
  doAnalytics()
43
45
  document.title = query + ' - ' + document.title
44
46
  }
@@ -49,7 +51,7 @@
49
51
  this.downloadSearchIndex = function downloadSearchIndex () {
50
52
  updateTitle('Loading search results')
51
53
  $.ajax({
52
- url: '/search.json',
54
+ url: pathToSiteRoot + 'search.json',
53
55
  cache: true,
54
56
  method: 'GET',
55
57
  success: function (data) {
@@ -65,7 +67,7 @@
65
67
  // We need JavaScript to do search, so if JS is not available the search
66
68
  // input sends the query string to Google. This JS function changes the
67
69
  // input to instead send it to the search page.
68
- $searchForm.prop('action', '/search')
70
+ $searchForm.prop('action', pathToSiteRoot + 'search/index.html')
69
71
  $searchForm.find('input[name="as_sitesearch"]').remove()
70
72
  }
71
73
 
@@ -86,10 +88,10 @@
86
88
  return query
87
89
  }
88
90
 
89
- function doSearch (query) {
91
+ function doSearch (query, pathToSiteRoot) {
90
92
  s.search(query, function (r) {
91
93
  results = r
92
- renderResults(query)
94
+ renderResults(query, pathToSiteRoot)
93
95
  updateTitle()
94
96
  })
95
97
  }
@@ -138,7 +140,7 @@
138
140
  callback(getResults(query))
139
141
  }
140
142
 
141
- function renderResults (query) {
143
+ function renderResults (query, pathToSiteRoot) {
142
144
  var output = ''
143
145
  if (results.length === 0) {
144
146
  output += '<p>Nothing found</p>'
@@ -149,7 +151,9 @@
149
151
  var content = s.processContent(result.content, query)
150
152
  output += '<li class="search-result">'
151
153
  output += '<h3 class="search-result__title">'
152
- output += '<a href="' + result.url + '">'
154
+ var pagePathWithoutLeadingSlash = result.url.startsWith('/') ? result.url.slice(1) : result.url
155
+ var url = pathToSiteRoot.startsWith('.') ? pathToSiteRoot + pagePathWithoutLeadingSlash : '/' + pagePathWithoutLeadingSlash
156
+ output += '<a href="' + url + '">'
153
157
  output += result.title
154
158
  output += '</a>'
155
159
  output += '</h3>'
@@ -1,4 +1,4 @@
1
- $govuk-assets-path: "/assets/govuk/assets/";
1
+ $govuk-assets-path: "/assets/govuk/assets/" !default;
2
2
 
3
3
  // Include only the bits of GOV.UK Frontend we need
4
4
  $govuk-new-link-styles: true;
@@ -18,12 +18,12 @@
18
18
  text-decoration: none;
19
19
  text-indent: -9999em;
20
20
 
21
- background-image: url('/images/anchored-heading-icon.png');
21
+ background-image: image-url('/images/anchored-heading-icon.png');
22
22
  background-repeat: no-repeat;
23
23
  background-position: center center;
24
24
 
25
25
  @include govuk-device-pixel-ratio {
26
- background-image: url('/images/anchored-heading-icon-2x.png');
26
+ background-image: image-url('/images/anchored-heading-icon-2x.png');
27
27
  background-size: $icon-width $icon-height;
28
28
  }
29
29
 
@@ -36,7 +36,7 @@ $input-size: 40px;
36
36
  padding: 0;
37
37
  width: $input-size;
38
38
  height: 100%;
39
- background-image: url('/images/search-button.png');
39
+ background-image: image-url('/images/search-button.png');
40
40
  background-repeat: no-repeat;
41
41
  background-position: 2px 50%;
42
42
  text-indent: -5000px;
@@ -104,7 +104,7 @@ $input-size: 40px;
104
104
  left: -9px;
105
105
  width: 10px;
106
106
  height: 20px;
107
- background: no-repeat url('/images/search-result-caret.svg') center right;
107
+ background: no-repeat image-url('/images/search-result-caret.svg') center right;
108
108
  background-size: contain;
109
109
  }
110
110
  }
@@ -152,12 +152,12 @@
152
152
  height: 20px;
153
153
  float: right;
154
154
 
155
- background-image: url('/images/govuk-icn-numbered-list.png');
155
+ background-image: image-url('/images/govuk-icn-numbered-list.png');
156
156
  background-repeat: no-repeat;
157
157
  background-position: left center;
158
158
 
159
159
  @include govuk-device-pixel-ratio {
160
- background-image: url('/images/govuk-icn-numbered-list@2x.png');
160
+ background-image: image-url('/images/govuk-icn-numbered-list@2x.png');
161
161
  background-size: 20px 20px;
162
162
  }
163
163
  }
@@ -178,12 +178,12 @@
178
178
  height: 20px;
179
179
  cursor: pointer;
180
180
 
181
- background-image: url('/images/govuk-icn-close.png');
181
+ background-image: image-url('/images/govuk-icn-close.png');
182
182
  background-repeat: no-repeat;
183
183
  background-position: left center;
184
184
 
185
185
  @include govuk-device-pixel-ratio {
186
- background-image: url('/images/govuk-icn-close@2x.png');
186
+ background-image: image-url('/images/govuk-icn-close@2x.png');
187
187
  background-size: 20px 20px;
188
188
  }
189
189
 
@@ -1,10 +1,12 @@
1
1
  module GovukTechDocs
2
2
  class Pages
3
+ include GovukTechDocs::PathHelpers
3
4
  attr_reader :sitemap
4
5
 
5
- def initialize(sitemap, config)
6
+ def initialize(sitemap, config, current_page)
6
7
  @sitemap = sitemap
7
8
  @config = config
9
+ @current_page = current_page
8
10
  end
9
11
 
10
12
  def to_json(*_args)
@@ -18,7 +20,7 @@ module GovukTechDocs
18
20
  review = PageReview.new(page, @config)
19
21
  {
20
22
  title: page.data.title,
21
- url: "#{@config[:tech_docs][:host]}#{page.url}",
23
+ url: get_path_to_resource(@config, page, @current_page).to_s,
22
24
  review_by: review.review_by,
23
25
  owner_slack: review.owner_slack,
24
26
  }
@@ -0,0 +1,30 @@
1
+ module GovukTechDocs
2
+ module PathHelpers
3
+ def get_path_to_resource(config, resource, current_page)
4
+ if config[:relative_links]
5
+ resource_path_segments = resource.path.split("/").reject(&:empty?)[0..-2]
6
+ resource_file_name = resource.path.split("/")[-1]
7
+
8
+ path_to_site_root = path_to_site_root config, current_page.path
9
+ resource_path = path_to_site_root + resource_path_segments
10
+ .push(resource_file_name)
11
+ .join("/")
12
+ else
13
+ resource_path = resource.url
14
+ end
15
+ resource_path
16
+ end
17
+
18
+ def path_to_site_root(config, page_path)
19
+ if config[:relative_links]
20
+ number_of_ascents_to_site_root = page_path.to_s.split("/").reject(&:empty?)[0..-2].length
21
+ ascents = number_of_ascents_to_site_root.zero? ? ["."] : number_of_ascents_to_site_root.times.collect { ".." }
22
+ path_to_site_root = ascents.join("/").concat("/")
23
+ else
24
+ middleman_http_prefix = config[:http_prefix]
25
+ path_to_site_root = middleman_http_prefix.end_with?("/") ? middleman_http_prefix : "#{middleman_http_prefix}/"
26
+ end
27
+ path_to_site_root
28
+ end
29
+ end
30
+ end
@@ -1,3 +1,4 @@
1
+ require "govuk_tech_docs/path_helpers"
1
2
  require "govuk_tech_docs/table_of_contents/heading_tree_builder"
2
3
  require "govuk_tech_docs/table_of_contents/heading_tree_renderer"
3
4
  require "govuk_tech_docs/table_of_contents/heading_tree"
@@ -7,6 +8,8 @@ require "govuk_tech_docs/table_of_contents/headings_builder"
7
8
  module GovukTechDocs
8
9
  module TableOfContents
9
10
  module Helpers
11
+ include GovukTechDocs::PathHelpers
12
+
10
13
  def single_page_table_of_contents(html, url: "", max_level: nil)
11
14
  output = "<ul>\n"
12
15
  output += list_items_from_headings(html, url: url, max_level: max_level)
@@ -48,11 +51,7 @@ module GovukTechDocs
48
51
 
49
52
  # Reuse the generated content for the active page
50
53
  # If we generate it twice it increments the heading ids
51
- content = if current_page.url == resource.url && current_page_html
52
- current_page_html
53
- else
54
- resource.render(layout: false)
55
- end
54
+ content = current_page.url == resource.url && current_page_html ? current_page_html : resource.render(layout: false)
56
55
  # Avoid redirect pages
57
56
  next if content.include? "http-equiv=refresh"
58
57
 
@@ -71,15 +70,16 @@ module GovukTechDocs
71
70
  config[:http_prefix] + "/"
72
71
  end
73
72
 
73
+ link_value = get_path_to_resource(config, resource, current_page)
74
74
  if resource.children.any? && resource.url != home_url
75
- output += %{<li><a href="#{resource.url}"><span>#{resource.data.title}</span></a>\n}
75
+ output += %{<li><a href="#{link_value}"><span>#{resource.data.title}</span></a>\n}
76
76
  output += render_page_tree(resource.children, current_page, config, current_page_html)
77
77
  output += "</li>\n"
78
78
  else
79
79
  output +=
80
80
  list_items_from_headings(
81
81
  content,
82
- url: resource.url,
82
+ url: link_value,
83
83
  max_level: config[:tech_docs][:max_toc_heading_level],
84
84
  )
85
85
  end
@@ -1,3 +1,3 @@
1
1
  module GovukTechDocs
2
- VERSION = "3.1.0".freeze
2
+ VERSION = "3.2.0".freeze
3
3
  end
@@ -67,6 +67,7 @@ module GovukTechDocs
67
67
  context.activate :api_reference
68
68
 
69
69
  context.helpers do
70
+ include GovukTechDocs::PathHelpers
70
71
  include GovukTechDocs::TableOfContents::Helpers
71
72
  include GovukTechDocs::ContributionBanner
72
73
 
@@ -1 +1 @@
1
- <%= GovukTechDocs::Pages.new(sitemap, config).to_json %>
1
+ <%= GovukTechDocs::Pages.new(sitemap, config, current_page).to_json %>
@@ -1,5 +1,5 @@
1
1
  <% if config[:tech_docs][:enable_search] %>
2
- <div class="search" data-module="search">
2
+ <div class="search" data-module="search" data-path-to-site-root="<%= path_to_site_root config, current_page.path %>">
3
3
  <form action="https://www.google.co.uk/search" method="get" role="search" class="search__form govuk-!-margin-bottom-4">
4
4
  <input type="hidden" name="as_sitesearch" value="<%= config[:tech_docs][:host] %>"/>
5
5
  <label class="govuk-label search__label" for="search" aria-hidden="true">
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_tech_docs
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Government Digital Service
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: autoprefixer-rails
@@ -360,6 +360,7 @@ files:
360
360
  - lib/govuk_tech_docs/meta_tags.rb
361
361
  - lib/govuk_tech_docs/page_review.rb
362
362
  - lib/govuk_tech_docs/pages.rb
363
+ - lib/govuk_tech_docs/path_helpers.rb
363
364
  - lib/govuk_tech_docs/redirects.rb
364
365
  - lib/govuk_tech_docs/table_of_contents/heading.rb
365
366
  - lib/govuk_tech_docs/table_of_contents/heading_tree.rb