meta-tags 2.13.0 → 2.19.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Appraisals +25 -0
  4. data/CHANGELOG.md +158 -78
  5. data/CONTRIBUTING.md +6 -6
  6. data/Gemfile +5 -19
  7. data/README.md +174 -137
  8. data/Rakefile +44 -6
  9. data/Steepfile +13 -0
  10. data/certs/kpumuk.pem +19 -18
  11. data/gemfiles/rails_5.1.gemfile +8 -0
  12. data/gemfiles/rails_5.1.gemfile.lock +200 -0
  13. data/gemfiles/rails_5.2.gemfile +8 -0
  14. data/gemfiles/rails_5.2.gemfile.lock +200 -0
  15. data/gemfiles/rails_6.0.gemfile +8 -0
  16. data/gemfiles/rails_6.0.gemfile.lock +202 -0
  17. data/gemfiles/rails_6.1.gemfile +8 -0
  18. data/gemfiles/rails_6.1.gemfile.lock +201 -0
  19. data/gemfiles/rails_7.0.gemfile +8 -0
  20. data/gemfiles/rails_7.0.gemfile.lock +201 -0
  21. data/gemfiles/rails_7.1.gemfile +8 -0
  22. data/gemfiles/rails_7.1.gemfile.lock +231 -0
  23. data/lib/generators/meta_tags/install_generator.rb +1 -1
  24. data/lib/meta-tags.rb +1 -1
  25. data/lib/meta_tags/configuration.rb +23 -16
  26. data/lib/meta_tags/controller_helper.rb +4 -4
  27. data/lib/meta_tags/meta_tags_collection.rb +31 -22
  28. data/lib/meta_tags/railtie.rb +4 -4
  29. data/lib/meta_tags/renderer.rb +55 -28
  30. data/lib/meta_tags/tag.rb +1 -1
  31. data/lib/meta_tags/text_normalizer.rb +44 -39
  32. data/lib/meta_tags/version.rb +1 -1
  33. data/lib/meta_tags/view_helper.rb +7 -7
  34. data/lib/meta_tags.rb +13 -10
  35. data/meta-tags.gemspec +41 -22
  36. data/sig/lib/_internal/rails.rbs +58 -0
  37. data/sig/lib/meta_tags/configuration.rbs +19 -0
  38. data/sig/lib/meta_tags/content_tag.rbs +5 -0
  39. data/sig/lib/meta_tags/controller_helper.rbs +14 -0
  40. data/sig/lib/meta_tags/meta_tags_collection.rbs +41 -0
  41. data/sig/lib/meta_tags/renderer.rbs +50 -0
  42. data/sig/lib/meta_tags/tag.rbs +12 -0
  43. data/sig/lib/meta_tags/text_normalizer.rbs +36 -0
  44. data/sig/lib/meta_tags/version.rbs +4 -0
  45. data/sig/lib/meta_tags/view_helper.rbs +57 -0
  46. data/sig/lib/meta_tags.rbs +18 -0
  47. data.tar.gz.sig +0 -0
  48. metadata +165 -35
  49. metadata.gz.sig +0 -0
