govspeak 10.4.0 → 10.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a3bf8e18b1cfd9bb3c71bf3774e9232c0c3defa120fd60f983fa9acf47c0b51
4
- data.tar.gz: 813f4543fa558f0394e29f06afcc52b6e95ed10714b25ae02607c7f185f78a8b
3
+ metadata.gz: e0c936c8543dbb14d96466ed3247e7a12270cd9235693b37905039a663f82988
4
+ data.tar.gz: b0b18ad7d4f43d2e6fda4a858ca310823551adf44d88c610ec38a51889f56e88
5
5
  SHA512:
6
- metadata.gz: 4aa85cc0a63094caaf65aef58851ece00cf9dd3cf32d2ff8c876758a07fb7d139ac7dc19a9b3446b73b8d31a8bef137c4b3b0e41ba1079223c4530fe95e212cf
7
- data.tar.gz: ccaa75526e6f9e947f1a2409156a60ca16d904b29c1a877ce8b84264ea2c655dd2a6991c2b992608d992ee26bb0ceb2189e1bc6b12f698091b9956b154f1ac25
6
+ metadata.gz: 8179405f6139a4890a70b5de379df13d772f8104311a7fa8ef841c66d74b4471d790769a03cc26511dc9540413e2366e7c4f46930552d1cbedadb81c3fa96d65
7
+ data.tar.gz: 10a9ef6773b3724fa13264fca599435bf69f6aeabd370b3ad263097bc86d4596492269b4e1150d5be5929a7d250b887d96f104b1346f7bbe6ad4040f17e316be
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 10.5.0
4
+
5
+ * Pass locale to child instances of `Govspeak::Document` (where one instance instantiates another) and to `HtmlValidator`
6
+ * Fall back to English when provided with an invalid locale or a translation is not available for the given locale
7
+
8
+ ## 10.4.1
9
+
10
+ * Update dependencies
11
+
3
12
  ## 10.4.0
4
13
 
5
14
  * Support abbreviations in informationals
@@ -4,6 +4,7 @@ class Govspeak::HtmlValidator
4
4
  def initialize(govspeak_string, options = {})
5
5
  @govspeak_string = govspeak_string.dup.force_encoding(Encoding::UTF_8)
6
6
  @allowed_image_hosts = options[:allowed_image_hosts]
7
+ @locale = options[:locale]
7
8
  end
8
9
 
9
10
  def invalid?
@@ -28,6 +29,7 @@ private
28
29
  govspeak_string,
29
30
  sanitize:,
30
31
  allowed_image_hosts: @allowed_image_hosts,
32
+ locale: @locale,
31
33
  ).to_html
32
34
  end
33
35
  end
@@ -150,12 +150,12 @@ module Govspeak
150
150
  extension("use custom footnotes") do |document|
151
151
  document.css("a.footnote").map do |el|
152
152
  footnote_number = el[:href].gsub(/\D/, "")
153
- label = I18n.t("govspeak.footnote.label", locale: govspeak_document.locale)
153
+ label = Govspeak::TranslationHelper.t_with_fallback("govspeak.footnote.label", locale: govspeak_document.locale)
154
154
  el.inner_html = "[#{label} #{footnote_number}]"
155
155
  end
156
156
  document.css("[role='doc-backlink']").map do |el|
157
157
  backlink_number = " #{el.css('sup')[0].content}" if el.css("sup")[0].present?
158
- aria_label = I18n.t("govspeak.footnote.backlink_aria_label", locale: govspeak_document.locale)
158
+ aria_label = Govspeak::TranslationHelper.t_with_fallback("govspeak.footnote.backlink_aria_label", locale: govspeak_document.locale)
159
159
  el["aria-label"] = "#{aria_label}#{backlink_number}"
160
160
  end
161
161
  end
@@ -35,7 +35,7 @@ module Govspeak
35
35
  lines = []
36
36
  lines << "<figcaption>"
