govuk_tech_docs 3.3.1 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/publish.yaml +10 -7
- data/.github/workflows/test.yaml +8 -3
- data/.nvmrc +1 -1
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +1 -1
- data/govuk_tech_docs.gemspec +13 -9
- data/lib/govuk_tech_docs/api_reference/api_reference_extension.rb +1 -1
- data/lib/govuk_tech_docs/api_reference/api_reference_renderer.rb +10 -10
- data/lib/govuk_tech_docs/path_helpers.rb +40 -10
- data/lib/govuk_tech_docs/redirects.rb +2 -2
- data/lib/govuk_tech_docs/table_of_contents/heading.rb +2 -2
- data/lib/govuk_tech_docs/table_of_contents/heading_tree_renderer.rb +5 -5
- data/lib/govuk_tech_docs/table_of_contents/helpers.rb +3 -3
- data/lib/govuk_tech_docs/version.rb +1 -1
- data/lib/govuk_tech_docs.rb +4 -4
- data/lib/source/layouts/_footer.erb +1 -1
- data/lib/source/layouts/_header.erb +2 -2
- data/package-lock.json +2705 -5
- metadata +20 -7
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac3b9630e3b7c40e2029a0e115dc1054e025f14d35fc07b81b4ab531cee7bea2
|
4
|
+
data.tar.gz: e414f5b7ab807ef05e95ec5f3281d68abd444e712f8355ed4bbac2dcd7c17dfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3b71ef93eac71413d405bb1a504b15a2692a498ba397c93f0d4aabb8f231650176e9b6b55edc620128fdec5fc0fa8a60f02d70eacd1092b1c52611966f84685
|
7
|
+
data.tar.gz: 1a6f93c4c7f2079adb79e02e734e7fe7f375d503ad0d20c3be59df2696d0efacbbbd189f6822e2263e9245925407d88fe96f02dbcd5aa6e099d636954c3440e1
|
@@ -16,22 +16,24 @@ jobs:
|
|
16
16
|
go: ${{ steps.gem_version.outputs.new_version }}
|
17
17
|
|
18
18
|
steps:
|
19
|
-
- uses: actions/checkout@
|
19
|
+
- uses: actions/checkout@v3
|
20
20
|
|
21
21
|
- uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: '3'
|
22
24
|
|
23
25
|
- name: Check if new version to release
|
24
26
|
id: gem_version
|
25
27
|
run: |
|
26
28
|
gem_version=$(ruby -r rubygems -e "puts Gem::Specification::load('govuk_tech_docs.gemspec').version")
|
27
|
-
echo "
|
29
|
+
echo "gem_version=$gem_version" >> "$GITHUB_OUTPUT"
|
28
30
|
|
29
31
|
if git fetch origin "refs/tags/v$gem_version" >/dev/null 2>&1
|
30
32
|
then
|
31
33
|
echo "Tag 'v$gem_version' already exists"
|
32
|
-
echo "
|
34
|
+
echo "new_version=false" >> "$GITHUB_OUTPUT"
|
33
35
|
else
|
34
|
-
echo "
|
36
|
+
echo "new_version=true" >> "$GITHUB_OUTPUT"
|
35
37
|
fi
|
36
38
|
|
37
39
|
deploy:
|
@@ -44,15 +46,16 @@ jobs:
|
|
44
46
|
if: ${{ needs.pre.outputs.go == 'true' }}
|
45
47
|
|
46
48
|
steps:
|
47
|
-
- uses: actions/checkout@
|
49
|
+
- uses: actions/checkout@v3
|
48
50
|
|
49
|
-
- uses: actions/setup-node@
|
51
|
+
- uses: actions/setup-node@v3
|
50
52
|
with:
|
53
|
+
node-version-file: '.nvmrc'
|
51
54
|
cache: 'npm'
|
52
|
-
node-version: '14'
|
53
55
|
|
54
56
|
- uses: ruby/setup-ruby@v1
|
55
57
|
with:
|
58
|
+
ruby-version: '3'
|
56
59
|
bundler-cache: true
|
57
60
|
|
58
61
|
- name: Publish
|
data/.github/workflows/test.yaml
CHANGED
@@ -7,16 +7,21 @@ jobs:
|
|
7
7
|
name: Test
|
8
8
|
runs-on: ubuntu-latest
|
9
9
|
|
10
|
+
strategy:
|
11
|
+
matrix:
|
12
|
+
ruby: ['2.7', '3.2']
|
13
|
+
|
10
14
|
steps:
|
11
|
-
- uses: actions/checkout@
|
15
|
+
- uses: actions/checkout@v3
|
12
16
|
|
13
|
-
- uses: actions/setup-node@
|
17
|
+
- uses: actions/setup-node@v3
|
14
18
|
with:
|
15
|
-
node-version: '
|
19
|
+
node-version-file: '.nvmrc'
|
16
20
|
cache: 'npm'
|
17
21
|
|
18
22
|
- uses: ruby/setup-ruby@v1
|
19
23
|
with:
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
20
25
|
bundler-cache: true
|
21
26
|
|
22
27
|
- name: Run tests
|
data/.nvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
18
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 3.4.0
|
6
|
+
|
7
|
+
### New features
|
8
|
+
|
9
|
+
- Footer and header links now work with relative links. Thanks to [@eddgrant](https://github.com/eddgrant) for contributing this feature.
|
10
|
+
|
11
|
+
See [pull request #325: Support sites deployed on a path other than "/" when generating header and footer links](https://github.com/alphagov/tech-docs-gem/pull/325) for more details.
|
12
|
+
|
13
|
+
### Fixes
|
14
|
+
|
15
|
+
- You no longer need to downgrade Haml yourself, `bundle install` will now make sure Haml 6 is not installed (see issue [#318: Error: Filters is not a module](https://github.com/alphagov/tech-docs/gem/issues/318)).
|
16
|
+
|
5
17
|
## 3.3.1
|
6
18
|
|
7
19
|
This change solves a potential security issue with HTML snippets. Pages indexed in search results have their entire contents indexed, including any HTML code snippets. These HTML snippets would appear in the search results unsanitised, making it possible to render arbitrary HTML or run arbitrary scripts.
|
data/Gemfile
CHANGED
data/govuk_tech_docs.gemspec
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require "English"
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require "govuk_tech_docs/version"
|
5
6
|
|
6
7
|
`npm install`
|
7
|
-
abort
|
8
|
+
abort "npm install failed" unless $CHILD_STATUS.success?
|
8
9
|
|
9
|
-
unless File.exist?(
|
10
|
-
abort
|
10
|
+
unless File.exist?("node_modules/govuk-frontend/govuk/all.scss")
|
11
|
+
abort "govuk-frontend npm package not installed"
|
11
12
|
end
|
12
13
|
|
13
14
|
Gem::Specification.new do |spec|
|
@@ -16,8 +17,8 @@ Gem::Specification.new do |spec|
|
|
16
17
|
spec.authors = ["Government Digital Service"]
|
17
18
|
spec.email = ["govuk-dev@digital.cabinet-office.gov.uk"]
|
18
19
|
|
19
|
-
spec.summary =
|
20
|
-
spec.description =
|
20
|
+
spec.summary = "Gem to distribute the GOV.UK Tech Docs Template"
|
21
|
+
spec.description = "Gem to distribute the GOV.UK Tech Docs Template. See https://github.com/alphagov/tech-docs-gem for the project."
|
21
22
|
spec.homepage = "https://github.com/alphagov/tech-docs-gem"
|
22
23
|
spec.license = "MIT"
|
23
24
|
|
@@ -30,10 +31,13 @@ Gem::Specification.new do |spec|
|
|
30
31
|
|
31
32
|
spec.bindir = "exe"
|
32
33
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
|
-
spec.require_paths = [
|
34
|
+
spec.require_paths = %w[lib]
|
35
|
+
|
36
|
+
spec.required_ruby_version = ">= 2.7.0"
|
34
37
|
|
35
38
|
spec.add_dependency "autoprefixer-rails", "~> 10.2"
|
36
39
|
spec.add_dependency "chronic", "~> 0.10.2"
|
40
|
+
spec.add_dependency "haml", "< 6.0.0"
|
37
41
|
spec.add_dependency "middleman", "~> 4.0"
|
38
42
|
spec.add_dependency "middleman-autoprefixer", "~> 2.10.0"
|
39
43
|
spec.add_dependency "middleman-compass", ">= 4.0.0"
|
@@ -50,5 +54,5 @@ Gem::Specification.new do |spec|
|
|
50
54
|
spec.add_development_dependency "jasmine", "~> 3.5.0"
|
51
55
|
spec.add_development_dependency "rake", "~> 13.0"
|
52
56
|
spec.add_development_dependency "rspec", "~> 3.9.0"
|
53
|
-
spec.add_development_dependency "rubocop-govuk", "~>
|
57
|
+
spec.add_development_dependency "rubocop-govuk", "~> 4.10.0"
|
54
58
|
end
|
@@ -124,15 +124,15 @@ module GovukTechDocs
|
|
124
124
|
properties.merge!(all_of_schema.properties.to_h)
|
125
125
|
end
|
126
126
|
|
127
|
-
properties.
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
127
|
+
properties.transform_values do |schema|
|
128
|
+
case schema.type
|
129
|
+
when "object"
|
130
|
+
schema_properties(schema.items || schema)
|
131
|
+
when "array"
|
132
|
+
schema.items ? [schema_properties(schema.items)] : []
|
133
|
+
else
|
134
|
+
schema.example || schema.type
|
135
|
+
end
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
@@ -144,7 +144,7 @@ module GovukTechDocs
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def get_renderer(file)
|
147
|
-
template_path = File.join(File.dirname(__FILE__), "templates
|
147
|
+
template_path = File.join(File.dirname(__FILE__), "templates/#{file}")
|
148
148
|
template = File.open(template_path, "r").read
|
149
149
|
ERB.new(template)
|
150
150
|
end
|
@@ -1,18 +1,29 @@
|
|
1
|
+
require "uri"
|
1
2
|
module GovukTechDocs
|
2
3
|
module PathHelpers
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# Some useful notes from https://www.rubydoc.info/github/middleman/middleman/Middleman/Sitemap/Resource#url-instance_method :
|
5
|
+
# 'resource.path' is "The source path of this resource (relative to the source directory, without template extensions)."
|
6
|
+
# 'resource.destination_path', which is: "The output path in the build directory for this resource."
|
7
|
+
# 'resource.url' is based on 'resource.destination_path', but is further tweaked to optionally strip the index file and prefixed with any :http_prefix.
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
# Calculates the path to the sought resource, taking in to account whether the site has been configured
|
10
|
+
# to generate relative or absolute links.
|
11
|
+
# Identifies whether the sought resource is an internal or external target: External targets are returned untouched. Path calculation is performed for internal targets.
|
12
|
+
# Works for both "Middleman::Sitemap::Resource" resources and plain strings (which may be passed from the site configuration when generating header links).
|
13
|
+
#
|
14
|
+
# @param [Object] config
|
15
|
+
# @param [Object] resource
|
16
|
+
# @param [Object] current_page
|
17
|
+
def get_path_to_resource(config, resource, current_page)
|
18
|
+
if resource.is_a?(Middleman::Sitemap::Resource)
|
19
|
+
config[:relative_links] ? get_resource_path_relative_to_current_page(config, current_page.path, resource.path) : resource.url
|
20
|
+
elsif external_url?(resource)
|
21
|
+
resource
|
22
|
+
elsif config[:relative_links]
|
23
|
+
get_resource_path_relative_to_current_page(config, current_page.path, resource)
|
12
24
|
else
|
13
|
-
|
25
|
+
resource
|
14
26
|
end
|
15
|
-
resource_path
|
16
27
|
end
|
17
28
|
|
18
29
|
def path_to_site_root(config, page_path)
|
@@ -26,5 +37,24 @@ module GovukTechDocs
|
|
26
37
|
end
|
27
38
|
path_to_site_root
|
28
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# Calculates the path to the sought resource, relative to the current page.
|
44
|
+
# @param [Object] config Middleman config.
|
45
|
+
# @param [String] current_page path of the current page, from the site root.
|
46
|
+
# @param [String] resource_path_from_site_root path of the sought resource, from the site root.
|
47
|
+
def get_resource_path_relative_to_current_page(config, current_page, resource_path_from_site_root)
|
48
|
+
path_segments = resource_path_from_site_root.split("/").reject(&:empty?)[0..-2]
|
49
|
+
path_file_name = resource_path_from_site_root.split("/")[-1]
|
50
|
+
|
51
|
+
path_to_site_root = path_to_site_root config, current_page
|
52
|
+
path_to_site_root + path_segments.push(path_file_name).join("/")
|
53
|
+
end
|
54
|
+
|
55
|
+
def external_url?(url)
|
56
|
+
uri = URI.parse(url)
|
57
|
+
uri.scheme || uri.to_s.split("/")[0]&.include?(".")
|
58
|
+
end
|
29
59
|
end
|
30
60
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module GovukTechDocs
|
2
2
|
class Redirects
|
3
|
-
LEADING_SLASH = %r
|
3
|
+
LEADING_SLASH = %r{\A/}.freeze
|
4
4
|
|
5
5
|
def initialize(context)
|
6
6
|
@context = context
|
@@ -11,7 +11,7 @@ module GovukTechDocs
|
|
11
11
|
|
12
12
|
all_redirects.map do |from, to|
|
13
13
|
# Middleman needs paths without leading slashes
|
14
|
-
[from.sub(LEADING_SLASH, ""), to: to.sub(LEADING_SLASH, "")]
|
14
|
+
[from.sub(LEADING_SLASH, ""), { to: to.sub(LEADING_SLASH, "") }]
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -9,14 +9,14 @@ module GovukTechDocs
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def size
|
12
|
-
@element_name.scan(/h(\d)/) &&
|
12
|
+
@element_name.scan(/h(\d)/) && ::Regexp.last_match(1) && Integer(::Regexp.last_match(1))
|
13
13
|
end
|
14
14
|
|
15
15
|
def href
|
16
16
|
if @page_url != "" && size == 1
|
17
17
|
@page_url
|
18
18
|
else
|
19
|
-
|
19
|
+
"#{@page_url}##{@attributes['id']}"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -20,23 +20,23 @@ module GovukTechDocs
|
|
20
20
|
output = ""
|
21
21
|
|
22
22
|
if tree.heading
|
23
|
-
output += indentation + %
|
23
|
+
output += indentation + %(<a href="#{tree.heading.href}"><span>#{tree.heading.title}</span></a>\n)
|
24
24
|
end
|
25
25
|
|
26
26
|
if tree.children.any? && level < @max_level
|
27
|
-
output += indentation
|
27
|
+
output += "#{indentation}<ul>\n" unless level.zero?
|
28
28
|
|
29
29
|
tree.children.each do |child|
|
30
|
-
output += indentation
|
30
|
+
output += "#{indentation}#{INDENTATION_INCREMENT}<li>\n"
|
31
31
|
output += render_tree(
|
32
32
|
child,
|
33
33
|
indentation: indentation + INDENTATION_INCREMENT * 2,
|
34
34
|
level: level + 1,
|
35
35
|
)
|
36
|
-
output += indentation
|
36
|
+
output += "#{indentation}#{INDENTATION_INCREMENT}</li>\n"
|
37
37
|
end
|
38
38
|
|
39
|
-
output += indentation
|
39
|
+
output += "#{indentation}</ul>\n" unless level.zero?
|
40
40
|
end
|
41
41
|
|
42
42
|
output
|
@@ -32,7 +32,7 @@ module GovukTechDocs
|
|
32
32
|
headings = HeadingsBuilder.new(html, url).headings
|
33
33
|
|
34
34
|
if headings.none? { |heading| heading.size == 1 }
|
35
|
-
raise "No H1 tag found. You have to at least add one H1 heading to the page: "
|
35
|
+
raise "No H1 tag found. You have to at least add one H1 heading to the page: #{url}"
|
36
36
|
end
|
37
37
|
|
38
38
|
tree = HeadingTreeBuilder.new(headings).tree
|
@@ -67,12 +67,12 @@ module GovukTechDocs
|
|
67
67
|
if config[:http_prefix].end_with?("/")
|
68
68
|
config[:http_prefix]
|
69
69
|
else
|
70
|
-
config[:http_prefix]
|
70
|
+
"#{config[:http_prefix]}/"
|
71
71
|
end
|
72
72
|
|
73
73
|
link_value = get_path_to_resource(config, resource, current_page)
|
74
74
|
if resource.children.any? && resource.url != home_url
|
75
|
-
output += %
|
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
|
data/lib/govuk_tech_docs.rb
CHANGED
@@ -86,8 +86,8 @@ module GovukTechDocs
|
|
86
86
|
def active_page(page_path)
|
87
87
|
[
|
88
88
|
page_path == "/" && current_page.path == "index.html",
|
89
|
-
|
90
|
-
current_page.data.parent
|
89
|
+
"/#{current_page.path}" == page_path,
|
90
|
+
!current_page.data.parent.nil? && current_page.data.parent.to_s == page_path,
|
91
91
|
].any?
|
92
92
|
end
|
93
93
|
end
|
@@ -109,9 +109,9 @@ module GovukTechDocs
|
|
109
109
|
search.resources = [""]
|
110
110
|
|
111
111
|
search.fields = {
|
112
|
-
title:
|
112
|
+
title: { boost: 100, store: true, required: true },
|
113
113
|
content: { boost: 50, store: true },
|
114
|
-
url:
|
114
|
+
url: { index: false, store: true },
|
115
115
|
}
|
116
116
|
|
117
117
|
search.pipeline_remove = %w[stemmer stopWordFilter]
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<ul class="govuk-footer__inline-list">
|
7
7
|
<% config[:tech_docs][:footer_links].each do |title, path| %>
|
8
8
|
<li class="govuk-footer__inline-list-item">
|
9
|
-
<a class="govuk-footer__link" href="<%=
|
9
|
+
<a class="govuk-footer__link" href="<%= get_path_to_resource config, path, current_page %>"><%= title %></a>
|
10
10
|
</li>
|
11
11
|
<% end %>
|
12
12
|
</ul>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class="govuk-header__container govuk-header__container--full-width">
|
3
3
|
<div class="govuk-header__logo">
|
4
4
|
<% if config[:tech_docs][:service_link] %>
|
5
|
-
<a href="<%=
|
5
|
+
<a href="<%= get_path_to_resource config, config[:tech_docs][:service_link], current_page %>" class="govuk-header__link govuk-header__link--homepage">
|
6
6
|
<% else %>
|
7
7
|
<span class="govuk-header__link govuk-header__link--homepage">
|
8
8
|
<% end %>
|
@@ -46,7 +46,7 @@
|
|
46
46
|
<ul id="navigation" class="govuk-header__navigation-list">
|
47
47
|
<% config[:tech_docs][:header_links].each do |title, path| %>
|
48
48
|
<li class="govuk-header__navigation-item<% if active_page(path) %> govuk-header__navigation-item--active<% end %>">
|
49
|
-
<a class="govuk-header__link" href="<%=
|
49
|
+
<a class="govuk-header__link" href="<%= get_path_to_resource config, path, current_page %>"><%= title %></a>
|
50
50
|
</li>
|
51
51
|
<% end %>
|
52
52
|
</ul>
|