text_helpers 0.7.0 → 1.1.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 text_helpers might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.travis.yml +2 -1
- data/CHANGELOG.md +88 -0
- data/README.md +13 -3
- data/Rakefile +1 -0
- data/lib/text_helpers.rb +2 -2
- data/lib/text_helpers/translation.rb +14 -13
- data/lib/text_helpers/version.rb +1 -1
- data/test/lib/text_helpers/translation_test.rb +54 -5
- data/test/lib/text_helpers/version_test.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d4e0a6d2b19adb159000ea905c72b4023942ae268e36ac0eb9b39baf551e7460
|
4
|
+
data.tar.gz: ba520c7137fe2355dab9c1e29cbf215c2a19baccef7b246b850f188f909e81e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1fb87f89fbc7e42cfeab3fa224573097626b6dafd3c252076f7b13df1de5c7a8e8046b95207ba8d69dc9d50aa4290b2bd859166ef2cf17441bddad961ad8f10
|
7
|
+
data.tar.gz: 599e77b95ca58b291bf1d0348b65cfb4e7f2ff831e2a2850a2fd883df1e4fb9e6d569aecd1a209fb6cedf1df1e7aa9136be5ec3db55a6bc61b3ab2b3197d9eb5
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## [1.1.0] - 2020-12-02
|
4
|
+
|
5
|
+
### New Features
|
6
|
+
|
7
|
+
- Add `rel=noopener` to external links (thanks to @n00dle)
|
8
|
+
|
9
|
+
## [1.0.1] - 2020-12-02
|
10
|
+
|
11
|
+
### Changes
|
12
|
+
|
13
|
+
- Support cascading backends by default
|
14
|
+
|
15
|
+
## [1.0.0] - 2020-03-27
|
16
|
+
|
17
|
+
### Changes
|
18
|
+
|
19
|
+
- **(Breaking)** Drop explicit support for Ruby versions below 2.6
|
20
|
+
|
21
|
+
### Bug Fixes
|
22
|
+
|
23
|
+
- Properly support translations using I18n::Pluralization backend (thanks to @jhanggi)
|
24
|
+
|
25
|
+
## [0.7.2] - 2019-07-06
|
26
|
+
|
27
|
+
### Bug Fixes
|
28
|
+
|
29
|
+
- Improve orphaned text matcher targeting
|
30
|
+
|
31
|
+
## [0.7.1] - 2019-07-05
|
32
|
+
|
33
|
+
### Bug Fixes
|
34
|
+
|
35
|
+
- Prevent unnecessary non-breaking spaces in generated HTML
|
36
|
+
|
37
|
+
### Changes
|
38
|
+
|
39
|
+
- Improve `NotImplementedError` messaging (thanks to @stephen-puiszis)
|
40
|
+
- Update README with spec setup instructions (thanks to @jhanggi)
|
41
|
+
|
42
|
+
## [0.7.0] - 2016-05-06
|
43
|
+
|
44
|
+
### New features
|
45
|
+
|
46
|
+
- Automatically load entire locale directory via Railtie
|
47
|
+
|
48
|
+
## [0.6.1] - 2015-10-01
|
49
|
+
|
50
|
+
### Changes
|
51
|
+
|
52
|
+
- Bump version requirement for Redcarpet gem to address memory leaks
|
53
|
+
|
54
|
+
## [0.6.0] - 2015-06-15
|
55
|
+
|
56
|
+
### New Features
|
57
|
+
|
58
|
+
- Apply `target=_blank` attribute to anchor tags pointed at external URLs
|
59
|
+
|
60
|
+
## [0.5.3] - 2015-02-25
|
61
|
+
|
62
|
+
### Changes
|
63
|
+
|
64
|
+
- Update spec helpers for compatibility with RSpec 3 (thanks to @gabrielg)
|
65
|
+
|
66
|
+
## [0.5.2] - 2015-02-03
|
67
|
+
|
68
|
+
### Changes
|
69
|
+
|
70
|
+
- Support cascading backends for interpolated keys (thanks to @gabrielg)
|
71
|
+
|
72
|
+
## [0.5.1] - 2015-01-23
|
73
|
+
|
74
|
+
### New Features
|
75
|
+
|
76
|
+
- Add RSpec helpers (thanks to @gabrielg)
|
77
|
+
|
78
|
+
[1.1.0]: https://github.com/ahorner/text-helpers/compare/v1.0.1...v1.1.0
|
79
|
+
[1.0.1]: https://github.com/ahorner/text-helpers/compare/v1.0.0...v1.0.1
|
80
|
+
[1.0.0]: https://github.com/ahorner/text-helpers/compare/v0.7.2...v1.0.0
|
81
|
+
[0.7.2]: https://github.com/ahorner/text-helpers/compare/v0.7.1...v0.7.2
|
82
|
+
[0.7.1]: https://github.com/ahorner/text-helpers/compare/v0.7.0...v0.7.1
|
83
|
+
[0.7.0]: https://github.com/ahorner/text-helpers/compare/v0.6.1...v0.7.0
|
84
|
+
[0.6.1]: https://github.com/ahorner/text-helpers/compare/v0.6.0...v0.6.1
|
85
|
+
[0.6.0]: https://github.com/ahorner/text-helpers/compare/v0.5.3...v0.6.0
|
86
|
+
[0.5.3]: https://github.com/ahorner/text-helpers/compare/v0.5.2...v0.5.3
|
87
|
+
[0.5.2]: https://github.com/ahorner/text-helpers/compare/v0.5.1...v0.5.2
|
88
|
+
[0.5.1]: https://github.com/ahorner/text-helpers/compare/v0.5.0...v0.5.1
|
data/README.md
CHANGED
@@ -60,7 +60,9 @@ The controller text helpers described above can be accessed in controller specs
|
|
60
60
|
|
61
61
|
### Temporary/Stub Localizations
|
62
62
|
|
63
|
-
`text_helpers/rspec.rb` contains some helpers for setting up a test localization
|
63
|
+
`text_helpers/rspec.rb` contains some helpers for setting up a test localization
|
64
|
+
environment during your test runs. You can enable the helper methods by adding
|
65
|
+
the `:text_helpers` tag to the examples that require them.
|
64
66
|
|
65
67
|
To configure it, `require "text_helpers/rspec"` and configure the `before` and
|
66
68
|
`after` hooks appropriately:
|
@@ -69,11 +71,13 @@ To configure it, `require "text_helpers/rspec"` and configure the `before` and
|
|
69
71
|
require 'text_helpers/rspec'
|
70
72
|
|
71
73
|
RSpec.configure do |config|
|
74
|
+
config.include TextHelpers::RSpec::TestHelpers, text_helpers: true
|
75
|
+
|
72
76
|
config.before(:suite) do
|
73
77
|
TextHelpers::RSpec.setup_spec_translations
|
74
78
|
end
|
75
79
|
|
76
|
-
config.after(:each) do
|
80
|
+
config.after(:each, :text_helpers) do
|
77
81
|
TextHelpers::RSpec.reset_spec_translations
|
78
82
|
end
|
79
83
|
end
|
@@ -83,7 +87,13 @@ Temporary localizations can then be defined within your examples via the
|
|
83
87
|
`#set_translation` method, like so:
|
84
88
|
|
85
89
|
```
|
86
|
-
|
90
|
+
describe "with a translation set", :text_helpers do
|
91
|
+
before do
|
92
|
+
set_translation('models.user.attributes.name', 'Name')
|
93
|
+
end
|
94
|
+
|
95
|
+
it { ... }
|
96
|
+
end
|
87
97
|
```
|
88
98
|
|
89
99
|
## Configuration & Initialization
|
data/Rakefile
CHANGED
data/lib/text_helpers.rb
CHANGED
@@ -5,10 +5,10 @@ require "text_helpers/railtie" if defined?(Rails)
|
|
5
5
|
module TextHelpers
|
6
6
|
# RaiseExceptionHandler just raises all exceptions, rather than swallowing
|
7
7
|
# MissingTranslation ones. It's cribbed almost verbatim from
|
8
|
-
#
|
8
|
+
# https://guides.rubyonrails.org/i18n.html#using-different-exception-handlers.
|
9
9
|
class RaiseExceptionHandler < I18n::ExceptionHandler
|
10
10
|
def call(exception, locale, key, options)
|
11
|
-
if exception.is_a?(I18n::MissingTranslation)
|
11
|
+
if exception.is_a?(I18n::MissingTranslation) && key.to_s != "i18n.plural.rule"
|
12
12
|
raise exception.to_exception
|
13
13
|
else
|
14
14
|
super
|
@@ -12,7 +12,7 @@ module TextHelpers
|
|
12
12
|
attributes = [
|
13
13
|
("href=\"#{link}\"" if link),
|
14
14
|
("title=\"#{title}\"" if title),
|
15
|
-
("target=\"_blank\"" if link
|
15
|
+
("target=\"_blank\" rel=\"noopener\"" if link.match?(PROTOCOL_MATCHER)),
|
16
16
|
]
|
17
17
|
|
18
18
|
"<a #{attributes.compact.join(" ")}>#{content}</a>"
|
@@ -22,7 +22,8 @@ module TextHelpers
|
|
22
22
|
|
23
23
|
module Translation
|
24
24
|
|
25
|
-
ORPHAN_MATCHER =
|
25
|
+
ORPHAN_MATCHER = /(\w+)[ \t](?![^<]*>)(\S+\s*<\/(?:p|li)>)/.freeze
|
26
|
+
KEYPATH_MATCHER = /!([\w.\/]+)!/.freeze
|
26
27
|
|
27
28
|
# Public: Get the I18n localized text for the passed key.
|
28
29
|
#
|
@@ -34,17 +35,17 @@ module TextHelpers
|
|
34
35
|
# Returns a String resulting from the I18n lookup.
|
35
36
|
def text(key, options = {})
|
36
37
|
options = html_safe_options(options)
|
37
|
-
text = I18n.t(key, {
|
38
|
+
text = I18n.t(key, **{
|
38
39
|
scope: self.translation_scope,
|
39
|
-
default: "!#{key}!"
|
40
|
+
default: "!#{key}!",
|
41
|
+
cascade: true,
|
40
42
|
}.merge(options)).strip
|
41
43
|
|
42
|
-
interpolation_options = options
|
43
|
-
interpolation_options[:cascade] = true unless interpolation_options.has_key?(:cascade)
|
44
|
+
interpolation_options = { cascade: true }.merge(options)
|
44
45
|
|
45
46
|
# Interpolate any keypaths (e.g., `!some.lookup.path/key!`) found in the text.
|
46
|
-
while text
|
47
|
-
text = text.gsub(
|
47
|
+
while text.match?(KEYPATH_MATCHER) do
|
48
|
+
text = text.gsub(KEYPATH_MATCHER) { |match| I18n.t($1, **interpolation_options) }
|
48
49
|
end
|
49
50
|
|
50
51
|
text = smartify(text) if options.fetch(:smart, true)
|
@@ -65,7 +66,7 @@ module TextHelpers
|
|
65
66
|
def html(key, options = {})
|
66
67
|
rendered = markdown(text(key, options.merge(smart: false)))
|
67
68
|
|
68
|
-
rendered = options[:orphans] ? rendered : rendered.gsub(ORPHAN_MATCHER, ' \
|
69
|
+
rendered = options[:orphans] ? rendered : rendered.gsub(ORPHAN_MATCHER, '\1 \2')
|
69
70
|
rendered = rendered.gsub(/<\/?p>/, '') if options[:inline]
|
70
71
|
rendered.html_safe
|
71
72
|
end
|
@@ -82,7 +83,7 @@ module TextHelpers
|
|
82
83
|
smartify(@renderer.render(text))
|
83
84
|
end
|
84
85
|
|
85
|
-
#
|
86
|
+
# Internal: Auto-apply smart quotes to the passed text.
|
86
87
|
#
|
87
88
|
# text - A String which should be passed through the SmartyPants renderer.
|
88
89
|
#
|
@@ -91,16 +92,16 @@ module TextHelpers
|
|
91
92
|
Redcarpet::Render::SmartyPants.render(text)
|
92
93
|
end
|
93
94
|
|
94
|
-
#
|
95
|
+
# Internal: The proper scope for I18n translation.
|
95
96
|
#
|
96
97
|
# Must be implemented by any classes which include this module.
|
97
98
|
#
|
98
99
|
# Raises NotImplementedError.
|
99
100
|
def translation_scope
|
100
|
-
raise NotImplementedError
|
101
|
+
raise NotImplementedError, "must implement a public method `translation_scope` to determine I18n scope"
|
101
102
|
end
|
102
103
|
|
103
|
-
#
|
104
|
+
# Internal: Convert all passed in arguments into html-safe strings
|
104
105
|
#
|
105
106
|
# hash - a set of key-value pairs, which converts the second argument into an html-safe string
|
106
107
|
#
|
data/lib/text_helpers/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../../test_helper"
|
2
2
|
|
3
3
|
describe TextHelpers::Translation do
|
4
4
|
before do
|
@@ -9,6 +9,7 @@ describe TextHelpers::Translation do
|
|
9
9
|
before do
|
10
10
|
@scoped_text = "Scoped lookup"
|
11
11
|
@global_text = "Global lookup"
|
12
|
+
@single_word_text = "Single"
|
12
13
|
@email_address = "user@example.org"
|
13
14
|
@multiline_text = <<-MULTI.gsub(/^[ \t]+/, '')
|
14
15
|
This is some multiline text.
|
@@ -30,6 +31,8 @@ describe TextHelpers::Translation do
|
|
30
31
|
email_key: "<#{@email_address}>",
|
31
32
|
test_key: "*#{@scoped_text}*",
|
32
33
|
list_key: "* #{@scoped_text}",
|
34
|
+
single_word_list_key: "* #{@single_word_text}",
|
35
|
+
prerendered_html_key: "<ul>\n <li> Get everything you ever wanted</li>\n <li> Practically-guaranteed</li>\n </ul>",
|
33
36
|
interpolated_key: "Global? (!test_key!)",
|
34
37
|
interpolated_scoped_key: "Global? (!test_scoped_key!)",
|
35
38
|
interpol_arg_key: "Interpolate global? (!interpolated_key!)",
|
@@ -74,6 +77,22 @@ describe TextHelpers::Translation do
|
|
74
77
|
assert_equal expected, @helper.html(:list_key)
|
75
78
|
end
|
76
79
|
|
80
|
+
it "does not inject ` ` entities in HTML list items unnecessarily" do
|
81
|
+
expected = <<-EXPECTED.gsub(/^[ \t]+/, '')
|
82
|
+
<ul>
|
83
|
+
<li>#{@single_word_text}</li>
|
84
|
+
</ul>
|
85
|
+
EXPECTED
|
86
|
+
|
87
|
+
assert_equal expected, @helper.html(:single_word_list_key)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "correctly handles orphans in HTML with erratic whitespace" do
|
91
|
+
expected = "<ul>\n <li> Get everything you ever wanted</li>\n <li> Practically-guaranteed</li>\n </ul>\n"
|
92
|
+
|
93
|
+
assert_equal expected, @helper.html(:prerendered_html_key)
|
94
|
+
end
|
95
|
+
|
77
96
|
it "does not modify HTML tags" do
|
78
97
|
expected = "<p><a href=\"mailto:#{@email_address}\">#{@email_address}</a></p>\n"
|
79
98
|
assert_equal expected, @helper.html(:email_key)
|
@@ -100,12 +119,12 @@ describe TextHelpers::Translation do
|
|
100
119
|
assert_equal "<em>#{@scoped_text}</em>\n", @helper.html(:test_key, inline: true, orphans: true)
|
101
120
|
end
|
102
121
|
|
103
|
-
it "renders internal links without a target" do
|
122
|
+
it "renders internal links without a target or rel" do
|
104
123
|
assert_equal "<a href=\"/internal/path\">Internal link</a>\n", @helper.html(:internal_link, inline: true)
|
105
124
|
end
|
106
125
|
|
107
|
-
it "renders external links with target='_blank'" do
|
108
|
-
assert_equal "<a href=\"http://external.com\" target=\"_blank\">External link</a>\n", @helper.html(:external_link, inline: true)
|
126
|
+
it "renders external links with target='_blank' and rel='noopener'" do
|
127
|
+
assert_equal "<a href=\"http://external.com\" target=\"_blank\" rel=\"noopener\">External link</a>\n", @helper.html(:external_link, inline: true)
|
109
128
|
end
|
110
129
|
|
111
130
|
it "interpolates values wrapped in !!" do
|
@@ -152,10 +171,32 @@ describe TextHelpers::Translation do
|
|
152
171
|
assert_equal "This is what <b>Han</b> Solo said", @helper.text(:argument_key, user: "<b>Han</b> Solo".html_safe)
|
153
172
|
end
|
154
173
|
|
155
|
-
it "correctly handles
|
174
|
+
it "correctly handles pluralized keys" do
|
156
175
|
assert_equal "A single piece of text", @helper.text(:pluralized_key, count: 1)
|
157
176
|
assert_equal "2 pieces of text", @helper.text(:pluralized_key, count: 2)
|
158
177
|
end
|
178
|
+
|
179
|
+
describe "when the pluralization backend is configured and the exception handler is enabled" do
|
180
|
+
before do
|
181
|
+
@original_backend = I18n.backend
|
182
|
+
new_backend = @original_backend.dup
|
183
|
+
new_backend.extend(I18n::Backend::Pluralization)
|
184
|
+
I18n.backend = new_backend
|
185
|
+
|
186
|
+
@original_exception_handler = I18n.exception_handler
|
187
|
+
I18n.exception_handler = TextHelpers::RaiseExceptionHandler.new
|
188
|
+
end
|
189
|
+
|
190
|
+
after do
|
191
|
+
I18n.backend = @original_backend
|
192
|
+
I18n.exception_handler = @original_exception_handler
|
193
|
+
end
|
194
|
+
|
195
|
+
it "correctly handles pluralized keys" do
|
196
|
+
assert_equal "A single piece of text", @helper.text(:pluralized_key, count: 1)
|
197
|
+
assert_equal "2 pieces of text", @helper.text(:pluralized_key, count: 2)
|
198
|
+
end
|
199
|
+
end
|
159
200
|
end
|
160
201
|
|
161
202
|
describe "when no valid scope is provided" do
|
@@ -201,6 +242,14 @@ describe TextHelpers::Translation do
|
|
201
242
|
I18n.backend = @original_backend
|
202
243
|
end
|
203
244
|
|
245
|
+
it "cascades the requested key by default" do
|
246
|
+
I18n.backend.store_translations(:en, {test_scoped_key: "a translation"})
|
247
|
+
assert_equal "a translation", @helper.text(:test_scoped_key, scope: "some.unnecessary.scope")
|
248
|
+
|
249
|
+
I18n.backend.store_translations(:en, {some: {test_scoped_key: "a scoped translation"}})
|
250
|
+
assert_equal "a scoped translation", @helper.text(:test_scoped_key, scope: "some.unnecessary.scope")
|
251
|
+
end
|
252
|
+
|
204
253
|
it "cascades the interpolated key by default" do
|
205
254
|
I18n.backend.store_translations(:en, {test_scoped_key: "a translation"})
|
206
255
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: text_helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Horner
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -89,6 +89,7 @@ extra_rdoc_files: []
|
|
89
89
|
files:
|
90
90
|
- ".gitignore"
|
91
91
|
- ".travis.yml"
|
92
|
+
- CHANGELOG.md
|
92
93
|
- Gemfile
|
93
94
|
- LICENSE
|
94
95
|
- README.md
|
@@ -108,7 +109,7 @@ homepage: https://github.com/ahorner/text-helpers
|
|
108
109
|
licenses:
|
109
110
|
- MIT
|
110
111
|
metadata: {}
|
111
|
-
post_install_message:
|
112
|
+
post_install_message:
|
112
113
|
rdoc_options: []
|
113
114
|
require_paths:
|
114
115
|
- lib
|
@@ -123,9 +124,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
124
|
- !ruby/object:Gem::Version
|
124
125
|
version: '0'
|
125
126
|
requirements: []
|
126
|
-
|
127
|
-
|
128
|
-
signing_key:
|
127
|
+
rubygems_version: 3.1.4
|
128
|
+
signing_key:
|
129
129
|
specification_version: 4
|
130
130
|
summary: TextHelpers is a gem which supplies some basic utilities for text localization
|
131
131
|
in Rails projects. The library is intended to make it simple to keep your application's
|