37
37
  lines << %(<p>#{caption}</p>) if caption.present?
38
- lines << %(<p>#{I18n.t('govspeak.image.figure.credit', credit:, locale:)}</p>) if credit.present?
38
+ lines << %(<p>#{Govspeak::TranslationHelper.t_with_fallback('govspeak.image.figure.credit', credit:, locale:)}</p>) if credit.present?
39
39
  lines << "</figcaption>"
40
40
  lines.join
41
41
  end
@@ -14,10 +14,8 @@ module Govspeak
14
14
  erb.result(template_binding)
15
15
  end
16
16
 
17
- def t(*args)
18
- options = args.last.is_a?(Hash) ? args.last.dup : {}
19
- key = args.shift
20
- I18n.t!(key, **options.merge(locale:))
17
+ def t(key, **options)
18
+ Govspeak::TranslationHelper.t_with_fallback(key, **options.merge(locale:))
21
19
  end
22
20
 
23
21
  def format_with_html_line_breaks(string)
@@ -0,0 +1,18 @@
1
+ module Govspeak
2
+ module TranslationHelper
3
+ def self.t_with_fallback(key, **options)
4
+ if I18n.available_locales.none?(options[:locale]&.to_sym)
5
+ options[:locale] = I18n.default_locale
6
+ end
7
+
8
+ if options[:locale] != I18n.default_locale
9
+ options[:default] = I18n.t(
10
+ key,
11
+ **options.merge(locale: I18n.default_locale),
12
+ )
13
+ end
14
+
15
+ I18n.t(key, **options)
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Govspeak
2
- VERSION = "10.4.0".freeze
2
+ VERSION = "10.5.0".freeze
3
3
  end
data/lib/govspeak.rb CHANGED
@@ -17,6 +17,7 @@ require "govspeak/blockquote_extra_quote_remover"
17
17
  require "govspeak/post_processor"
18
18
  require "govspeak/link_extractor"
19
19
  require "govspeak/template_renderer"
20
+ require "govspeak/translation_helper"
20
21
  require "govspeak/presenters/attachment_presenter"
21
22
  require "govspeak/presenters/contact_presenter"
22
23
  require "govspeak/presenters/h_card_presenter"
@@ -94,7 +95,10 @@ module Govspeak
94
95
  end
95
96
 
96
97
  def valid?(validation_options = {})
97
- Govspeak::HtmlValidator.new(@source, validation_options).valid?
98
+ Govspeak::HtmlValidator.new(
99
+ @source,
100
+ validation_options.merge({ locale: @locale }),
101
+ ).valid?
98
102
  end
99
103
 
100
104
  def headers
@@ -152,13 +156,20 @@ module Govspeak
152
156
 
153
157
  def self.wrap_with_div(class_name, character, parser = Kramdown::Document)
154
158
  extension(class_name, surrounded_by(character)) do |body|
155
- content = parser ? parser.new("#{body.strip}\n").to_html : body.strip
159
+ content = if parser
160
+ parser.new("#{body.strip}\n", locale: @locale).to_html
161
+ else
162
+ body.strip
163
+ end
156
164
  %(\n<div class="#{class_name}">\n#{content}</div>\n)
157
165
  end
158
166
  end
159
167
 
160
168
  def insert_strong_inside_p(body, parser = Govspeak::Document)
161
- parser.new(body.strip).to_html.sub(/^<p>(.*)<\/p>$/, "<p><strong>\\1</strong></p>")
169
+ parser
170
+ .new(body.strip, locale: @locale)
171
+ .to_html
172
+ .sub(/^<p>(.*)<\/p>$/, "<p><strong>\\1</strong></p>")
162
173
  end
163
174
 
164
175
  extension("button", %r{
@@ -192,15 +203,14 @@ module Govspeak
192
203
 
193
204
  extension("highlight-answer") do |body|
194
205
  %(\n\n<div class="highlight-answer">
195
- #{Govspeak::Document.new(body.strip).to_html}</div>\n)
206
+ #{Govspeak::Document.new(body.strip, locale: @locale).to_html}</div>\n)
196
207
  end
197
208
 
198
209
  extension("stat-headline", %r${stat-headline}(.*?){/stat-headline}$m) do |body|
199
210
  %(\n\n<div class="stat-headline">
200
- #{Govspeak::Document.new(body.strip).to_html}</div>\n)
211
+ #{Govspeak::Document.new(body.strip, locale: @locale).to_html}</div>\n)
201
212
  end
202
213
 
203
- # FIXME: these surrounded_by arguments look dodgy
204
214
  extension("external", surrounded_by("x[", ")x")) do |body|
205
215
  Kramdown::Document.new("[#{body.strip}){:rel='external'}").to_html
206
216
  end
@@ -214,7 +224,7 @@ module Govspeak
214
224
  end
215
225
 
216
226
  extension("helpful", surrounded_by("%")) do |body|
217
- %(\n\n<div role="note" aria-label="Warning" class="application-notice help-notice">\n#{Govspeak::Document.new(body.strip).to_html}</div>\n)
227
+ %(\n\n<div role="note" aria-label="Warning" class="application-notice help-notice">\n#{Govspeak::Document.new(body.strip, locale: @locale).to_html}</div>\n)
218
228
  end
219
229
 
220
230
  extension("barchart", /{barchart(.*?)}/) do |captures|
@@ -350,13 +360,22 @@ module Govspeak
350
360
  northern-ireland
351
361
  wales
352
362
  london].each do |devolved_option|
353
- extension("devolved-#{devolved_option}", /:#{devolved_option}:(.*?):#{devolved_option}:/m) do |body|
354
- header_content = I18n.t("govspeak.devolved.#{devolved_option}", locale:)
363
+ extension(
364
+ "devolved-#{devolved_option}",
365
+ /:#{devolved_option}:(.*?):#{devolved_option}:/m,
366
+ ) do |body|
367
+ header_content = Govspeak::TranslationHelper.t_with_fallback(
368
+ "govspeak.devolved.#{devolved_option}",
369
+ locale:,
370
+ )
371
+ body_content = Govspeak::Document
372
+ .new(body.strip, locale: @locale)
373
+ .to_html
355
374
 
356
375
  <<~HTML
357
376
  <div class="devolved-content #{devolved_option}">
358
377
  <p class="devolved-header">#{header_content}</p>
359
- <div class="devolved-body">#{Govspeak::Document.new(body.strip).to_html}</div>
378
+ <div class="devolved-body">#{body_content}</div>
360
379
  </div>
361
380
  HTML
362
381
  end
@@ -422,3 +441,5 @@ end
422
441
  I18n.load_path.unshift(
423
442
  *Dir.glob(File.expand_path("locales/*.yml", Govspeak.root)),
424
443
  )
444
+
445
+ I18n.default_locale = :en
@@ -341,8 +341,6 @@ Teston
341
341
 
342
342
  # Regression test - the surrounded_by helper doesn't require the closing x
343
343
  # so 'xaa' was getting picked up by the external link helper above
344
- # TODO: review whether we should require closing symbols for these extensions
345
- # need to check all existing content.
346
344
  test_given_govspeak "xaa" do
347
345
  assert_html_output "<p>xaa</p>"
348
346
  assert_text_output "xaa"
data/test/test_helper.rb CHANGED
@@ -8,6 +8,7 @@ require "bundler"
8
8
  Bundler.setup :default, :development, :test
9
9
 
10
10
  require "minitest/autorun"
11
+ require "mocha/minitest"
11
12
 
12
13
  require "support/html_helpers"
13
14
 
@@ -0,0 +1,51 @@
1
+ require "test_helper"
2
+
3
+ class TranslationHelperTest < Minitest::Test
4
+ extend Minitest::Spec::DSL
5
+
6
+ describe ".t_with_fallback" do
7
+ before do
8
+ I18n.expects(:available_locales).returns(%i[en cy])
9
+ I18n
10
+ .expects(:default_locale)
11
+ .at_least_once
12
+ .at_most(2)
13
+ .returns(:en)
14
+ end
15
+
16
+ it "passes the provided key and options with a locale to I18n.t" do
17
+ I18n.expects(:t).with(
18
+ "whatever",
19
+ a_translation_variable: "my favourite value",
20
+ locale: instance_of(Symbol),
21
+ )
22
+
23
+ Govspeak::TranslationHelper.t_with_fallback(
24
+ "whatever",
25
+ a_translation_variable: "my favourite value",
26
+ )
27
+ end
28
+
29
+ it "passes the default locale to I18n.t when matching the provided locale" do
30
+ I18n.expects(:t).with("whatever", locale: :en)
31
+ Govspeak::TranslationHelper.t_with_fallback("whatever", locale: :en)
32
+ end
33
+
34
+ it "passes a fallback translation using the default locale to I18n.t when the provided locale is supported but non-default" do
35
+ I18n.expects(:t).with("whatever", locale: :en).returns("WHATEVER!")
36
+ I18n.expects(:t).with("whatever", locale: :cy, default: "WHATEVER!")
37
+
38
+ Govspeak::TranslationHelper.t_with_fallback("whatever", locale: :cy)
39
+ end
40
+
41
+ it "passes the default locale to I18n.t when the provided locale is unsupported" do
42
+ I18n.expects(:t).with("whatever", locale: :en)
43
+ Govspeak::TranslationHelper.t_with_fallback("whatever", locale: :yo)
44
+ end
45
+
46
+ it "passes the default locale to I18n.t when a locale is not provided" do
47
+ I18n.expects(:t).with("whatever", locale: :en)
48
+ Govspeak::TranslationHelper.t_with_fallback("whatever")
49
+ end
50
+ end
51
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govspeak
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.4.0
4
+ version: 10.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
@@ -179,6 +179,20 @@ dependencies:
179
179
  - - "~>"
180
180
  - !ruby/object:Gem::Version
181
181
  version: '5.14'
182
+ - !ruby/object:Gem::Dependency
183
+ name: mocha
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
182
196
  - !ruby/object:Gem::Dependency
183
197
  name: pry-byebug
184
198
  requirement: !ruby/object:Gem::Requirement
@@ -213,14 +227,14 @@ dependencies:
213
227
  requirements:
214
228
  - - '='
215
229
  - !ruby/object:Gem::Version
216
- version: 5.1.15
230
+ version: 5.1.17
217
231
  type: :development
218
232
  prerelease: false
219
233
  version_requirements: !ruby/object:Gem::Requirement
220
234
  requirements:
221
235
  - - '='
222
236
  - !ruby/object:Gem::Version
223
- version: 5.1.15
237
+ version: 5.1.17
224
238
  - !ruby/object:Gem::Dependency
225
239
  name: simplecov
226
240
  requirement: !ruby/object:Gem::Requirement
@@ -267,6 +281,7 @@ files:
267
281
  - lib/govspeak/presenters/image_presenter.rb
268
282
  - lib/govspeak/structured_header_extractor.rb
269
283
  - lib/govspeak/template_renderer.rb
284
+ - lib/govspeak/translation_helper.rb
270
285
  - lib/govspeak/version.rb
271
286
  - lib/kramdown/parser/govuk.rb
272
287
  - lib/templates/contact.html.erb
@@ -334,6 +349,7 @@ files:
334
349
  - test/presenters/h_card_presenter_test.rb
335
350
  - test/support/html_helpers.rb
336
351
  - test/test_helper.rb
352
+ - test/translation_helper_test.rb
337
353
  homepage: http://github.com/alphagov/govspeak
338
354
  licenses: []
339
355
  metadata: {}
@@ -351,7 +367,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
351
367
  - !ruby/object:Gem::Version
352
368
  version: '0'
353
369
  requirements: []
354
- rubygems_version: 3.6.9
370
+ rubygems_version: 3.7.0
355
371
  specification_version: 4
356
372
  summary: Markup language for single domain
357
373
  test_files:
@@ -379,3 +395,4 @@ test_files:
379
395
  - test/presenters/h_card_presenter_test.rb
380
396
  - test/support/html_helpers.rb
381
397
  - test/test_helper.rb
398
+ - test/translation_helper_test.rb