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.
@@ -1,3 +1,4 @@
1
+ require 'English'
1
2
  require 'action_controller'
2
3
  require 'action_view'
3
4
 
@@ -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) === true
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) === true
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] === false
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.is_a?(HashWithIndifferentAccess) ? meta_tags.dup : meta_tags.with_indifferent_access
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] === false ? '' : (meta_tags[name] || default)
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 === noindex ? noindex : 'robots'
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 ]
@@ -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
- if charset = meta_tags.extract(:charset)
52
- tags << Tag.new(:meta, charset: charset) if charset.present?
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
- if icon = meta_tags.extract(:icon)
72
- if String === icon
73
- tags << Tag.new(:link, rel: 'icon', href: icon, type: 'image/x-icon')
74
- else
75
- icon = [icon] if Hash === icon
76
- icon.each do |icon_params|
77
- icon_params = { rel: 'icon', type: 'image/x-icon' }.with_indifferent_access.merge(icon_params)
78
- tags << Tag.new(:link, icon_params)
79
- end
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
- if refresh = meta_tags.extract(:refresh)
112
- tags << Tag.new(:meta, 'http-equiv' => 'refresh', content: refresh.to_s) if refresh.present?
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
- if alternate = meta_tags.extract(:alternate)
122
- if Hash === alternate
123
- alternate.each do |hreflang, href|
124
- tags << Tag.new(:link, rel: 'alternate', href: href, hreflang: hreflang) if href.present?
125
- end
126
- elsif Array === alternate
127
- alternate.each do |link_params|
128
- tags << Tag.new(:link, { rel: 'alternate' }.with_indifferent_access.merge(link_params))
129
- end
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
- if open_search = meta_tags.extract(:open_search)
140
- href = open_search[:href]
141
- title = open_search[:title]
142
- if href.present?
143
- type = "application/opensearchdescription+xml"
144
- tags << Tag.new(:link, rel: 'search', type: type, href: href, title: title)
145
- end
146
- end
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, data|
169
- if data.is_a?(Hash)
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
- if data.is_a?(Hash)
183
- process_hash(tags, key, data, options)
184
- meta_tags.extract(key)
185
- end
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: name, content: val)
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.is_a?(Symbol)
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, :name)
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 = if site_title.present?
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 == 0
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 - length - (result.any? ? separator.length : 0)
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
@@ -1,4 +1,4 @@
1
1
  module MetaTags
2
2
  # Gem version.
3
- VERSION = '2.4.1'
3
+ VERSION = '2.5.0'
4
4
  end
@@ -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 $0 =~ /gem\z/
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.1
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-05-15 00:00:00.000000000 Z
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