@@ -0,0 +1,231 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ meta-tags (2.19.0)
5
+ actionpack (>= 3.2.0, < 7.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (7.1.0)
11
+ actionview (= 7.1.0)
12
+ activesupport (= 7.1.0)
13
+ nokogiri (>= 1.8.5)
14
+ rack (>= 2.2.4)
15
+ rack-session (>= 1.0.1)
16
+ rack-test (>= 0.6.3)
17
+ rails-dom-testing (~> 2.2)
18
+ rails-html-sanitizer (~> 1.6)
19
+ actionview (7.1.0)
20
+ activesupport (= 7.1.0)
21
+ builder (~> 3.1)
22
+ erubi (~> 1.11)
23
+ rails-dom-testing (~> 2.2)
24
+ rails-html-sanitizer (~> 1.6)
25
+ activesupport (7.1.0)
26
+ base64
27
+ bigdecimal
28
+ concurrent-ruby (~> 1.0, >= 1.0.2)
29
+ connection_pool (>= 2.2.5)
30
+ drb
31
+ i18n (>= 1.6, < 2)
32
+ minitest (>= 5.1)
33
+ mutex_m
34
+ tzinfo (~> 2.0)
35
+ appraisal (2.5.0)
36
+ bundler
37
+ rake
38
+ thor (>= 0.14.0)
39
+ ast (2.4.2)
40
+ base64 (0.1.1)
41
+ bigdecimal (3.1.4)
42
+ builder (3.2.4)
43
+ concurrent-ruby (1.2.2)
44
+ connection_pool (2.4.1)
45
+ crass (1.0.6)
46
+ csv (3.2.7)
47
+ diff-lcs (1.5.0)
48
+ docile (1.4.0)
49
+ drb (2.1.1)
50
+ ruby2_keywords
51
+ erubi (1.12.0)
52
+ ffi (1.16.3)
53
+ fileutils (1.7.1)
54
+ i18n (1.14.1)
55
+ concurrent-ruby (~> 1.0)
56
+ io-console (0.6.0)
57
+ irb (1.8.1)
58
+ rdoc
59
+ reline (>= 0.3.8)
60
+ json (2.6.3)
61
+ language_server-protocol (3.17.0.3)
62
+ lint_roller (1.1.0)
63
+ listen (3.8.0)
64
+ rb-fsevent (~> 0.10, >= 0.10.3)
65
+ rb-inotify (~> 0.9, >= 0.9.10)
66
+ logger (1.5.3)
67
+ loofah (2.21.3)
68
+ crass (~> 1.0.2)
69
+ nokogiri (>= 1.12.0)
70
+ minitest (5.20.0)
71
+ mutex_m (0.1.2)
72
+ nokogiri (1.15.4-arm64-darwin)
73
+ racc (~> 1.4)
74
+ parallel (1.23.0)
75
+ parser (3.2.2.4)
76
+ ast (~> 2.4.1)
77
+ racc
78
+ psych (5.1.0)
79
+ stringio
80
+ racc (1.7.1)
81
+ rack (3.0.8)
82
+ rack-session (2.0.0)
83
+ rack (>= 3.0.0)
84
+ rack-test (2.1.0)
85
+ rack (>= 1.3)
86
+ rackup (2.1.0)
87
+ rack (>= 3)
88
+ webrick (~> 1.8)
89
+ rails-dom-testing (2.2.0)
90
+ activesupport (>= 5.0.0)
91
+ minitest
92
+ nokogiri (>= 1.6)
93
+ rails-html-sanitizer (1.6.0)
94
+ loofah (~> 2.21)
95
+ nokogiri (~> 1.14)
96
+ railties (7.1.0)
97
+ actionpack (= 7.1.0)
98
+ activesupport (= 7.1.0)
99
+ irb
100
+ rackup (>= 1.0.0)
101
+ rake (>= 12.2)
102
+ thor (~> 1.0, >= 1.2.2)
103
+ zeitwerk (~> 2.6)
104
+ rainbow (3.1.1)
105
+ rake (13.0.6)
106
+ rb-fsevent (0.11.2)
107
+ rb-inotify (0.10.1)
108
+ ffi (~> 1.0)
109
+ rbs (3.2.2)
110
+ rdoc (6.5.0)
111
+ psych (>= 4.0.0)
112
+ regexp_parser (2.8.1)
113
+ reline (0.3.9)
114
+ io-console (~> 0.5)
115
+ rexml (3.2.6)
116
+ rspec (3.12.0)
117
+ rspec-core (~> 3.12.0)
118
+ rspec-expectations (~> 3.12.0)
119
+ rspec-mocks (~> 3.12.0)
120
+ rspec-core (3.12.2)
121
+ rspec-support (~> 3.12.0)
122
+ rspec-expectations (3.12.3)
123
+ diff-lcs (>= 1.2.0, < 2.0)
124
+ rspec-support (~> 3.12.0)
125
+ rspec-html-matchers (0.10.0)
126
+ nokogiri (~> 1)
127
+ rspec (>= 3.0.0.a)
128
+ rspec-mocks (3.12.6)
129
+ diff-lcs (>= 1.2.0, < 2.0)
130
+ rspec-support (~> 3.12.0)
131
+ rspec-support (3.12.1)
132
+ rspec_junit_formatter (0.6.0)
133
+ rspec-core (>= 2, < 4, != 2.12.0)
134
+ rubocop (1.56.4)
135
+ base64 (~> 0.1.1)
136
+ json (~> 2.3)
137
+ language_server-protocol (>= 3.17.0)
138
+ parallel (~> 1.10)
139
+ parser (>= 3.2.2.3)
140
+ rainbow (>= 2.2.2, < 4.0)
141
+ regexp_parser (>= 1.8, < 3.0)
142
+ rexml (>= 3.2.5, < 4.0)
143
+ rubocop-ast (>= 1.28.1, < 2.0)
144
+ ruby-progressbar (~> 1.7)
145
+ unicode-display_width (>= 2.4.0, < 3.0)
146
+ rubocop-ast (1.29.0)
147
+ parser (>= 3.2.1.0)
148
+ rubocop-capybara (2.19.0)
149
+ rubocop (~> 1.41)
150
+ rubocop-factory_bot (2.24.0)
151
+ rubocop (~> 1.33)
152
+ rubocop-performance (1.19.1)
153
+ rubocop (>= 1.7.0, < 2.0)
154
+ rubocop-ast (>= 0.4.0)
155
+ rubocop-rails (2.20.2)
156
+ activesupport (>= 4.2.0)
157
+ rack (>= 1.1)
158
+ rubocop (>= 1.33.0, < 2.0)
159
+ rubocop-rake (0.6.0)
160
+ rubocop (~> 1.0)
161
+ rubocop-rspec (2.23.2)
162
+ rubocop (~> 1.33)
163
+ rubocop-capybara (~> 2.17)
164
+ rubocop-factory_bot (~> 2.22)
165
+ ruby-progressbar (1.13.0)
166
+ ruby2_keywords (0.0.5)
167
+ securerandom (0.2.2)
168
+ simplecov (0.22.0)
169
+ docile (~> 1.1)
170
+ simplecov-html (~> 0.11)
171
+ simplecov_json_formatter (~> 0.1)
172
+ simplecov-html (0.12.3)
173
+ simplecov_json_formatter (0.1.4)
174
+ standard (1.31.1)
175
+ language_server-protocol (~> 3.17.0.2)
176
+ lint_roller (~> 1.0)
177
+ rubocop (~> 1.56.2)
178
+ standard-custom (~> 1.0.0)
179
+ standard-performance (~> 1.2)
180
+ standard-custom (1.0.2)
181
+ lint_roller (~> 1.0)
182
+ rubocop (~> 1.50)
183
+ standard-performance (1.2.0)
184
+ lint_roller (~> 1.1)
185
+ rubocop-performance (~> 1.19.0)
186
+ steep (1.5.3)
187
+ activesupport (>= 5.1)
188
+ concurrent-ruby (>= 1.1.10)
189
+ csv (>= 3.0.9)
190
+ fileutils (>= 1.1.0)
191
+ json (>= 2.1.0)
192
+ language_server-protocol (>= 3.15, < 4.0)
193
+ listen (~> 3.0)
194
+ logger (>= 1.3.0)
195
+ parser (>= 3.1)
196
+ rainbow (>= 2.2.2, < 4.0)
197
+ rbs (>= 3.1.0)
198
+ securerandom (>= 0.1)
199
+ strscan (>= 1.0.0)
200
+ terminal-table (>= 2, < 4)
201
+ stringio (3.0.8)
202
+ strscan (3.0.6)
203
+ terminal-table (3.0.2)
204
+ unicode-display_width (>= 1.1.1, < 3)
205
+ thor (1.2.2)
206
+ tzinfo (2.0.6)
207
+ concurrent-ruby (~> 1.0)
208
+ unicode-display_width (2.5.0)
209
+ webrick (1.8.1)
210
+ zeitwerk (2.6.12)
211
+
212
+ PLATFORMS
213
+ arm64-darwin
214
+
215
+ DEPENDENCIES
216
+ appraisal (~> 2.5.0)
217
+ meta-tags!
218
+ railties (= 7.1.0)
219
+ rake (~> 13.0)
220
+ rspec (~> 3.12.0)
221
+ rspec-html-matchers (~> 0.10.0)
222
+ rspec_junit_formatter (~> 0.6.0)
223
+ rubocop-rails (~> 2.20.2)
224
+ rubocop-rake (~> 0.6.0)
225
+ rubocop-rspec (~> 2.23.0)
226
+ simplecov (~> 0.22.0)
227
+ standard (~> 1.29)
228
+ steep (~> 1.5.2)
229
+
230
+ BUNDLED WITH
231
+ 2.4.10
@@ -4,7 +4,7 @@ module MetaTags
4
4
  module Generators
5
5
  class InstallGenerator < Rails::Generators::Base
6
6
  desc "Copy MetaTags default files"
7
- source_root File.expand_path('templates', __dir__)
7
+ source_root File.expand_path("templates", __dir__)
8
8
 
9
9
  def copy_config
10
10
  template "config/initializers/meta_tags.rb"
data/lib/meta-tags.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'meta_tags'
3
+ require "meta_tags"
@@ -33,6 +33,12 @@ module MetaTags
33
33
  # - an array of strings or symbols representing their names or name-prefixes.
34
34
  attr_reader :property_tags
35
35
 
36
+ # Configure whenever Meta-Tags should skip canonicals on pages with noindex: true
37
+ # "shouldn't mix noindex & rel=canonical comes from: they're very contradictory pieces of information for us."
38
+ # - John Mueller (Webmaster Trends Analyst at Google)
39
+ # https://www.reddit.com/r/TechSEO/comments/8yahdr/2_questions_about_the_canonical_tag/e2dey9i/
40
+ attr_accessor :skip_canonical_links_on_noindex
41
+
36
42
  # Initializes a new instance of Configuration class.
37
43
  def initialize
38
44
  reset_defaults!
@@ -41,25 +47,25 @@ module MetaTags
41
47
  def default_property_tags
42
48
  [
43
49
  # App Link metadata https://developers.facebook.com/docs/applinks/metadata-reference
44
- 'al',
50
+ "al",
45
51
  # Open Graph Markup https://developers.facebook.com/docs/sharing/webmasters#markup
46
- 'fb',
47
- 'og',
52
+ "fb",
53
+ "og",
48
54
  # Facebook OpenGraph Object Types https://developers.facebook.com/docs/reference/opengraph
49
55
  # Note that these tags are used in a regex, so including e.g. 'restaurant' will affect
50
56
  # 'restaurant:category', 'restaurant:price_rating', and anything else under that namespace.
51
- 'article',
52
- 'book',
53
- 'books',
54
- 'business',
55
- 'fitness',
56
- 'game',
57
- 'music',
58
- 'place',
59
- 'product',
60
- 'profile',
61
- 'restaurant',
62
- 'video',
57
+ "article",
58
+ "book",
59
+ "books",
60
+ "business",
61
+ "fitness",
62
+ "game",
63
+ "music",
64
+ "place",
65
+ "product",
66
+ "profile",
67
+ "restaurant",
68
+ "video"
63
69
  ].freeze
64
70
  end
65
71
 
@@ -72,11 +78,12 @@ module MetaTags
72
78
  @truncate_site_title_first = false
73
79
  @description_limit = 300
74
80
  @keywords_limit = 255
75
- @keywords_separator = ', '
81
+ @keywords_separator = ", "
76
82
  @keywords_lowercase = true
77
83
  @property_tags = default_property_tags.dup
78
84
  @open_meta_tags = true
79
85
  @minify_output = false
86
+ @skip_canonical_links_on_noindex = false
80
87
  end
81
88
  end
82
89
  end
@@ -15,9 +15,9 @@ module MetaTags
15
15
  # Processes the <tt>@page_title</tt>, <tt>@page_keywords</tt>, and
16
16
  # <tt>@page_description</tt> instance variables and calls +render+.
17
17
  def render(*args, &block)
18
- meta_tags[:title] = @page_title if @page_title
19
- meta_tags[:keywords] = @page_keywords if @page_keywords
20
- meta_tags[:description] = @page_description if @page_description
18
+ meta_tags[:title] = @page_title if defined?(@page_title) && @page_title
19
+ meta_tags[:keywords] = @page_keywords if defined?(@page_keywords) && @page_keywords
20
+ meta_tags[:description] = @page_description if defined?(@page_description) && @page_description
21
21
 
22
22
  super
23
23
  end
@@ -25,7 +25,7 @@ module MetaTags
25
25
  # Set meta tags for the page.
26
26
  #
27
27
  # See <tt>MetaTags::ViewHelper#set_meta_tags</tt> for details.
28
- def set_meta_tags(meta_tags) # rubocop:disable Naming/AccessorMethodName
28
+ def set_meta_tags(meta_tags)
29
29
  self.meta_tags.update(meta_tags)
30
30
  end
31
31
  protected :set_meta_tags
@@ -9,7 +9,7 @@ module MetaTags
9
9
  # Initializes a new instance of MetaTagsCollection.
10
10
  #
11
11
  def initialize
12
- @meta_tags = HashWithIndifferentAccess.new
12
+ @meta_tags = ActiveSupport::HashWithIndifferentAccess.new
13
13
  end
14
14
 
15
15
  # Returns meta tag value by name.
@@ -38,7 +38,13 @@ module MetaTags
38
38
  # @return [Hash] result of the merge.
39
39
  #
40
40
  def update(object = {})
41
- meta_tags = object.respond_to?(:to_meta_tags) ? object.to_meta_tags : object
41
+ meta_tags = if object.respond_to?(:to_meta_tags)
42
+ # @type var object: _MetaTagish & Object
43
+ object.to_meta_tags
44
+ else
45
+ # @type var object: Hash[String | Symbol, untyped]
46
+ object
47
+ end
42
48
  @meta_tags.deep_merge! normalize_open_graph(meta_tags)
43
49
  end
44
50
 
@@ -64,14 +70,16 @@ module MetaTags
64
70
  with_defaults(defaults) { extract_full_title }
65
71
  end
66
72
 
67
- # Constructs the title without site title (for normalized parameters).
73
+ # Constructs the title without site title (for normalized parameters). When title is empty,
74
+ # use the site title instead.
68
75
  #
69
76
  # @return [String] page title.
70
77
  #
71
78
  def page_title(defaults = {})
72
79
  old_site = @meta_tags[:site]
73
80
  @meta_tags[:site] = nil
74
- with_defaults(defaults) { extract_full_title }
81
+ full_title = with_defaults(defaults) { extract_full_title }
82
+ full_title.presence || old_site || ""
75
83
  ensure
76
84
  @meta_tags[:site] = old_site
77
85
  end
@@ -98,10 +106,10 @@ module MetaTags
98
106
  # @return [String] page title.
99
107
  #
100
108
  def extract_full_title
101
- site_title = extract(:site) || ''
102
- title = extract_title || []
103
- separator = extract_separator
104
- reverse = extract(:reverse) == true
109
+ site_title = extract(:site) || ""
110
+ title = extract_title
111
+ separator = extract_separator
112
+ reverse = extract(:reverse) == true
105
113
 
106
114
  TextNormalizer.normalize_title(site_title, title, separator, reverse)
107
115
  end
@@ -112,8 +120,9 @@ module MetaTags
112
120
  #
113
121
  def extract_title
114
122
  title = extract(:title).presence
115
- return unless title
123
+ return [] unless title
116
124
 
125
+ # @type var title: Array[String]
117
126
  title = Array(title)
118
127
  return title.map(&:downcase) if extract(:lowercase) == true
119
128
 
@@ -127,15 +136,15 @@ module MetaTags
127
136
  def extract_separator
128
137
  if meta_tags[:separator] == false
129
138
  # Special case: if separator is hidden, do not display suffix/prefix
130
- prefix = separator = suffix = ''
139
+ prefix = separator = suffix = ""
131
140
  else
132
- prefix = extract_separator_section(:prefix, ' ')
133
- separator = extract_separator_section(:separator, '|')
134
- suffix = extract_separator_section(:suffix, ' ')
141
+ prefix = extract_separator_section(:prefix, " ")
142
+ separator = extract_separator_section(:separator, "|")
143
+ suffix = extract_separator_section(:suffix, " ")
135
144
  end
136
145
  delete(:separator, :prefix, :suffix)
137
146
 
138
- TextNormalizer.safe_join([prefix, separator, suffix], '')
147
+ TextNormalizer.safe_join([prefix, separator, suffix], "")
139
148
  end
140
149
 
141
150
  # Extracts noindex settings as a Hash mapping noindex tag name to value.
@@ -150,12 +159,12 @@ module MetaTags
150
159
  [:noindex, :index],
151
160
  # follow has higher priority than nofollow
152
161
  [:follow, :nofollow],
153
- :noarchive,
162
+ :noarchive
154
163
  ].each do |attributes|
