govuk_navigation_helpers 7.3.0 → 7.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/config/tasklists/end-a-civil-partnership.json +339 -0
- data/config/tasklists/get-a-divorce.json +321 -0
- data/config/tasklists/learn-to-drive-a-car.json +262 -0
- data/govuk_navigation_helpers.gemspec +2 -0
- data/lib/govuk_navigation_helpers.rb +17 -8
- data/lib/govuk_navigation_helpers/current_tasklist_ab_test.rb +70 -0
- data/lib/govuk_navigation_helpers/tasklist_content.rb +120 -0
- data/lib/govuk_navigation_helpers/version.rb +1 -1
- data/spec/tasklist_content_spec.rb +269 -0
- metadata +37 -2
@@ -0,0 +1,262 @@
|
|
1
|
+
{
|
2
|
+
"title": "Learn to drive a car: step by step",
|
3
|
+
"base_path": "/learn-to-drive-a-car",
|
4
|
+
"description": "<p>Check what you need to do to learn to drive.</p>",
|
5
|
+
"links": {
|
6
|
+
"breadcrumbs": [
|
7
|
+
{ "title": "Home", "url": "/" },
|
8
|
+
{ "title": "Driving and transport", "url": "/browse/driving"},
|
9
|
+
{ "title": "Learning to drive", "url": "/browse/driving/learning-to-drive"}
|
10
|
+
]
|
11
|
+
},
|
12
|
+
"ab_test_prefix": "",
|
13
|
+
"related_paths": [
|
14
|
+
"/apply-for-your-full-driving-licence",
|
15
|
+
"/automatic-driving-licence-to-manual",
|
16
|
+
"/complain-about-a-driving-instructor",
|
17
|
+
"/driving-licence-fees",
|
18
|
+
"/driving-test-cost",
|
19
|
+
"/dvlaforms",
|
20
|
+
"/find-theory-test-pass-number",
|
21
|
+
"/government/publications/application-for-refunding-out-of-pocket-expenses",
|
22
|
+
"/government/publications/drivers-record-for-learner-drivers",
|
23
|
+
"/government/publications/driving-instructor-grades-explained",
|
24
|
+
"/government/publications/know-your-traffic-signs",
|
25
|
+
"/government/publications/l-plate-size-rules",
|
26
|
+
"/guidance/rules-for-observing-driving-tests",
|
27
|
+
"/report-an-illegal-driving-instructor",
|
28
|
+
"/report-driving-medical-condition",
|
29
|
+
"/report-driving-test-impersonation",
|
30
|
+
"/seat-belts-law",
|
31
|
+
"/speed-limits",
|
32
|
+
"/track-your-driving-licence-application",
|
33
|
+
"/vehicle-insurance",
|
34
|
+
"/driving-lessons-learning-to-drive/practising-with-family-or-friends",
|
35
|
+
"/driving-lessons-learning-to-drive/taking-driving-lessons",
|
36
|
+
"/driving-lessons-learning-to-drive/using-l-and-p-plates",
|
37
|
+
"/driving-test",
|
38
|
+
"/driving-test/changes-december-2017",
|
39
|
+
"/driving-test/disability-health-condition-or-learning-difficulty",
|
40
|
+
"/driving-test/driving-test-faults-result",
|
41
|
+
"/driving-test/test-cancelled-bad-weather",
|
42
|
+
"/driving-test/using-your-own-car",
|
43
|
+
"/driving-test/what-happens-during-test",
|
44
|
+
"/pass-plus/apply-for-a-pass-plus-certificate",
|
45
|
+
"/pass-plus/booking-pass-plus",
|
46
|
+
"/pass-plus/car-insurance-discounts",
|
47
|
+
"/pass-plus/local-councils-offering-discounts",
|
48
|
+
"/pass-plus/how-pass-plus-training-works",
|
49
|
+
"/theory-test",
|
50
|
+
"/theory-test/hazard-perception-test",
|
51
|
+
"/theory-test/if-you-have-safe-road-user-award",
|
52
|
+
"/theory-test/multiple-choice-questions",
|
53
|
+
"/theory-test/pass-mark-and-result",
|
54
|
+
"/theory-test/reading-difficulty-disability-or-health-condition"
|
55
|
+
],
|
56
|
+
"tasklist": {
|
57
|
+
"groups": [
|
58
|
+
[
|
59
|
+
{
|
60
|
+
"title": "Check you're allowed to drive",
|
61
|
+
"contents": [
|
62
|
+
{
|
63
|
+
"type": "paragraph",
|
64
|
+
"text": "Most people can start learning to drive when they’re 17."
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"type": "list",
|
68
|
+
"style": "required",
|
69
|
+
"contents": [
|
70
|
+
{
|
71
|
+
"href": "/vehicles-can-drive",
|
72
|
+
"text": "Check what age you can drive"
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"href": "/legal-obligations-drivers-riders",
|
76
|
+
"text": "Requirements for driving legally"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"href": "/driving-eyesight-rules",
|
80
|
+
"text": "Driving eyesight rules"
|
81
|
+
}
|
82
|
+
]
|
83
|
+
}
|
84
|
+
]
|
85
|
+
}
|
86
|
+
],
|
87
|
+
[
|
88
|
+
{
|
89
|
+
"title": "Get a provisional driving licence",
|
90
|
+
"contents": [
|
91
|
+
{
|
92
|
+
"type": "list",
|
93
|
+
"style": "required",
|
94
|
+
"contents": [
|
95
|
+
{
|
96
|
+
"href": "/apply-first-provisional-driving-licence",
|
97
|
+
"text": "Apply for your first provisional driving licence"
|
98
|
+
}
|
99
|
+
]
|
100
|
+
}
|
101
|
+
]
|
102
|
+
}
|
103
|
+
],
|
104
|
+
[
|
105
|
+
{
|
106
|
+
"title": "Driving lessons and practice",
|
107
|
+
"contents": [
|
108
|
+
{
|
109
|
+
"type": "paragraph",
|
110
|
+
"text": "You need a provisional driving licence to take lessons or practice."
|
111
|
+
},
|
112
|
+
{
|
113
|
+
"type": "list",
|
114
|
+
"style": "required",
|
115
|
+
"contents": [
|
116
|
+
{
|
117
|
+
"href": "/guidance/the-highway-code",
|
118
|
+
"text": "The Highway Code"
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"href": "/driving-lessons-learning-to-drive",
|
122
|
+
"text": "Taking driving lessons"
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"href": "/find-driving-schools-and-lessons",
|
126
|
+
"text": "Find driving schools, lessons and instructors"
|
127
|
+
},
|
128
|
+
{
|
129
|
+
"href": "/government/publications/car-show-me-tell-me-vehicle-safety-questions",
|
130
|
+
"text": "Practise vehicle safety questions"
|
131
|
+
}
|
132
|
+
]
|
133
|
+
}
|
134
|
+
]
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"title": "Prepare for your theory test",
|
138
|
+
"contents": [
|
139
|
+
{
|
140
|
+
"type": "list",
|
141
|
+
"style": "required",
|
142
|
+
"contents": [
|
143
|
+
{
|
144
|
+
"href": "/theory-test/revision-and-practice",
|
145
|
+
"text": "Theory test revision and practice"
|
146
|
+
},
|
147
|
+
{
|
148
|
+
"href": "/take-practice-theory-test",
|
149
|
+
"text": "Take a practice theory test"
|
150
|
+
},
|
151
|
+
{
|
152
|
+
"href": "https://www.safedrivingforlife.info/shop/product/official-dvsa-theory-test-kit-app-app",
|
153
|
+
"text": "Theory and hazard perception test app"
|
154
|
+
}
|
155
|
+
]
|
156
|
+
}
|
157
|
+
]
|
158
|
+
}
|
159
|
+
],
|
160
|
+
[
|
161
|
+
{
|
162
|
+
"title": "Book and manage your theory test",
|
163
|
+
"contents": [
|
164
|
+
{
|
165
|
+
"type": "paragraph",
|
166
|
+
"text": "You need a provisional driving licence to book your theory test."
|
167
|
+
},
|
168
|
+
{
|
169
|
+
"type": "list",
|
170
|
+
"style": "required",
|
171
|
+
"contents": [
|
172
|
+
{
|
173
|
+
"href": "/book-theory-test",
|
174
|
+
"text": "Book your theory test"
|
175
|
+
},
|
176
|
+
{
|
177
|
+
"href": "/theory-test/what-to-take",
|
178
|
+
"text": "What to take to your test"
|
179
|
+
},
|
180
|
+
{
|
181
|
+
"href": "/change-theory-test",
|
182
|
+
"text": "Change your theory test appointment"
|
183
|
+
},
|
184
|
+
{
|
185
|
+
"href": "/check-theory-test",
|
186
|
+
"text": "Check your theory test appointment details"
|
187
|
+
},
|
188
|
+
{
|
189
|
+
"href": "/cancel-theory-test",
|
190
|
+
"text": "Cancel your theory test"
|
191
|
+
}
|
192
|
+
]
|
193
|
+
}
|
194
|
+
]
|
195
|
+
}
|
196
|
+
],
|
197
|
+
[
|
198
|
+
{
|
199
|
+
"title": "Book and manage your driving test",
|
200
|
+
"contents": [
|
201
|
+
{
|
202
|
+
"type": "paragraph",
|
203
|
+
"text": "You must pass your theory test before you can book your driving test."
|
204
|
+
},
|
205
|
+
{
|
206
|
+
"type": "list",
|
207
|
+
"style": "required",
|
208
|
+
"contents": [
|
209
|
+
{
|
210
|
+
"href": "/book-driving-test",
|
211
|
+
"text": "Book your driving test"
|
212
|
+
},
|
213
|
+
{
|
214
|
+
"href": "/driving-test/what-to-take",
|
215
|
+
"text": "What to take to your test"
|
216
|
+
},
|
217
|
+
{
|
218
|
+
"href": "/change-driving-test",
|
219
|
+
"text": "Change your driving test appointment"
|
220
|
+
},
|
221
|
+
{
|
222
|
+
"href": "/check-driving-test",
|
223
|
+
"text": "Check your driving test appointment details"
|
224
|
+
},
|
225
|
+
{
|
226
|
+
"href": "/cancel-driving-test",
|
227
|
+
"text": "Cancel your driving test"
|
228
|
+
}
|
229
|
+
]
|
230
|
+
}
|
231
|
+
]
|
232
|
+
}
|
233
|
+
],
|
234
|
+
[
|
235
|
+
{
|
236
|
+
"title": "When you pass",
|
237
|
+
"contents": [
|
238
|
+
{
|
239
|
+
"type": "paragraph",
|
240
|
+
"text": "You can start driving as soon as you pass your driving test."
|
241
|
+
},
|
242
|
+
{
|
243
|
+
"type": "paragraph",
|
244
|
+
"text": "You must have an insurance policy that allows you to drive without supervision."
|
245
|
+
},
|
246
|
+
{
|
247
|
+
"type": "list",
|
248
|
+
"style": "required",
|
249
|
+
"style": "required",
|
250
|
+
"contents": [
|
251
|
+
{
|
252
|
+
"href": "/pass-plus",
|
253
|
+
"text": "Find out about Pass Plus training courses"
|
254
|
+
}
|
255
|
+
]
|
256
|
+
}
|
257
|
+
]
|
258
|
+
}
|
259
|
+
]
|
260
|
+
]
|
261
|
+
}
|
262
|
+
}
|
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_runtime_dependency "gds-api-adapters", ">= 43.0"
|
22
|
+
spec.add_runtime_dependency 'govuk_ab_testing', '~> 2.4'
|
23
|
+
spec.add_runtime_dependency 'activesupport', '~> 5.1'
|
22
24
|
|
23
25
|
spec.add_development_dependency "bundler", "~> 1.6"
|
24
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
@@ -1,11 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
5
|
-
require
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext/hash/keys'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
|
5
|
+
require 'govuk_ab_testing'
|
6
|
+
|
7
|
+
require_relative "govuk_navigation_helpers/version"
|
8
|
+
require_relative "govuk_navigation_helpers/breadcrumbs"
|
9
|
+
require_relative "govuk_navigation_helpers/related_items"
|
10
|
+
require_relative "govuk_navigation_helpers/taxon_breadcrumbs"
|
11
|
+
require_relative "govuk_navigation_helpers/taxonomy_sidebar"
|
12
|
+
require_relative "govuk_navigation_helpers/related_navigation_sidebar"
|
13
|
+
require_relative "govuk_navigation_helpers/rummager_taxonomy_sidebar_links"
|
14
|
+
require_relative "govuk_navigation_helpers/curated_taxonomy_sidebar_links"
|
15
|
+
|
16
|
+
require_relative "govuk_navigation_helpers/tasklist_content"
|
17
|
+
require_relative "govuk_navigation_helpers/current_tasklist_ab_test"
|
9
18
|
|
10
19
|
module GovukNavigationHelpers
|
11
20
|
class NavigationHelper
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module GovukNavigationHelpers
|
2
|
+
class CurrentTasklistAbTest
|
3
|
+
TASKLIST_HEADER_DIMENSION = 44
|
4
|
+
TASKLIST_SIDEBAR_DIMENSION = 66
|
5
|
+
PUBLICATION_PAGE = "/government/publications/car-show-me-tell-me-vehicle-safety-questions".freeze
|
6
|
+
|
7
|
+
def initialize(current_tasklist:, request:)
|
8
|
+
@current_tasklist = current_tasklist
|
9
|
+
@ab_test_prefix = current_tasklist.ab_test_prefix if current_tasklist
|
10
|
+
@request = request
|
11
|
+
end
|
12
|
+
|
13
|
+
def eligible?
|
14
|
+
!! current_tasklist
|
15
|
+
end
|
16
|
+
|
17
|
+
def header
|
18
|
+
@header ||= set_ab_test(
|
19
|
+
name: "#{ab_test_prefix}TaskListHeader",
|
20
|
+
dimension: TASKLIST_HEADER_DIMENSION
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def sidebar
|
25
|
+
@sidebar ||= set_ab_test(
|
26
|
+
name: "#{ab_test_prefix}TaskListSidebar",
|
27
|
+
dimension: TASKLIST_SIDEBAR_DIMENSION
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def sidebar_variant
|
32
|
+
@sidebar_variant ||=
|
33
|
+
sidebar.requested_variant(request.headers)
|
34
|
+
end
|
35
|
+
|
36
|
+
def header_variant
|
37
|
+
@header_variant ||=
|
38
|
+
header.requested_variant(request.headers)
|
39
|
+
end
|
40
|
+
|
41
|
+
def show_tasklist_sidebar?
|
42
|
+
sidebar_variant.variant?('B')
|
43
|
+
end
|
44
|
+
|
45
|
+
def show_tasklist_header?
|
46
|
+
header_variant.variant?('B')
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_response_header(response)
|
50
|
+
sidebar_variant.configure_response(response) if show_tasklist_sidebar?
|
51
|
+
header_variant.configure_response(response) if show_tasklist_header?
|
52
|
+
end
|
53
|
+
|
54
|
+
def publication_with_sidebar?
|
55
|
+
show_tasklist_sidebar? && request.path == PUBLICATION_PAGE
|
56
|
+
end
|
57
|
+
|
58
|
+
def publication_with_sidebar_template_name
|
59
|
+
"publication_with_tasklist_sidebar"
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
attr_reader :current_tasklist, :ab_test_prefix, :request
|
65
|
+
|
66
|
+
def set_ab_test(name:, dimension:)
|
67
|
+
GovukAbTesting::AbTest.new(name, dimension: dimension)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module GovukNavigationHelpers
|
2
|
+
class TasklistContent
|
3
|
+
TASKLIST_NAMES = %w(
|
4
|
+
get-a-divorce
|
5
|
+
end-a-civil-partnership
|
6
|
+
learn-to-drive-a-car
|
7
|
+
).freeze
|
8
|
+
|
9
|
+
def self.current_tasklist(path)
|
10
|
+
TASKLIST_NAMES.each do |tasklist_name|
|
11
|
+
tasklist = new(file_name: tasklist_name, path: path)
|
12
|
+
return tasklist if tasklist.current?
|
13
|
+
end
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(file_name: nil, path: nil)
|
18
|
+
@file_name = file_name
|
19
|
+
@path = path
|
20
|
+
end
|
21
|
+
|
22
|
+
def title
|
23
|
+
parsed_file.dig(:title)
|
24
|
+
end
|
25
|
+
|
26
|
+
def base_path
|
27
|
+
parsed_file.dig(:base_path)
|
28
|
+
end
|
29
|
+
|
30
|
+
def tasklist
|
31
|
+
parsed_file.dig(:tasklist)
|
32
|
+
end
|
33
|
+
|
34
|
+
def ab_test_prefix
|
35
|
+
parsed_file.dig(:ab_test_prefix)
|
36
|
+
end
|
37
|
+
|
38
|
+
def skip_link
|
39
|
+
"##{groups.flatten.first[:title].downcase.tr(' ', '-')}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def primary_paths
|
43
|
+
primary_content.map { |content|
|
44
|
+
content[:href] unless content[:href].start_with?('http')
|
45
|
+
}.select(&:present?)
|
46
|
+
end
|
47
|
+
|
48
|
+
def groups
|
49
|
+
tasklist.dig(:groups)
|
50
|
+
end
|
51
|
+
|
52
|
+
def related_paths
|
53
|
+
parsed_file.dig(:related_paths)
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_current_task
|
57
|
+
set_task_as_active_if_current_page
|
58
|
+
end
|
59
|
+
|
60
|
+
def is_page_included_in_ab_test?
|
61
|
+
primary_paths.include?(path) ||
|
62
|
+
related_paths.include?(path)
|
63
|
+
end
|
64
|
+
|
65
|
+
def current?
|
66
|
+
primary_paths.include?(path) ||
|
67
|
+
related_paths.include?(path)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
attr_reader :file_name, :file, :path
|
73
|
+
|
74
|
+
def set_task_as_active_if_current_page
|
75
|
+
counter = 0
|
76
|
+
|
77
|
+
groups.each_with_index.each do |grouped_steps, group_index|
|
78
|
+
grouped_steps.each do |step|
|
79
|
+
counter += 1
|
80
|
+
|
81
|
+
step[:contents].each do |content|
|
82
|
+
next unless content[:contents]
|
83
|
+
|
84
|
+
content[:contents].each do |link|
|
85
|
+
if link[:href] == path
|
86
|
+
link[:active] = true
|
87
|
+
tasklist[:show_step] = counter
|
88
|
+
tasklist[:highlight_group] = group_index + 1
|
89
|
+
return tasklist
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
tasklist
|
97
|
+
end
|
98
|
+
|
99
|
+
def primary_content
|
100
|
+
primary_content = groups.flat_map do |grouped_steps|
|
101
|
+
grouped_steps.flat_map do |group|
|
102
|
+
group[:contents].select { |content| content[:contents] }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
primary_content.flat_map { |hash| hash[:contents] }
|
107
|
+
end
|
108
|
+
|
109
|
+
def parsed_file
|
110
|
+
@parsed_file ||=
|
111
|
+
JSON.parse(
|
112
|
+
File.read(
|
113
|
+
File.join(File.dirname(__FILE__), "../../", "config", "tasklists", "#{file_name}.json")
|
114
|
+
)
|
115
|
+
).deep_symbolize_keys.tap do |json_file|
|
116
|
+
json_file[:tasklist].merge!(small: true, heading_level: 3)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|