meta-tags 2.4.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.codeclimate.yml +2 -3
- data/.rubocop.yml +110 -107
- data/.travis.yml +16 -28
- data/CHANGELOG.md +27 -19
- data/Gemfile +0 -1
- data/README.md +237 -214
- data/lib/meta_tags.rb +1 -0
- data/lib/meta_tags/configuration.rb +44 -0
- data/lib/meta_tags/meta_tags_collection.rb +7 -7
- data/lib/meta_tags/renderer.rb +54 -50
- data/lib/meta_tags/text_normalizer.rb +21 -11
- data/lib/meta_tags/version.rb +1 -1
- data/meta-tags.gemspec +1 -1
- metadata +2 -2
- metadata.gz.sig +0 -0
data/lib/meta_tags.rb
CHANGED
@@ -9,13 +9,57 @@ module MetaTags
|
|
9
9
|
attr_accessor :keywords_limit
|
10
10
|
# Keywords separator - a string to join keywords with.
|
11
11
|
attr_accessor :keywords_separator
|
12
|
+
# Custom meta tags that should use `property` attribute instead of `name`
|
13
|
+
# - an array of strings or symbols representing their names or name-prefixes.
|
14
|
+
attr_accessor :property_tags
|
12
15
|
|
13
16
|
# Initializes a new instance of Configuration class.
|
14
17
|
def initialize
|
18
|
+
reset_defaults!
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_property_tags
|
22
|
+
[
|
23
|
+
# App Link metadata https://developers.facebook.com/docs/applinks/metadata-reference
|
24
|
+
'al',
|
25
|
+
# Open Graph Markup https://developers.facebook.com/docs/sharing/webmasters#markup
|
26
|
+
'fb',
|
27
|
+
'og',
|
28
|
+
# Facebook OpenGraph Object Types https://developers.facebook.com/docs/reference/opengraph
|
29
|
+
'article',
|
30
|
+
'book',
|
31
|
+
'books:author',
|
32
|
+
'books:book',
|
33
|
+
'books:genre',
|
34
|
+
'business:business',
|
35
|
+
'fitness:course',
|
36
|
+
'game:achievement',
|
37
|
+
'music:album',
|
38
|
+
'music:playlist',
|
39
|
+
'music:radio_station',
|
40
|
+
'music:song',
|
41
|
+
'place',
|
42
|
+
'product',
|
43
|
+
'product:group',
|
44
|
+
'product:item',
|
45
|
+
'profile',
|
46
|
+
'restaurant:menu',
|
47
|
+
'restaurant:menu_item',
|
48
|
+
'restaurant:menu_section',
|
49
|
+
'restaurant:restaurant',
|
50
|
+
'video:episode',
|
51
|
+
'video:movie',
|
52
|
+
'video:other',
|
53
|
+
'video:tv_show',
|
54
|
+
].freeze
|
55
|
+
end
|
56
|
+
|
57
|
+
def reset_defaults!
|
15
58
|
@title_limit = 70
|
16
59
|
@description_limit = 160
|
17
60
|
@keywords_limit = 255
|
18
61
|
@keywords_separator = ', '
|
62
|
+
@property_tags = default_property_tags.dup
|
19
63
|
end
|
20
64
|
end
|
21
65
|
end
|
@@ -57,7 +57,7 @@ module MetaTags
|
|
57
57
|
# @return [String] page title.
|
58
58
|
#
|
59
59
|
def full_title(defaults = {})
|
60
|
-
with_defaults(defaults) { extract_full_title
|
60
|
+
with_defaults(defaults) { extract_full_title }
|
61
61
|
end
|
62
62
|
|
63
63
|
# Deletes and returns a meta tag value by name.
|
@@ -85,7 +85,7 @@ module MetaTags
|
|
85
85
|
site_title = extract(:site) || ''
|
86
86
|
title = extract_title || []
|
87
87
|
separator = extract_separator
|
88
|
-
reverse = extract(:reverse)
|
88
|
+
reverse = extract(:reverse) == true
|
89
89
|
|
90
90
|
TextNormalizer.normalize_title(site_title, title, separator, reverse)
|
91
91
|
end
|
@@ -99,7 +99,7 @@ module MetaTags
|
|
99
99
|
return unless title
|
100
100
|
|
101
101
|
title = Array(title)
|
102
|
-
title.each(&:downcase!) if extract(:lowercase)
|
102
|
+
title.each(&:downcase!) if extract(:lowercase) == true
|
103
103
|
title
|
104
104
|
end
|
105
105
|
|
@@ -108,7 +108,7 @@ module MetaTags
|
|
108
108
|
# @return [String] page title separator.
|
109
109
|
#
|
110
110
|
def extract_separator
|
111
|
-
if meta_tags[:separator]
|
111
|
+
if meta_tags[:separator] == false
|
112
112
|
# Special case: if separator is hidden, do not display suffix/prefix
|
113
113
|
prefix = separator = suffix = ''
|
114
114
|
else
|
@@ -147,7 +147,7 @@ module MetaTags
|
|
147
147
|
# @return [HashWithIndifferentAccess] normalized meta tags list.
|
148
148
|
#
|
149
149
|
def normalize_open_graph(meta_tags)
|
150
|
-
meta_tags = meta_tags.
|
150
|
+
meta_tags = meta_tags.kind_of?(HashWithIndifferentAccess) ? meta_tags.dup : meta_tags.with_indifferent_access
|
151
151
|
meta_tags[:og] = meta_tags.delete(:open_graph) if meta_tags.key?(:open_graph)
|
152
152
|
meta_tags
|
153
153
|
end
|
@@ -160,7 +160,7 @@ module MetaTags
|
|
160
160
|
# @return [String] separator segment value.
|
161
161
|
#
|
162
162
|
def extract_separator_section(name, default)
|
163
|
-
meta_tags[name]
|
163
|
+
meta_tags[name] == false ? '' : (meta_tags[name] || default)
|
164
164
|
end
|
165
165
|
|
166
166
|
# Extracts noindex attribute name and value without deleting it from meta tags list.
|
@@ -170,7 +170,7 @@ module MetaTags
|
|
170
170
|
#
|
171
171
|
def extract_noindex_attribute(name)
|
172
172
|
noindex = extract(name)
|
173
|
-
noindex_name = String
|
173
|
+
noindex_name = noindex.kind_of?(String) ? noindex : 'robots'
|
174
174
|
noindex_value = noindex ? name.to_s : nil
|
175
175
|
|
176
176
|
[ noindex_name, noindex_value ]
|
data/lib/meta_tags/renderer.rb
CHANGED
@@ -29,11 +29,6 @@ module MetaTags
|
|
29
29
|
render_open_search(tags)
|
30
30
|
render_links(tags)
|
31
31
|
|
32
|
-
render_hash(tags, :og, name_key: :property)
|
33
|
-
render_hash(tags, :al, name_key: :property)
|
34
|
-
render_hash(tags, :fb, name_key: :property)
|
35
|
-
render_hash(tags, :article, name_key: :property)
|
36
|
-
render_hash(tags, :place, name_key: :property)
|
37
32
|
render_hashes(tags)
|
38
33
|
render_custom(tags)
|
39
34
|
|
@@ -42,15 +37,13 @@ module MetaTags
|
|
42
37
|
|
43
38
|
protected
|
44
39
|
|
45
|
-
|
46
40
|
# Renders charset tag.
|
47
41
|
#
|
48
42
|
# @param [Array<Tag>] tags a buffer object to store tag in.
|
49
43
|
#
|
50
44
|
def render_charset(tags)
|
51
|
-
|
52
|
-
|
53
|
-
end
|
45
|
+
charset = meta_tags.extract(:charset)
|
46
|
+
tags << Tag.new(:meta, charset: charset) if charset.present?
|
54
47
|
end
|
55
48
|
|
56
49
|
# Renders title tag.
|
@@ -68,15 +61,16 @@ module MetaTags
|
|
68
61
|
# @param [Array<Tag>] tags a buffer object to store tag in.
|
69
62
|
#
|
70
63
|
def render_icon(tags)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
64
|
+
icon = meta_tags.extract(:icon)
|
65
|
+
return unless icon
|
66
|
+
|
67
|
+
if icon.kind_of?(String)
|
68
|
+
tags << Tag.new(:link, rel: 'icon', href: icon, type: 'image/x-icon')
|
69
|
+
else
|
70
|
+
icon = [icon] if icon.kind_of?(Hash)
|
71
|
+
icon.each do |icon_params|
|
72
|
+
icon_params = { rel: 'icon', type: 'image/x-icon' }.with_indifferent_access.merge(icon_params)
|
73
|
+
tags << Tag.new(:link, icon_params)
|
80
74
|
end
|
81
75
|
end
|
82
76
|
end
|
@@ -108,9 +102,8 @@ module MetaTags
|
|
108
102
|
# @param [Array<Tag>] tags a buffer object to store tag in.
|
109
103
|
#
|
110
104
|
def render_refresh(tags)
|
111
|
-
|
112
|
-
|
113
|
-
end
|
105
|
+
refresh = meta_tags.extract(:refresh)
|
106
|
+
tags << Tag.new(:meta, 'http-equiv' => 'refresh', content: refresh.to_s) if refresh.present?
|
114
107
|
end
|
115
108
|
|
116
109
|
# Renders alternate link tags.
|
@@ -118,15 +111,16 @@ module MetaTags
|
|
118
111
|
# @param [Array<Tag>] tags a buffer object to store tag in.
|
119
112
|
#
|
120
113
|
def render_alternate(tags)
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
114
|
+
alternate = meta_tags.extract(:alternate)
|
115
|
+
return unless alternate
|
116
|
+
|
117
|
+
if alternate.kind_of?(Hash)
|
118
|
+
alternate.each do |hreflang, href|
|
119
|
+
tags << Tag.new(:link, rel: 'alternate', href: href, hreflang: hreflang) if href.present?
|
120
|
+
end
|
121
|
+
elsif alternate.kind_of?(Array)
|
122
|
+
alternate.each do |link_params|
|
123
|
+
tags << Tag.new(:link, { rel: 'alternate' }.with_indifferent_access.merge(link_params))
|
130
124
|
end
|
131
125
|
end
|
132
126
|
end
|
@@ -136,14 +130,14 @@ module MetaTags
|
|
136
130
|
# @param [Array<Tag>] tags a buffer object to store tag in.
|
137
131
|
#
|
138
132
|
def render_open_search(tags)
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
133
|
+
open_search = meta_tags.extract(:open_search)
|
134
|
+
return unless open_search
|
135
|
+
|
136
|
+
href = open_search[:href]
|
137
|
+
title = open_search[:title]
|
138
|
+
|
139
|
+
type = "application/opensearchdescription+xml"
|
140
|
+
tags << Tag.new(:link, rel: 'search', type: type, href: href, title: title) if href.present?
|
147
141
|
end
|
148
142
|
|
149
143
|
# Renders links.
|
@@ -165,11 +159,8 @@ module MetaTags
|
|
165
159
|
# @param [Array<Tag>] tags a buffer object to store tag in.
|
166
160
|
#
|
167
161
|
def render_hashes(tags, options = {})
|
168
|
-
meta_tags.meta_tags.each do |property
|
169
|
-
|
170
|
-
process_hash(tags, property, data, options)
|
171
|
-
meta_tags.extract(property)
|
172
|
-
end
|
162
|
+
meta_tags.meta_tags.keys.each do |property|
|
163
|
+
render_hash(tags, property, options)
|
173
164
|
end
|
174
165
|
end
|
175
166
|
|
@@ -179,10 +170,10 @@ module MetaTags
|
|
179
170
|
#
|
180
171
|
def render_hash(tags, key, options = {})
|
181
172
|
data = meta_tags.meta_tags[key]
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
173
|
+
return unless data.kind_of?(Hash)
|
174
|
+
|
175
|
+
process_hash(tags, key, data, options)
|
176
|
+
meta_tags.extract(key)
|
186
177
|
end
|
187
178
|
|
188
179
|
# Renders custom meta tags.
|
@@ -192,7 +183,7 @@ module MetaTags
|
|
192
183
|
def render_custom(tags)
|
193
184
|
meta_tags.meta_tags.each do |name, data|
|
194
185
|
Array(data).each do |val|
|
195
|
-
tags << Tag.new(:meta, name
|
186
|
+
tags << Tag.new(:meta, configured_name_key(name) => name, content: val)
|
196
187
|
end
|
197
188
|
meta_tags.extract(name)
|
198
189
|
end
|
@@ -226,7 +217,7 @@ module MetaTags
|
|
226
217
|
def process_hash(tags, property, content, options = {})
|
227
218
|
content.each do |key, value|
|
228
219
|
key = key.to_s == '_' ? property : "#{property}:#{key}"
|
229
|
-
value = normalized_meta_tags[value] if value.
|
220
|
+
value = normalized_meta_tags[value] if value.kind_of?(Symbol)
|
230
221
|
process_tree(tags, key, value, options)
|
231
222
|
end
|
232
223
|
end
|
@@ -249,9 +240,22 @@ module MetaTags
|
|
249
240
|
# top-level meta tag.
|
250
241
|
#
|
251
242
|
def render_tag(tags, name, value, options = {})
|
252
|
-
name_key = options.fetch(:name_key,
|
243
|
+
name_key = options.fetch(:name_key, configured_name_key(name))
|
253
244
|
value_key = options.fetch(:value_key, :content)
|
254
245
|
tags << Tag.new(:meta, name_key => name.to_s, value_key => value) unless value.blank?
|
255
246
|
end
|
247
|
+
|
248
|
+
# Returns meta tag property name for a give meta tag based on the
|
249
|
+
# configured list of property tags in MetaTags::Configuration#property_tags.
|
250
|
+
#
|
251
|
+
# @param [String, Symbol] meta tag key.
|
252
|
+
# @return [String] meta tag attribute name ("property" or "name").
|
253
|
+
#
|
254
|
+
def configured_name_key(name)
|
255
|
+
is_property_tag = MetaTags.config.property_tags.any? do |tag_name|
|
256
|
+
name.to_s.match(/^#{Regexp.escape(tag_name.to_s)}\b/)
|
257
|
+
end
|
258
|
+
is_property_tag ? :property : :name
|
259
|
+
end
|
256
260
|
end
|
257
261
|
end
|
@@ -10,18 +10,12 @@ module MetaTags
|
|
10
10
|
# @return [Array<String>] array of title parts with tags removed.
|
11
11
|
#
|
12
12
|
def self.normalize_title(site_title, title, separator, reverse = false)
|
13
|
-
title = Array(title).flatten.map(&method(:strip_tags))
|
14
|
-
title.reject!(&:blank?)
|
13
|
+
title = Array(title).flatten.map(&method(:strip_tags)).reject(&:blank?)
|
15
14
|
site_title = strip_tags(site_title)
|
16
15
|
separator = strip_tags(separator)
|
17
16
|
|
18
17
|
if MetaTags.config.title_limit
|
19
|
-
limit =
|
20
|
-
MetaTags.config.title_limit - separator.length
|
21
|
-
else
|
22
|
-
# separtor won't be used: ignore its length
|
23
|
-
MetaTags.config.title_limit
|
24
|
-
end
|
18
|
+
limit = calculate_limit(site_title, separator)
|
25
19
|
|
26
20
|
if limit > site_title.length
|
27
21
|
title = truncate_array(title, limit - site_title.length, separator)
|
@@ -95,7 +89,7 @@ module MetaTags
|
|
95
89
|
# @param [String] sep separator to join strings with.
|
96
90
|
# @return [String] input strings joined together using a given separator.
|
97
91
|
#
|
98
|
-
def self.safe_join(array, sep =
|
92
|
+
def self.safe_join(array, sep = $OFS)
|
99
93
|
helpers.safe_join(array, sep)
|
100
94
|
end
|
101
95
|
|
@@ -140,21 +134,37 @@ module MetaTags
|
|
140
134
|
# @return [String] truncated string.
|
141
135
|
#
|
142
136
|
def self.truncate_array(string_array, limit = nil, separator = '', natural_separator = ' ')
|
143
|
-
return string_array if limit.nil? || limit
|
137
|
+
return string_array if limit.nil? || limit.zero?
|
138
|
+
|
144
139
|
length = 0
|
145
140
|
result = []
|
141
|
+
|
146
142
|
string_array.each do |string|
|
147
|
-
limit_left = limit
|
143
|
+
limit_left = calculate_limit_left(limit, length, result, separator)
|
144
|
+
|
148
145
|
if string.length > limit_left
|
149
146
|
result << truncate(string, limit_left, natural_separator)
|
150
147
|
break
|
151
148
|
end
|
149
|
+
|
152
150
|
length += (result.any? ? separator.length : 0) + string.length
|
153
151
|
result << string
|
152
|
+
|
154
153
|
# No more strings will fit
|
155
154
|
break if length + separator.length >= limit
|
156
155
|
end
|
156
|
+
|
157
157
|
result
|
158
158
|
end
|
159
|
+
|
160
|
+
def self.calculate_limit_left(limit, length, result, separator)
|
161
|
+
limit - length - (result.any? ? separator.length : 0)
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.calculate_limit(site_title, separator)
|
165
|
+
return MetaTags.config.title_limit unless site_title.present?
|
166
|
+
|
167
|
+
MetaTags.config.title_limit - separator.length
|
168
|
+
end
|
159
169
|
end
|
160
170
|
end
|
data/lib/meta_tags/version.rb
CHANGED
data/meta-tags.gemspec
CHANGED
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency "rspec-html-matchers", "~> 0.8.0"
|
28
28
|
|
29
29
|
spec.cert_chain = ["certs/kpumuk.pem"]
|
30
|
-
spec.signing_key = File.expand_path("~/.ssh/gem-kpumuk.pem") if $
|
30
|
+
spec.signing_key = File.expand_path("~/.ssh/gem-kpumuk.pem") if $PROGRAM_NAME =~ /gem\z/
|
31
31
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meta-tags
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmytro Shteflyuk
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
He5T3dBG5WWdIclQcE+JgohBpQ78TcVs1pFNjFmW9pC/P7Rm2GlYqOPHBQG1/Qx9
|
31
31
|
ySbbrGHRLVz8DCxQbhKw+mdT5bg=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2017-
|
33
|
+
date: 2017-08-23 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: actionpack
|
metadata.gz.sig
CHANGED
Binary file
|