155
164
  calculate_robots_attributes(result, attributes)
156
165
  end
157
166
 
158
- result.transform_values { |v| v.join(', ') }
167
+ result.transform_values { |v| v.join(", ") }
159
168
  end
160
169
 
161
170
  protected
@@ -163,10 +172,10 @@ module MetaTags
163
172
  # Converts input hash to HashWithIndifferentAccess and renames :open_graph to :og.
164
173
  #
165
174
  # @param [Hash] meta_tags list of meta tags.
166
- # @return [HashWithIndifferentAccess] normalized meta tags list.
175
+ # @return [ActiveSupport::HashWithIndifferentAccess] normalized meta tags list.
167
176
  #
168
177
  def normalize_open_graph(meta_tags)
169
- meta_tags = meta_tags.kind_of?(HashWithIndifferentAccess) ? meta_tags.dup : meta_tags.with_indifferent_access
178
+ meta_tags = meta_tags.with_indifferent_access
170
179
  meta_tags[:og] = meta_tags.delete(:open_graph) if meta_tags.key?(:open_graph)
171
180
  meta_tags
172
181
  end
@@ -179,7 +188,7 @@ module MetaTags
179
188
  # @return [String] separator segment value.
180
189
  #
181
190
  def extract_separator_section(name, default)
182
- meta_tags[name] == false ? '' : (meta_tags[name] || default)
191
+ (meta_tags[name] == false) ? "" : (meta_tags[name] || default)
183
192
  end
