meta-tags 2.22.3 → 2.24.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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +83 -0
- data/README.md +191 -60
- data/SECURITY.md +40 -0
- data/lib/generators/meta_tags/install_generator.rb +5 -0
- data/lib/generators/meta_tags/templates/config/initializers/meta_tags.rb +16 -5
- data/lib/meta_tags/configuration.rb +31 -10
- data/lib/meta_tags/content_tag.rb +3 -4
- data/lib/meta_tags/controller_helper.rb +11 -8
- data/lib/meta_tags/meta_tags_collection.rb +123 -50
- data/lib/meta_tags/railtie.rb +5 -0
- data/lib/meta_tags/renderer.rb +124 -84
- data/lib/meta_tags/tag.rb +10 -8
- data/lib/meta_tags/text_normalizer.rb +54 -40
- data/lib/meta_tags/version.rb +1 -1
- data/lib/meta_tags/view_helper.rb +65 -75
- data/lib/meta_tags.rb +6 -2
- data/sig/{lib/_internal/rails.rbs → _private/rails_support.rbs} +5 -19
- data/sig/lib/meta_tags/configuration.rbs +5 -3
- data/sig/lib/meta_tags/controller_helper.rbs +1 -1
- data/sig/lib/meta_tags/meta_tags_collection.rbs +9 -3
- data/sig/lib/meta_tags/rails_interfaces.rbs +15 -0
- data/sig/lib/meta_tags/renderer.rbs +11 -7
- data/sig/lib/meta_tags/tag.rbs +1 -1
- data/sig/lib/meta_tags/view_helper.rbs +9 -37
- data/sig/lib/meta_tags.rbs +5 -1
- data.tar.gz.sig +0 -0
- metadata +22 -5
- metadata.gz.sig +0 -0
data/lib/meta_tags/renderer.rb
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MetaTags
|
|
4
|
-
# This class is used by MetaTags
|
|
4
|
+
# This class is used by the MetaTags gem to render HTML meta tags on a page.
|
|
5
5
|
class Renderer
|
|
6
6
|
attr_reader :meta_tags, :normalized_meta_tags
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# @param [MetaTagsCollection] meta_tags meta tags object to render.
|
|
8
|
+
# Initializes a new instance of Renderer.
|
|
11
9
|
#
|
|
10
|
+
# @param meta_tags [MetaTagsCollection] meta tags object to render.
|
|
12
11
|
def initialize(meta_tags)
|
|
13
12
|
@meta_tags = meta_tags
|
|
14
13
|
@normalized_meta_tags = {}
|
|
@@ -16,7 +15,7 @@ module MetaTags
|
|
|
16
15
|
|
|
17
16
|
# Renders meta tags on the page.
|
|
18
17
|
#
|
|
19
|
-
# @param [ActionView::Base]
|
|
18
|
+
# @param view [ActionView::Base] Rails view object.
|
|
20
19
|
def render(view)
|
|
21
20
|
tags = [] # : Array[Tag]
|
|
22
21
|
|
|
@@ -43,8 +42,7 @@ module MetaTags
|
|
|
43
42
|
|
|
44
43
|
# Renders charset tag.
|
|
45
44
|
#
|
|
46
|
-
# @param [Array<Tag>]
|
|
47
|
-
#
|
|
45
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
48
46
|
def render_charset(tags)
|
|
49
47
|
charset = meta_tags.extract(:charset)
|
|
50
48
|
tags << Tag.new(:meta, charset: charset) if charset.present?
|
|
@@ -52,8 +50,7 @@ module MetaTags
|
|
|
52
50
|
|
|
53
51
|
# Renders title tag.
|
|
54
52
|
#
|
|
55
|
-
# @param [Array<Tag>]
|
|
56
|
-
#
|
|
53
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
57
54
|
def render_title(tags)
|
|
58
55
|
normalized_meta_tags[:title] = meta_tags.page_title
|
|
59
56
|
normalized_meta_tags[:site] = meta_tags[:site]
|
|
@@ -68,8 +65,7 @@ module MetaTags
|
|
|
68
65
|
|
|
69
66
|
# Renders icon(s) tag.
|
|
70
67
|
#
|
|
71
|
-
# @param [Array<Tag>]
|
|
72
|
-
#
|
|
68
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
73
69
|
def render_icon(tags)
|
|
74
70
|
icon = meta_tags.extract(:icon)
|
|
75
71
|
return unless icon
|
|
@@ -81,16 +77,16 @@ module MetaTags
|
|
|
81
77
|
|
|
82
78
|
icon.each do |icon_params|
|
|
83
79
|
icon_params = {rel: "icon", type: "image/x-icon"}.with_indifferent_access.merge(icon_params)
|
|
84
|
-
tags << Tag.new(:link, icon_params)
|
|
80
|
+
tags << Tag.new(:link, icon_params) if icon_params[:href].present?
|
|
85
81
|
end
|
|
86
82
|
end
|
|
87
83
|
|
|
88
84
|
# Renders meta tag with normalization (should have a corresponding normalize_
|
|
89
85
|
# method in TextNormalizer).
|
|
90
86
|
#
|
|
91
|
-
# @param [Array<Tag>]
|
|
87
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
88
|
+
# @param name [Symbol] meta tag name to normalize and render.
|
|
92
89
|
# @see TextNormalizer
|
|
93
|
-
#
|
|
94
90
|
def render_with_normalization(tags, name)
|
|
95
91
|
value = TextNormalizer.public_send(:"normalize_#{name}", meta_tags.extract(name))
|
|
96
92
|
normalized_meta_tags[name] = value
|
|
@@ -99,8 +95,7 @@ module MetaTags
|
|
|
99
95
|
|
|
100
96
|
# Renders noindex and nofollow meta tags.
|
|
101
97
|
#
|
|
102
|
-
# @param [Array<Tag>]
|
|
103
|
-
#
|
|
98
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
104
99
|
def render_noindex(tags)
|
|
105
100
|
meta_tags.extract_robots.each do |name, content|
|
|
106
101
|
tags << Tag.new(:meta, name: name, content: content) if content.present?
|
|
@@ -109,8 +104,7 @@ module MetaTags
|
|
|
109
104
|
|
|
110
105
|
# Renders refresh meta tag.
|
|
111
106
|
#
|
|
112
|
-
# @param [Array<Tag>]
|
|
113
|
-
#
|
|
107
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
114
108
|
def render_refresh(tags)
|
|
115
109
|
refresh = meta_tags.extract(:refresh)
|
|
116
110
|
tags << Tag.new(:meta, "http-equiv" => "refresh", :content => refresh.to_s) if refresh.present?
|
|
@@ -118,8 +112,7 @@ module MetaTags
|
|
|
118
112
|
|
|
119
113
|
# Renders alternate link tags.
|
|
120
114
|
#
|
|
121
|
-
# @param [Array<Tag>]
|
|
122
|
-
#
|
|
115
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
123
116
|
def render_alternate(tags)
|
|
124
117
|
alternate = meta_tags.extract(:alternate)
|
|
125
118
|
return unless alternate
|
|
@@ -130,15 +123,15 @@ module MetaTags
|
|
|
130
123
|
end
|
|
131
124
|
elsif alternate.is_a?(Array)
|
|
132
125
|
alternate.each do |link_params|
|
|
133
|
-
|
|
126
|
+
link_params = {rel: "alternate"}.with_indifferent_access.merge(link_params)
|
|
127
|
+
tags << Tag.new(:link, link_params) if link_params[:href].present?
|
|
134
128
|
end
|
|
135
129
|
end
|
|
136
130
|
end
|
|
137
131
|
|
|
138
|
-
# Renders
|
|
139
|
-
#
|
|
140
|
-
# @param [Array<Tag>] tags a buffer object to store tag in.
|
|
132
|
+
# Renders the OpenSearch link tag.
|
|
141
133
|
#
|
|
134
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
142
135
|
def render_open_search(tags)
|
|
143
136
|
open_search = meta_tags.extract(:open_search)
|
|
144
137
|
return unless open_search
|
|
@@ -152,8 +145,7 @@ module MetaTags
|
|
|
152
145
|
|
|
153
146
|
# Renders links.
|
|
154
147
|
#
|
|
155
|
-
# @param [Array<Tag>]
|
|
156
|
-
#
|
|
148
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
157
149
|
def render_links(tags)
|
|
158
150
|
[:amphtml, :prev, :next, :image_src, :manifest].each do |tag_name|
|
|
159
151
|
href = meta_tags.extract(tag_name)
|
|
@@ -164,13 +156,12 @@ module MetaTags
|
|
|
164
156
|
end
|
|
165
157
|
end
|
|
166
158
|
|
|
167
|
-
# Renders canonical link
|
|
168
|
-
#
|
|
169
|
-
# @param [Array<Tag>] tags a buffer object to store tag in.
|
|
159
|
+
# Renders the canonical link.
|
|
170
160
|
#
|
|
161
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
171
162
|
def render_canonical_link(tags)
|
|
172
|
-
href = meta_tags.extract(:canonical) # extract, so
|
|
173
|
-
return if MetaTags.config.skip_canonical_links_on_noindex && meta_tags
|
|
163
|
+
href = meta_tags.extract(:canonical) # extract, so it's not used anywhere else
|
|
164
|
+
return if MetaTags.config.skip_canonical_links_on_noindex && meta_tags.noindex?
|
|
174
165
|
return if href.blank?
|
|
175
166
|
|
|
176
167
|
@normalized_meta_tags[:canonical] = href
|
|
@@ -179,30 +170,28 @@ module MetaTags
|
|
|
179
170
|
|
|
180
171
|
# Renders complex hash objects.
|
|
181
172
|
#
|
|
182
|
-
# @param [Array<Tag>]
|
|
183
|
-
|
|
184
|
-
def render_hashes(tags, **opts)
|
|
173
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
174
|
+
def render_hashes(tags)
|
|
185
175
|
meta_tags.meta_tags.each_key do |property|
|
|
186
|
-
render_hash(tags, property
|
|
176
|
+
render_hash(tags, property)
|
|
187
177
|
end
|
|
188
178
|
end
|
|
189
179
|
|
|
190
180
|
# Renders a complex hash object by key.
|
|
191
181
|
#
|
|
192
|
-
# @param [Array<Tag>]
|
|
193
|
-
#
|
|
194
|
-
def render_hash(tags, key
|
|
182
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
183
|
+
# @param key [String, Symbol] top-level meta tag key.
|
|
184
|
+
def render_hash(tags, key)
|
|
195
185
|
data = meta_tags.meta_tags[key]
|
|
196
186
|
return unless data.is_a?(Hash)
|
|
197
187
|
|
|
198
|
-
process_hash(tags, key, data
|
|
188
|
+
process_hash(tags, key, data)
|
|
199
189
|
meta_tags.extract(key)
|
|
200
190
|
end
|
|
201
191
|
|
|
202
192
|
# Renders custom meta tags.
|
|
203
193
|
#
|
|
204
|
-
# @param [Array<Tag>]
|
|
205
|
-
#
|
|
194
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
206
195
|
def render_custom(tags)
|
|
207
196
|
meta_tags.meta_tags.each do |name, data|
|
|
208
197
|
Array(data).each do |val|
|
|
@@ -212,85 +201,136 @@ module MetaTags
|
|
|
212
201
|
end
|
|
213
202
|
end
|
|
214
203
|
|
|
215
|
-
# Recursive method to process all
|
|
216
|
-
#
|
|
217
|
-
# @param [Array<Tag>] tags a buffer object to store tag in.
|
|
218
|
-
# @param [String, Symbol] property a Hash or a String to render as meta tag.
|
|
219
|
-
# @param [Hash, Array, String, Symbol] content text content or a symbol reference to
|
|
220
|
-
# top-level meta tag.
|
|
204
|
+
# Recursive method to process all hashes and arrays in meta tags.
|
|
221
205
|
#
|
|
222
|
-
|
|
223
|
-
|
|
206
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
207
|
+
# @param property [String, Symbol] the meta tag property name.
|
|
208
|
+
# @param content [Hash, Array, String, Symbol] text content or a symbol
|
|
209
|
+
# reference to a top-level meta tag.
|
|
210
|
+
# @param itemprop [String, Symbol, nil] value of the itemprop attribute.
|
|
211
|
+
def process_tree(tags, property, content, itemprop: nil)
|
|
212
|
+
case content
|
|
224
213
|
when Hash
|
|
225
|
-
:
|
|
214
|
+
process_hash(tags, property, content, itemprop: itemprop)
|
|
226
215
|
when Array
|
|
227
|
-
:
|
|
216
|
+
process_array(tags, property, content, itemprop: itemprop)
|
|
228
217
|
else
|
|
229
|
-
|
|
230
|
-
|
|
218
|
+
if content.is_a?(Symbol) && MetaTags.config.resolve_symbolic_references_in_arrays
|
|
219
|
+
process_reference(tags, property, content, itemprop: itemprop)
|
|
220
|
+
else
|
|
221
|
+
render_tag(tags, property, content, itemprop: itemprop)
|
|
222
|
+
end
|
|
231
223
|
end
|
|
232
|
-
__send__(method, tags, property, content, itemprop: iprop, **opts)
|
|
233
224
|
end
|
|
234
225
|
|
|
235
|
-
# Recursive method to process a hash
|
|
226
|
+
# Recursive method to process a hash of meta tags.
|
|
236
227
|
#
|
|
237
|
-
# @param [Array<Tag>]
|
|
238
|
-
# @param [String, Symbol]
|
|
239
|
-
# @param [Hash]
|
|
240
|
-
#
|
|
241
|
-
def process_hash(tags, property, content,
|
|
242
|
-
|
|
228
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
229
|
+
# @param property [String, Symbol] the meta tag property name.
|
|
230
|
+
# @param content [Hash] nested meta tag attributes.
|
|
231
|
+
# @param itemprop [String, Symbol, nil] inherited itemprop value.
|
|
232
|
+
def process_hash(tags, property, content, itemprop: nil)
|
|
233
|
+
itemprop_key = content.key?(:itemprop) ? :itemprop : "itemprop"
|
|
234
|
+
current_itemprop = content.key?(itemprop_key) ? content[itemprop_key] : itemprop
|
|
235
|
+
|
|
243
236
|
content.each do |key, value|
|
|
237
|
+
next if key.to_s == "itemprop"
|
|
238
|
+
|
|
244
239
|
if key.to_s == "_"
|
|
245
|
-
iprop = itemprop
|
|
246
240
|
key = property
|
|
241
|
+
next_itemprop = current_itemprop
|
|
247
242
|
else
|
|
248
243
|
key = "#{property}:#{key}"
|
|
244
|
+
next_itemprop = nil
|
|
249
245
|
end
|
|
250
246
|
|
|
251
|
-
|
|
252
|
-
|
|
247
|
+
if value.is_a?(Symbol)
|
|
248
|
+
process_reference(tags, key, value, itemprop: next_itemprop)
|
|
253
249
|
else
|
|
254
|
-
value
|
|
250
|
+
process_tree(tags, key, value, itemprop: next_itemprop)
|
|
255
251
|
end
|
|
256
|
-
process_tree(tags, key, normalized_value, **opts.merge(itemprop: iprop))
|
|
257
252
|
end
|
|
258
253
|
end
|
|
259
254
|
|
|
260
|
-
# Recursive method to process
|
|
261
|
-
#
|
|
262
|
-
# @param [Array<Tag>]
|
|
263
|
-
# @param [String, Symbol]
|
|
264
|
-
# @param [Array]
|
|
265
|
-
#
|
|
266
|
-
def process_array(tags, property, content,
|
|
267
|
-
|
|
255
|
+
# Recursive method to process an array of meta tags.
|
|
256
|
+
#
|
|
257
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
258
|
+
# @param property [String, Symbol] the meta tag property name.
|
|
259
|
+
# @param content [Array] array of nested meta tag attributes or values.
|
|
260
|
+
# @param itemprop [String, Symbol, nil] value of the itemprop attribute.
|
|
261
|
+
def process_array(tags, property, content, itemprop: nil)
|
|
262
|
+
unless MetaTags.config.resolve_symbolic_references_in_arrays
|
|
263
|
+
symbol_reference = content.find { |value| value.is_a?(Symbol) }
|
|
264
|
+
if symbol_reference
|
|
265
|
+
MetaTags.deprecator.warn(
|
|
266
|
+
"Passing #{symbol_reference.inspect} directly inside a nested meta tag Array is deprecated. " \
|
|
267
|
+
"It is rendered literally in MetaTags 2.x but will be interpreted as a mirrored reference in MetaTags 3.0. " \
|
|
268
|
+
"Set MetaTags.config.resolve_symbolic_references_in_arrays = true to opt in now; this behavior will " \
|
|
269
|
+
"become the default in MetaTags 3.0. Use a String to keep a literal value."
|
|
270
|
+
)
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
content.each { |value| process_tree(tags, property, value, itemprop: itemprop) }
|
|
268
275
|
end
|
|
269
276
|
|
|
270
|
-
#
|
|
277
|
+
# Resolves a Symbol reference and processes its normalized value once.
|
|
271
278
|
#
|
|
272
|
-
# @param [Array<Tag>]
|
|
273
|
-
# @param [String, Symbol]
|
|
274
|
-
# @param [
|
|
275
|
-
#
|
|
276
|
-
|
|
279
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
280
|
+
# @param property [String, Symbol] the meta tag property name.
|
|
281
|
+
# @param reference [Symbol] normalized top-level meta tag reference.
|
|
282
|
+
# @param itemprop [String, Symbol, nil] value of the itemprop attribute.
|
|
283
|
+
def process_reference(tags, property, reference, itemprop: nil)
|
|
284
|
+
content = normalized_meta_tags[reference]
|
|
285
|
+
case content
|
|
286
|
+
when Hash
|
|
287
|
+
process_hash(tags, property, content, itemprop: itemprop)
|
|
288
|
+
when Array
|
|
289
|
+
process_array(tags, property, content, itemprop: itemprop)
|
|
290
|
+
else
|
|
291
|
+
render_tag(tags, property, content, itemprop: itemprop)
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Renders a single meta tag.
|
|
277
296
|
#
|
|
297
|
+
# @param tags [Array<Tag>] a buffer object to store tags in.
|
|
298
|
+
# @param name [String, Symbol] the meta tag name.
|
|
299
|
+
# @param value [String, Symbol] text content or a symbol reference to a
|
|
300
|
+
# top-level meta tag.
|
|
301
|
+
# @param itemprop [String, Symbol, nil] value of the itemprop attribute.
|
|
278
302
|
def render_tag(tags, name, value, itemprop: nil)
|
|
279
303
|
name_key ||= configured_name_key(name)
|
|
280
304
|
tags << Tag.new(:meta, name_key => name.to_s, :content => value, :itemprop => itemprop) if value.present?
|
|
281
305
|
end
|
|
282
306
|
|
|
283
|
-
# Returns meta tag property name for a
|
|
307
|
+
# Returns the meta tag property name for a given meta tag based on the
|
|
284
308
|
# configured list of property tags in MetaTags::Configuration#property_tags.
|
|
285
309
|
#
|
|
286
|
-
# @param [String, Symbol]
|
|
310
|
+
# @param name [String, Symbol] tag key.
|
|
287
311
|
# @return [Symbol] meta tag attribute name (:property or :name).
|
|
288
|
-
#
|
|
289
312
|
def configured_name_key(name)
|
|
313
|
+
name = name.to_s
|
|
290
314
|
is_property_tag = MetaTags.config.property_tags.any? do |tag_name|
|
|
291
|
-
name
|
|
315
|
+
property_tag?(name, tag_name.to_s)
|
|
292
316
|
end
|
|
293
317
|
is_property_tag ? :property : :name
|
|
294
318
|
end
|
|
319
|
+
|
|
320
|
+
# Returns true when a configured property tag matches the exact meta tag
|
|
321
|
+
# name or the start of a colon-delimited namespace.
|
|
322
|
+
#
|
|
323
|
+
# @param name [String] rendered meta tag name.
|
|
324
|
+
# @param tag_name [String] configured property tag name or namespace prefix.
|
|
325
|
+
# @return [Boolean]
|
|
326
|
+
def property_tag?(name, tag_name)
|
|
327
|
+
return false unless name.start_with?(tag_name)
|
|
328
|
+
|
|
329
|
+
tag_name_length = tag_name.bytesize
|
|
330
|
+
return true if name.bytesize == tag_name_length
|
|
331
|
+
return true if tag_name.getbyte(tag_name_length - 1) == 58
|
|
332
|
+
|
|
333
|
+
name.getbyte(tag_name_length) == 58
|
|
334
|
+
end
|
|
295
335
|
end
|
|
296
336
|
end
|
data/lib/meta_tags/tag.rb
CHANGED
|
@@ -7,26 +7,28 @@ module MetaTags
|
|
|
7
7
|
|
|
8
8
|
# Initializes a new instance of Tag class.
|
|
9
9
|
#
|
|
10
|
-
# @param [String, Symbol]
|
|
11
|
-
# @param [Hash]
|
|
12
|
-
#
|
|
10
|
+
# @param name [String, Symbol] HTML tag name.
|
|
11
|
+
# @param attributes [Hash] list of HTML tag attributes.
|
|
13
12
|
def initialize(name, attributes = {})
|
|
14
13
|
@name = name.to_s
|
|
15
14
|
@attributes = attributes
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
#
|
|
17
|
+
# Renders the tag in a Rails view.
|
|
19
18
|
#
|
|
20
|
-
# @param [ActionView::Base]
|
|
19
|
+
# @param view [ActionView::Base] instance of a Rails view.
|
|
21
20
|
# @return [String] HTML string for the tag.
|
|
22
|
-
#
|
|
23
21
|
def render(view)
|
|
24
|
-
view.tag(name,
|
|
22
|
+
view.tag(name, serialize_iso8601_attributes(attributes), MetaTags.config.open_meta_tags?)
|
|
25
23
|
end
|
|
26
24
|
|
|
27
25
|
protected
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
# Serializes attribute values that support ISO 8601 formatting.
|
|
28
|
+
#
|
|
29
|
+
# @param attributes [Hash] HTML tag attributes.
|
|
30
|
+
# @return [Hash] normalized HTML tag attributes.
|
|
31
|
+
def serialize_iso8601_attributes(attributes)
|
|
30
32
|
attributes.each do |key, value|
|
|
31
33
|
attributes[key] = value.iso8601 if value.respond_to?(:iso8601)
|
|
32
34
|
end
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MetaTags
|
|
4
|
-
#
|
|
4
|
+
# This module contains helpers that normalize text meta tag values.
|
|
5
5
|
module TextNormalizer
|
|
6
6
|
extend self
|
|
7
7
|
|
|
8
8
|
# Normalize title value.
|
|
9
9
|
#
|
|
10
|
-
# @param [String]
|
|
11
|
-
# @param [Array<String>] title
|
|
12
|
-
# @param [String]
|
|
13
|
-
# @param [
|
|
10
|
+
# @param site_title [String] site title.
|
|
11
|
+
# @param title [Array<String>] title segments.
|
|
12
|
+
# @param separator [String] a string to join title parts with.
|
|
13
|
+
# @param reverse [Boolean] whether title should be reversed.
|
|
14
14
|
# @return [String] title with HTML tags removed.
|
|
15
|
-
#
|
|
16
15
|
def normalize_title(site_title, title, separator, reverse = false)
|
|
17
16
|
clean_title = cleanup_strings(title)
|
|
18
17
|
clean_title.reverse! if reverse
|
|
@@ -35,13 +34,12 @@ module MetaTags
|
|
|
35
34
|
|
|
36
35
|
# Normalize description value.
|
|
37
36
|
#
|
|
38
|
-
# @param [String] description
|
|
39
|
-
# @return [String] text with tags removed, squashed spaces, truncated
|
|
40
|
-
#
|
|
41
|
-
#
|
|
37
|
+
# @param description [String] description string.
|
|
38
|
+
# @return [String] text with tags removed, squashed spaces, and truncated
|
|
39
|
+
# to the configured description limit.
|
|
42
40
|
def normalize_description(description)
|
|
43
41
|
# description could be another object not a string, but since it probably
|
|
44
|
-
# serves the same purpose we
|
|
42
|
+
# serves the same purpose, we can ask it to convert itself to a string
|
|
45
43
|
# and continue from there
|
|
46
44
|
description = cleanup_string(description)
|
|
47
45
|
return "" if description.blank?
|
|
@@ -51,9 +49,8 @@ module MetaTags
|
|
|
51
49
|
|
|
52
50
|
# Normalize keywords value.
|
|
53
51
|
#
|
|
54
|
-
# @param [String, Array<String>]
|
|
52
|
+
# @param keywords [String, Array<String>] list of keywords as a string or Array.
|
|
55
53
|
# @return [String] list of keywords joined with comma, with tags removed.
|
|
56
|
-
#
|
|
57
54
|
def normalize_keywords(keywords)
|
|
58
55
|
keywords = cleanup_strings(keywords)
|
|
59
56
|
return "" if keywords.blank?
|
|
@@ -68,16 +65,14 @@ module MetaTags
|
|
|
68
65
|
# Easy way to get access to Rails helpers.
|
|
69
66
|
#
|
|
70
67
|
# @return [ActionView::Base] proxy object to access Rails helpers.
|
|
71
|
-
#
|
|
72
68
|
def helpers
|
|
73
69
|
ActionController::Base.helpers
|
|
74
70
|
end
|
|
75
71
|
|
|
76
|
-
# Strips all HTML tags from
|
|
77
|
-
#
|
|
78
|
-
# @param [String] string HTML string.
|
|
79
|
-
# @return [String] html_safe string with no HTML tags.
|
|
72
|
+
# Strips all HTML tags from +string+, including comments.
|
|
80
73
|
#
|
|
74
|
+
# @param string [String] HTML string.
|
|
75
|
+
# @return [String] HTML-safe string with no HTML tags.
|
|
81
76
|
def strip_tags(string)
|
|
82
77
|
if defined?(Loofah)
|
|
83
78
|
# Instead of strip_tags we will use Loofah to strip tags from now on
|
|
@@ -87,25 +82,24 @@ module MetaTags
|
|
|
87
82
|
end
|
|
88
83
|
end
|
|
89
84
|
|
|
90
|
-
# This method returns
|
|
85
|
+
# This method returns an HTML-safe string similar to what <tt>Array#join</tt>
|
|
91
86
|
# would return. All items in the array, including the supplied separator, are
|
|
92
|
-
#
|
|
93
|
-
# as
|
|
87
|
+
# HTML-escaped unless they are HTML-safe, and the returned string is marked
|
|
88
|
+
# as HTML-safe.
|
|
94
89
|
#
|
|
95
|
-
# @param [Array<String>]
|
|
96
|
-
# @param [String]
|
|
90
|
+
# @param array [Array<String>] list of strings to join.
|
|
91
|
+
# @param sep [String] separator to join strings with.
|
|
97
92
|
# @return [String] input strings joined together using a given separator.
|
|
98
|
-
#
|
|
99
93
|
def safe_join(array, sep = $OFS)
|
|
100
94
|
helpers.safe_join(array, sep)
|
|
101
95
|
end
|
|
102
96
|
|
|
103
97
|
# Removes HTML tags and squashes down all the spaces.
|
|
104
98
|
#
|
|
105
|
-
# @param [String, nil]
|
|
106
|
-
# @
|
|
107
|
-
#
|
|
108
|
-
#
|
|
99
|
+
# @param string [String, nil] input string.
|
|
100
|
+
# @param strip [Boolean] whether to trim leading and trailing whitespace.
|
|
101
|
+
# @return [String] input string with no HTML tags and consecutive
|
|
102
|
+
# whitespace characters squashed into a single space.
|
|
109
103
|
def cleanup_string(string, strip: true)
|
|
110
104
|
return "" if string.nil?
|
|
111
105
|
raise ArgumentError, "Expected a string or an object that implements #to_str" unless string.respond_to?(:to_str)
|
|
@@ -118,24 +112,24 @@ module MetaTags
|
|
|
118
112
|
s
|
|
119
113
|
end
|
|
120
114
|
|
|
121
|
-
# Cleans multiple strings
|
|
115
|
+
# Cleans up multiple strings.
|
|
122
116
|
#
|
|
123
|
-
# @param [String, Array<String>]
|
|
117
|
+
# @param strings [String, Array<String>] input string(s).
|
|
118
|
+
# @param strip [Boolean] whether to trim leading and trailing whitespace.
|
|
124
119
|
# @return [Array<String>] clean strings.
|
|
125
120
|
# @see cleanup_string
|
|
126
|
-
#
|
|
127
121
|
def cleanup_strings(strings, strip: true)
|
|
128
122
|
strings = Array(strings).flatten.map! { |s| cleanup_string(s, strip: strip) }
|
|
129
123
|
strings.reject!(&:blank?)
|
|
130
124
|
strings
|
|
131
125
|
end
|
|
132
126
|
|
|
133
|
-
# Truncates a string to a specific limit.
|
|
127
|
+
# Truncates a string to a specific limit. Returns the string without
|
|
128
|
+
# truncation when the limit is 0 or nil.
|
|
134
129
|
#
|
|
135
|
-
# @param [String]
|
|
136
|
-
# @param [Integer,nil]
|
|
130
|
+
# @param string [String] input string.
|
|
131
|
+
# @param limit [Integer, nil] number of characters to truncate to.
|
|
137
132
|
# @return [String] truncated string.
|
|
138
|
-
#
|
|
139
133
|
def truncate(string, limit = nil)
|
|
140
134
|
return string if limit.to_i == 0
|
|
141
135
|
|
|
@@ -150,22 +144,22 @@ module MetaTags
|
|
|
150
144
|
|
|
151
145
|
# Truncates an array of strings to a specific limit.
|
|
152
146
|
#
|
|
153
|
-
# @param [Array<String>]
|
|
154
|
-
# @param [Integer,nil]
|
|
155
|
-
# @param [String] separator
|
|
147
|
+
# @param string_array [Array<String>] input strings.
|
|
148
|
+
# @param limit [Integer, nil] number of characters to truncate to.
|
|
149
|
+
# @param separator [String] separator that will be used to join the array later.
|
|
156
150
|
# @return [Array<String>] truncated array of strings.
|
|
157
|
-
#
|
|
158
151
|
def truncate_array(string_array, limit = nil, separator = "")
|
|
159
152
|
return string_array if limit.nil? || limit <= 0
|
|
160
153
|
|
|
161
154
|
length = 0
|
|
155
|
+
preserve_items = string_array.size > 1 && MetaTags.config.truncate_array_items_at_boundaries
|
|
162
156
|
result = [] # : Array[String]
|
|
163
157
|
|
|
164
158
|
string_array.each do |string|
|
|
165
159
|
limit_left = calculate_limit_left(limit, length, result, separator)
|
|
166
160
|
|
|
167
161
|
if string.length > limit_left
|
|
168
|
-
result << truncate(string, limit_left)
|
|
162
|
+
result << truncate(string, limit_left) if !preserve_items || result.empty?
|
|
169
163
|
break string_array
|
|
170
164
|
end
|
|
171
165
|
|
|
@@ -181,10 +175,23 @@ module MetaTags
|
|
|
181
175
|
|
|
182
176
|
private
|
|
183
177
|
|
|
178
|
+
# Calculates how many characters are left for the next segment.
|
|
179
|
+
#
|
|
180
|
+
# @param limit [Integer] total truncation limit.
|
|
181
|
+
# @param length [Integer] current accumulated length.
|
|
182
|
+
# @param result [Array<String>] accumulated string segments.
|
|
183
|
+
# @param separator [String] separator inserted between segments.
|
|
184
|
+
# @return [Integer] remaining number of characters.
|
|
184
185
|
def calculate_limit_left(limit, length, result, separator)
|
|
185
186
|
limit - length - (result.any? ? separator.length : 0)
|
|
186
187
|
end
|
|
187
188
|
|
|
189
|
+
# Truncates the site title and page title segments to the configured limit.
|
|
190
|
+
#
|
|
191
|
+
# @param site_title [String] site title.
|
|
192
|
+
# @param title [Array<String>] page title segments.
|
|
193
|
+
# @param separator [String] separator used between segments.
|
|
194
|
+
# @return [Array] truncated site title and title segments.
|
|
188
195
|
def truncate_title(site_title, title, separator)
|
|
189
196
|
global_limit = MetaTags.config.title_limit.to_i
|
|
190
197
|
if global_limit > 0
|
|
@@ -199,6 +206,13 @@ module MetaTags
|
|
|
199
206
|
[site_title, title]
|
|
200
207
|
end
|
|
201
208
|
|
|
209
|
+
# Calculates the title length limits for the site title and page title.
|
|
210
|
+
#
|
|
211
|
+
# @param site_title [String] site title.
|
|
212
|
+
# @param title [Array<String>] page title segments.
|
|
213
|
+
# @param separator [String] separator used between segments.
|
|
214
|
+
# @param global_limit [Integer] total allowed title length.
|
|
215
|
+
# @return [Array<Integer>] site title limit and page title limit.
|
|
202
216
|
def calculate_title_limits(site_title, title, separator, global_limit)
|
|
203
217
|
# What should we truncate first: site title or page title?
|
|
204
218
|
main_title = MetaTags.config.truncate_site_title_first ? title : [site_title]
|