184
193
 
185
194
  # Extracts robots attribute (noindex, nofollow, etc) name and value.
@@ -188,11 +197,11 @@ module MetaTags
188
197
  # @return [Array<String>] pair of noindex attribute name and value.
189
198
  #
190
199
  def extract_robots_attribute(name)
191
- noindex = extract(name)
192
- noindex_name = noindex.kind_of?(String) || noindex.kind_of?(Array) ? noindex : 'robots'
200
+ noindex = extract(name)
201
+ noindex_name = (noindex.is_a?(String) || noindex.is_a?(Array)) ? noindex : "robots"
193
202
  noindex_value = noindex ? name.to_s : nil
194
203
 
195
- [ noindex_name, noindex_value ]
204
+ [noindex_name, noindex_value]
196
205
  end
197
206
 
198
207
  def calculate_robots_attributes(result, attributes)
@@ -2,15 +2,15 @@
2
2
 
3
3
  module MetaTags
4
4
  class Railtie < Rails::Railtie
5
- initializer 'meta_tags.setup_action_controller' do
5
+ initializer "meta_tags.setup_action_controller" do
6
6
  ActiveSupport.on_load :action_controller do
7
- ActionController::Base.include MetaTags::ControllerHelper
7
+ include MetaTags::ControllerHelper
8
8
  end
9
9
  end
10
10
 
11
- initializer 'meta_tags.setup_action_view' do
11
+ initializer "meta_tags.setup_action_view" do
12
12
  ActiveSupport.on_load :action_view do
13
- ActionView::Base.include MetaTags::ViewHelper
13
+ include MetaTags::ViewHelper
14
14
  end
15
15
  end
16
16
  end
@@ -26,6 +26,7 @@ module MetaTags
26
26
  render_with_normalization(tags, :description)
27
27
  render_with_normalization(tags, :keywords)
28
28
  render_refresh(tags)
29
+ render_canonical_link(tags)
29
30
  render_noindex(tags)
30
31
  render_alternate(tags)
31
32
  render_open_search(tags)
@@ -70,12 +71,12 @@ module MetaTags
70
71
  return unless icon
71
72
 
72
73
  # String? Value is an href
73
- icon = [{ href: icon }] if icon.kind_of?(String)
74
+ icon = [{href: icon}] if icon.is_a?(String)
74
75
  # Hash? Single icon instead of a list of icons
75
- icon = [icon] if icon.kind_of?(Hash)
76
+ icon = [icon] if icon.is_a?(Hash)
76
77
 
77
78
  icon.each do |icon_params|
78
- icon_params = { rel: 'icon', type: 'image/x-icon' }.with_indifferent_access.merge(icon_params)
79
+ icon_params = {rel: "icon", type: "image/x-icon"}.with_indifferent_access.merge(icon_params)
79
80
  tags << Tag.new(:link, icon_params)
80
81
  end
81
82
  end
@@ -108,7 +109,7 @@ module MetaTags
108
109
  #
109
110
  def render_refresh(tags)
110
111
  refresh = meta_tags.extract(:refresh)
111
- tags << Tag.new(:meta, 'http-equiv' => 'refresh', content: refresh.to_s) if refresh.present?
112
+ tags << Tag.new(:meta, "http-equiv" => "refresh", :content => refresh.to_s) if refresh.present?
112
113
  end
113
114
 
114
115
  # Renders alternate link tags.
@@ -119,13 +120,13 @@ module MetaTags
119
120
  alternate = meta_tags.extract(:alternate)
120
121
  return unless alternate
121
122
 
122
- if alternate.kind_of?(Hash)
123
+ if alternate.is_a?(Hash)
123
124
  alternate.each do |hreflang, href|
124
- tags << Tag.new(:link, rel: 'alternate', href: href, hreflang: hreflang) if href.present?
125
+ tags << Tag.new(:link, rel: "alternate", href: href, hreflang: hreflang) if href.present?
125
126
  end
126
- elsif alternate.kind_of?(Array)
127
+ elsif alternate.is_a?(Array)
127
128
  alternate.each do |link_params|
128
- tags << Tag.new(:link, { rel: 'alternate' }.with_indifferent_access.merge(link_params))
129
+ tags << Tag.new(:link, {rel: "alternate"}.with_indifferent_access.merge(link_params))
129
130
  end
130
131
  end
131
132
  end
@@ -142,7 +143,7 @@ module MetaTags
142
143
  title = open_search[:title]
143
144
 
144
145
  type = "application/opensearchdescription+xml"
145
- tags << Tag.new(:link, rel: 'search', type: type, href: href, title: title) if href.present?
146
+ tags << Tag.new(:link, rel: "search", type: type, href: href, title: title) if href.present?
146
147
  end
147
148
 
148
149
  # Renders links.
@@ -150,7 +151,7 @@ module MetaTags
150
151
  # @param [Array<Tag>] tags a buffer object to store tag in.
151
152
  #
152
153
  def render_links(tags)
153
- [ :amphtml, :canonical, :prev, :next, :image_src, :manifest ].each do |tag_name|
154
+ [:amphtml, :prev, :next, :image_src, :manifest].each do |tag_name|
154
155
  href = meta_tags.extract(tag_name)
155
156
  if href.present?
156
157
  @normalized_meta_tags[tag_name] = href
@@ -159,6 +160,19 @@ module MetaTags
159
160
  end
160
161
  end
161
162
 
163
+ # Renders canonical link
164
+ #
165
+ # @param [Array<Tag>] tags a buffer object to store tag in.
166
+ #
167
+ def render_canonical_link(tags)
168
+ href = meta_tags.extract(:canonical) # extract, so its not used anywhere else
169
+ return if MetaTags.config.skip_canonical_links_on_noindex && meta_tags[:noindex]
170
+ return if href.blank?
171
+
172
+ @normalized_meta_tags[:canonical] = href
173
+ tags << Tag.new(:link, rel: :canonical, href: href)
174
+ end
175
+
162
176
  # Renders complex hash objects.
163
177
  #
164
178
  # @param [Array<Tag>] tags a buffer object to store tag in.
@@ -175,7 +189,7 @@ module MetaTags
175
189
  #
176
190
  def render_hash(tags, key, **opts)
177
191
  data = meta_tags.meta_tags[key]
178
- return unless data.kind_of?(Hash)
192
+ return unless data.is_a?(Hash)
179
193
 
180
194
  process_hash(tags, key, data, **opts)
181
195
  meta_tags.extract(key)
@@ -188,7 +202,7 @@ module MetaTags
188
202
  def render_custom(tags)
189
203
  meta_tags.meta_tags.each do |name, data|
190
204
  Array(data).each do |val|
191
- tags << Tag.new(:meta, configured_name_key(name) => name, content: val)
205
+ tags << Tag.new(:meta, configured_name_key(name) => name, :content => val)
192
206
  end
193
207
  meta_tags.extract(name)
194
208
  end
@@ -201,16 +215,17 @@ module MetaTags
201
215
  # @param [Hash, Array, String, Symbol] content text content or a symbol reference to
202
216
  # top-level meta tag.
203
217
  #
204
- def process_tree(tags, property, content, **opts)
218
+ def process_tree(tags, property, content, itemprop: nil, **opts)
205
219
  method = case content
206
- when Hash
207
- :process_hash
208
- when Array
209
- :process_array
210
- else
211
- :render_tag
212
- end
213
- __send__(method, tags, property, content, **opts)
220
+ when Hash
221
+ :process_hash
222
+ when Array
223
+ :process_array
224
+ else
225
+ iprop = itemprop
226
+ :render_tag
227
+ end
228
+ __send__(method, tags, property, content, itemprop: iprop, **opts)
214
229
  end
215
230
 
216
231
  # Recursive method to process a hash with meta tags
@@ -220,10 +235,21 @@ module MetaTags
220
235
  # @param [Hash] content nested meta tag attributes.
221
236
  #
222
237
  def process_hash(tags, property, content, **opts)
238
+ itemprop = content.delete(:itemprop)
223
239
  content.each do |key, value|
224
- key = key.to_s == '_' ? property : "#{property}:#{key}"
225
- value = normalized_meta_tags[value] if value.kind_of?(Symbol)
226
- process_tree(tags, key, value, **opts)
240
+ if key.to_s == "_"
241
+ iprop = itemprop
242
+ key = property
243
+ else
244
+ key = "#{property}:#{key}"
245
+ end
246
+
247
+ normalized_value = if value.is_a?(Symbol)
248
+ normalized_meta_tags[value]
249
+ else
250
+ value
251
+ end
252
+ process_tree(tags, key, normalized_value, **opts.merge(itemprop: iprop))
227
253
  end
228
254
  end
229
255
 
@@ -243,17 +269,18 @@ module MetaTags
243
269
  # @param [String, Symbol] name a Hash or a String to render as meta tag.
244
270
  # @param [String, Symbol] value text content or a symbol reference to
245
271
  # top-level meta tag.
272
+ # @param [String, Symbol] itemprop value of the itemprop attribute.
246
273
  #
247
- def render_tag(tags, name, value, name_key: nil, value_key: :content)
274
+ def render_tag(tags, name, value, itemprop: nil)
248
275
  name_key ||= configured_name_key(name)
249
- tags << Tag.new(:meta, name_key => name.to_s, value_key => value) if value.present?
276
+ tags << Tag.new(:meta, name_key => name.to_s, :content => value, :itemprop => itemprop) if value.present?
250
277
  end
251
278
 
252
279
  # Returns meta tag property name for a give meta tag based on the
253
280
  # configured list of property tags in MetaTags::Configuration#property_tags.
254
281
  #
255
- # @param [String, Symbol] meta tag key.
256
- # @return [String] meta tag attribute name ("property" or "name").
282
+ # @param [String, Symbol] name tag key.
283
+ # @return [Symbol] meta tag attribute name (:property or :name).
257
284
  #
258
285
  def configured_name_key(name)
259
286
  is_property_tag = MetaTags.config.property_tags.any? do |tag_name|
data/lib/meta_tags/tag.rb CHANGED
@@ -11,7 +11,7 @@ module MetaTags
11
11
  # @param [Hash] attributes list of HTML tag attributes
12
12
  #
13
13
  def initialize(name, attributes = {})
14
- @name = name
14
+ @name = name.to_s
15
15
  @attributes = attributes
16
16
  end
17
17