meta-tags 2.12.0 → 2.16.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.
data/README.md CHANGED
@@ -5,19 +5,19 @@
5
5
  [![Code Climate](https://codeclimate.com/github/kpumuk/meta-tags/badges/gpa.svg)](https://codeclimate.com/github/kpumuk/meta-tags)
6
6
  [![Test Coverage](https://codeclimate.com/github/kpumuk/meta-tags/badges/coverage.svg)](https://codeclimate.com/github/kpumuk/meta-tags/coverage)
7
7
  [![Gem Downloads](https://img.shields.io/gem/dt/meta-tags.svg)](https://badge.fury.io/rb/meta-tags)
8
- [![Changelog](https://img.shields.io/badge/Changelog-latest-blue.svg)](https://github.com/kpumuk/meta-tags/blob/master/CHANGELOG.md)
8
+ [![Changelog](https://img.shields.io/badge/Changelog-latest-blue.svg)](https://github.com/kpumuk/meta-tags/blob/main/CHANGELOG.md)
9
9
 
10
10
  Search Engine Optimization (SEO) plugin for Ruby on Rails applications.
11
11
 
12
12
  ## Ruby on Rails
13
13
 
14
- MetaTags master branch fully supports Ruby on Rails 4.2+, and is tested against all
15
- major Rails releases up to 6.0.beta2.
14
+ MetaTags main branch fully supports Ruby on Rails 5.1+, and is tested against all
15
+ major Rails releases up to 6.1.
16
16
 
17
- Ruby versions older than 2.2.0 are no longer officially supported.
17
+ Ruby versions older than 2.5 are no longer officially supported.
18
18
 
19
- _Please note_ that we are no longer support Ruby versions older than 2.2.0 and
20
- Ruby on Rails older than 4.2, because they [reached their End of Life](https://github.com/kpumuk/meta-tags/pull/143).
19
+ _Please note_ that we are no longer support Ruby versions older than 2.4.0 and
20
+ Ruby on Rails older than 5.1, because they [reached their End of Life](https://github.com/kpumuk/meta-tags/pull/143).
21
21
 
22
22
  ## Installation
23
23
 
@@ -152,30 +152,30 @@ If you want to set the title and display another text, use this:
152
152
 
153
153
  Use these options to customize the title format:
154
154
 
155
- | Option | Description |
156
- | -------------- | ----------- |
157
- | `:site` | site title |
158
- | `:title` | page title |
159
- | `:description` | page description |
160
- | `:keywords` | page keywords |
161
- | `:charset` | page character set |
162
- | `:prefix` | text between site name and separator |
163
- | `:separator` | text used to separate website name from page title |
164
- | `:suffix` | text between separator and page title |
165
- | `:lowercase` | when true, the page name will be lowercase |
166
- | `:reverse` | when true, the page and site names will be reversed |
167
- | `:noindex` | add noindex meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
168
- | `:index` | add index meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
169
- | `:nofollow` | add nofollow meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
170
- | `:follow` | add follow meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
155
+ | Option | Description |
156
+ | -------------- | -------------------------------------------------------------------------------------------------------------------- |
157
+ | `:site` | site title |
158
+ | `:title` | page title |
159
+ | `:description` | page description |
160
+ | `:keywords` | page keywords |
161
+ | `:charset` | page character set |
162
+ | `:prefix` | text between site name and separator |
163
+ | `:separator` | text used to separate website name from page title |
164
+ | `:suffix` | text between separator and page title |
165
+ | `:lowercase` | when true, the page name will be lowercase |
166
+ | `:reverse` | when true, the page and site names will be reversed |
167
+ | `:noindex` | add noindex meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
168
+ | `:index` | add index meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
169
+ | `:nofollow` | add nofollow meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
170
+ | `:follow` | add follow meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
171
171
  | `:noarchive` | add noarchive meta tag; when true, 'robots' will be used; accepts a string with a robot name, or an array of strings |
172
- | `:canonical` | add canonical link tag |
173
- | `:prev` | add prev link tag |
174
- | `:next` | add next link tag |
175
- | `:image_src` | add image_src link tag |
176
- | `:og` | add Open Graph tags (Hash) |
177
- | `:twitter` | add Twitter tags (Hash) |
178
- | `:refresh` | refresh interval and optionally url to redirect to |
172
+ | `:canonical` | add canonical link tag |
173
+ | `:prev` | add prev link tag |
174
+ | `:next` | add next link tag |
175
+ | `:image_src` | add image_src link tag |
176
+ | `:og` | add Open Graph tags (Hash) |
177
+ | `:twitter` | add Twitter tags (Hash) |
178
+ | `:refresh` | refresh interval and optionally url to redirect to |
179
179
 
180
180
  And here are a few examples to give you ideas.
181
181
 
@@ -307,7 +307,7 @@ Recommended title tag length: up to <b>70 characters</b>, <b>10 words</b>.
307
307
 
308
308
  Further reading:
309
309
 
310
- * [Title Tag](https://moz.com/learn/seo/title-tag)
310
+ - [Title Tag](https://moz.com/learn/seo/title-tag)
311
311
 
312
312
  ### Description
313
313
 
@@ -325,8 +325,8 @@ Recommended description tag length: up to <b>300 characters</b>.
325
325
 
326
326
  Further reading:
327
327
 
328
- * [Meta Description](https://moz.com/learn/seo/meta-description)
329
- * [How Long Should Your Meta Description Be? (2018 Edition)](https://moz.com/blog/how-long-should-your-meta-description-be-2018)
328
+ - [Meta Description](https://moz.com/learn/seo/meta-description)
329
+ - [How Long Should Your Meta Description Be? (2018 Edition)](https://moz.com/blog/how-long-should-your-meta-description-be-2018)
330
330
 
331
331
  ### Keywords
332
332
 
@@ -360,8 +360,8 @@ This is useful for pages like login, password reset, privacy policy, etc.
360
360
 
361
361
  Further reading:
362
362
 
363
- * [Blocking Google](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=93708)
364
- * [Using meta tags to block access to your site](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=93710)
363
+ - [Blocking Google](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=93708)
364
+ - [Using meta tags to block access to your site](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=93710)
365
365
 
366
366
  ### Index
367
367
 
@@ -388,12 +388,12 @@ set_meta_tags nofollow: 'googlebot'
388
388
 
389
389
  Further reading:
390
390
 
391
- * [About rel="nofollow"](http://www.google.com/support/webmasters/bin/answer.py?answer=96569)
392
- * [Meta tags](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=79812)
391
+ - [About rel="nofollow"](http://www.google.com/support/webmasters/bin/answer.py?answer=96569)
392
+ - [Meta tags](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=79812)
393
393
 
394
394
  ### Follow
395
395
 
396
- Follow will work with Noindex meta tag
396
+ Follow will work with Noindex meta tag
397
397
 
398
398
  ```ruby
399
399
  set_meta_tags noindex: true, follow: true
@@ -409,6 +409,9 @@ Canonical link element tells a search engine what is the canonical or main URL
409
409
  for a content which have multiple URLs. The search engine will always return
410
410
  that URL, and link popularity and authority will be applied to that URL.
411
411
 
412
+ Note: If you like follow a hint of John Mueller that you shouldn't mix canonical with noindex, then you can
413
+ set `MetaTags.config.skip_canonical_links_on_noindex = true` and we'll handle it for you.
414
+
412
415
  ```ruby
413
416
  set_meta_tags canonical: "http://yoursite.com/canonical/url"
414
417
  # <link rel="canonical" href="http://yoursite.com/canonical/url">
@@ -416,8 +419,8 @@ set_meta_tags canonical: "http://yoursite.com/canonical/url"
416
419
 
417
420
  Further reading:
418
421
 
419
- * [About rel="canonical"](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=139394)
420
- * [Canonicalization](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=139066)
422
+ - [About rel="canonical"](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=139394)
423
+ - [Canonicalization](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=139066)
421
424
 
422
425
  ### Icon
423
426
 
@@ -440,9 +443,8 @@ set_meta_tags icon: [
440
443
 
441
444
  Further reading:
442
445
 
443
- * [Favicon](https://www.wikiwand.com/en/Favicon)
444
- * [Touch Icons](https://mathiasbynens.be/notes/touch-icons)
445
-
446
+ - [Favicon](https://www.wikiwand.com/en/Favicon)
447
+ - [Touch Icons](https://mathiasbynens.be/notes/touch-icons)
446
448
 
447
449
  ### Multi-regional and multilingual URLs, RSS and mobile links
448
450
 
@@ -471,9 +473,9 @@ set_meta_tags alternate: [
471
473
 
472
474
  Further reading:
473
475
 
474
- * [Multi-regional and multilingual sites](https://support.google.com/webmasters/answer/182192)
475
- * [About rel="alternate" hreflang="x"](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=189077)
476
- * [Separate URLs](https://developers.google.com/webmasters/mobile-sites/mobile-seo/configurations/separate-urls#annotation-in-the-html)
476
+ - [Multi-regional and multilingual sites](https://support.google.com/webmasters/answer/182192)
477
+ - [About rel="alternate" hreflang="x"](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=189077)
478
+ - [Separate URLs](https://developers.google.com/webmasters/mobile-sites/mobile-seo/configurations/separate-urls#annotation-in-the-html)
477
479
 
478
480
  ### Pagination links
479
481
 
@@ -490,8 +492,8 @@ set_meta_tags next: "http://yoursite.com/url?page=3"
490
492
 
491
493
  Further reading:
492
494
 
493
- * [Pagination](http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1663744)
494
- * [Pagination with rel="next" and rel="prev"](http://googlewebmastercentral.blogspot.ca/2011/09/pagination-with-relnext-and-relprev.html)
495
+ - [Pagination](http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1663744)
496
+ - [Pagination with rel="next" and rel="prev"](http://googlewebmastercentral.blogspot.ca/2011/09/pagination-with-relnext-and-relprev.html)
495
497
 
496
498
  ### image_src links
497
499
 
@@ -518,8 +520,17 @@ set_meta_tags amphtml: url_for(format: :amp, only_path: false)
518
520
 
519
521
  To link back to normal version, use `canonical`.
520
522
 
521
- * [What Is AMP?](https://www.ampproject.org/learn/about-amp/)
522
- * [Make Your Page Discoverable](https://www.ampproject.org/docs/guides/discovery)
523
+ - [What Is AMP?](https://www.ampproject.org/learn/about-amp/)
524
+ - [Make Your Page Discoverable](https://www.ampproject.org/docs/guides/discovery)
525
+
526
+ ### Manifest links
527
+
528
+ ```ruby
529
+ set_meta_tags manifest: 'manifest.json'
530
+ # <link rel="manifest" href="manifest.json">
531
+ ```
532
+
533
+ - [What is manifest?](https://developer.mozilla.org/en-US/docs/Web/Manifest)
523
534
 
524
535
  ### Refresh interval and redirect URL
525
536
 
@@ -539,9 +550,8 @@ set_meta_tags refresh: '5;url=http://example.com'
539
550
 
540
551
  Further reading:
541
552
 
542
- * [Meta refresh](http://en.wikipedia.org/wiki/Meta_refresh)
543
- * [What is the Meta Refresh Tag](http://webdesign.about.com/od/metataglibraries/a/aa080300a.htm)
544
-
553
+ - [Meta refresh](http://en.wikipedia.org/wiki/Meta_refresh)
554
+ - [What is the Meta Refresh Tag](http://webdesign.about.com/od/metataglibraries/a/aa080300a.htm)
545
555
 
546
556
  ### Open Search
547
557
 
@@ -557,8 +567,8 @@ set_meta_tags open_search: {
557
567
 
558
568
  Further reading:
559
569
 
560
- * [OpenSearch specs](http://www.opensearch.org/Specifications/OpenSearch/1.1)
561
- * [OpenSearch wiki](http://en.wikipedia.org/wiki/OpenSearch)
570
+ - [OpenSearch specs](http://www.opensearch.org/Specifications/OpenSearch/1.1)
571
+ - [OpenSearch wiki](http://en.wikipedia.org/wiki/OpenSearch)
562
572
 
563
573
  ### Hashes
564
574
 
@@ -660,8 +670,8 @@ set_meta_tags article: {
660
670
 
661
671
  Further reading:
662
672
 
663
- * [Open Graph protocol](http://developers.facebook.com/docs/opengraph/)
664
- * [Must-Have Social Meta Tags for Twitter, Google+, Facebook and More](https://moz.com/blog/meta-data-templates-123)
673
+ - [Open Graph protocol](http://developers.facebook.com/docs/opengraph/)
674
+ - [Must-Have Social Meta Tags for Twitter, Google+, Facebook and More](https://moz.com/blog/meta-data-templates-123)
665
675
 
666
676
  ### Twitter Cards
667
677
 
@@ -696,9 +706,27 @@ set_meta_tags twitter: {
696
706
  # <meta name="twitter:image:height" content="100">
697
707
  ```
698
708
 
709
+ Special parameter `itemprop` can be used on a "anonymous" tag "\_" to generate "itemprop" HTML attribute:
710
+
711
+ ```ruby
712
+ set_meta_tags twitter: {
713
+ card: "photo",
714
+ image: {
715
+ _: "http://example.com/1.png",
716
+ width: 100,
717
+ height: 100,
718
+ itemprop: "image",
719
+ }
720
+ }
721
+ # <meta name="twitter:card" content="photo">
722
+ # <meta name="twitter:image" content="http://example.com/1.png" itemprop="image">
723
+ # <meta name="twitter:image:width" content="100">
724
+ # <meta name="twitter:image:height" content="100">
725
+ ```
726
+
699
727
  Further reading:
700
728
 
701
- * [Twitter Cards Documentation](https://dev.twitter.com/cards/)
729
+ - [Twitter Cards Documentation](https://dev.twitter.com/cards/)
702
730
 
703
731
  ### App Links
704
732
 
@@ -719,7 +747,7 @@ set_meta_tags al: {
719
747
 
720
748
  Further reading:
721
749
 
722
- * [App Links Documentation](https://developers.facebook.com/docs/applinks)
750
+ - [App Links Documentation](https://developers.facebook.com/docs/applinks)
723
751
 
724
752
  ### Custom meta tags
725
753
 
data/Rakefile CHANGED
@@ -16,3 +16,34 @@ task :circleci do
16
16
  config_path = File.expand_path('.circleci/config.yml', __dir__)
17
17
  File.write config_path, ERB.new(File.read(template_path)).result
18
18
  end
19
+
20
+ module SteepRunner
21
+ def self.run(*command)
22
+ require "steep"
23
+ require "steep/cli"
24
+
25
+ Steep::CLI.new(argv: command, stdout: $stdout, stderr: $stderr, stdin: $stdin).run
26
+ end
27
+ end
28
+
29
+ task :steep do
30
+ SteepRunner.run("check")
31
+ end
32
+
33
+ namespace :steep do
34
+ task :stats do
35
+ SteepRunner.run("stats", "--log-level=fatal")
36
+ end
37
+ end
38
+
39
+ namespace :rbs do
40
+ task :spec do
41
+ exec(
42
+ {
43
+ 'RBS_TEST_TARGET' => 'MetaTags::*',
44
+ 'RUBYOPT' => '-rrbs/test/setup',
45
+ },
46
+ 'bundle exec rspec',
47
+ )
48
+ end
49
+ end
data/Steepfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ target :lib do
4
+ signature "sig"
5
+
6
+ check "lib"
7
+ # check "Gemfile"
8
+
9
+ # We don't want to type check Rails/RSpec related code
10
+ # (because we don't have RBS files for it)
11
+ ignore "lib/meta_tags/railtie.rb"
12
+ ignore "lib/generators"
13
+ end
data/certs/kpumuk.pem CHANGED
@@ -1,7 +1,7 @@
1
1
  -----BEGIN CERTIFICATE-----
2
2
  MIIDODCCAiCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhrcHVt
3
- dWsvREM9a3B1bXVrL0RDPWluZm8wHhcNMTgxMTE2MTgxOTIzWhcNMTkxMTE2MTgx
4
- OTIzWjAjMSEwHwYDVQQDDBhrcHVtdWsvREM9a3B1bXVrL0RDPWluZm8wggEiMA0G
3
+ dWsvREM9a3B1bXVrL0RDPWluZm8wHhcNMjAxMjEwMjA1MTE5WhcNMjExMjEwMjA1
4
+ MTE5WjAjMSEwHwYDVQQDDBhrcHVtdWsvREM9a3B1bXVrL0RDPWluZm8wggEiMA0G
5
5
  CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8NmK6GXPiE/q7PDbj7nNdw3pa8a6Q
6
6
  IDxLtc7kW95e1mh0TVgOE8kvGegGtRtjvhXVGTTFtZ+yMD/0DCfTM2oUQYk5oYpO
7
7
  ZGrCfbNIdZauf4WYsnJtKOTrRoqFMwpL5PlBDKczB2y5lUmQs2HIsjQ0Q21wdKyy
@@ -10,11 +10,11 @@ ZGrCfbNIdZauf4WYsnJtKOTrRoqFMwpL5PlBDKczB2y5lUmQs2HIsjQ0Q21wdKyy
10
10
  RryRTj5NVZbq9p1/WRc5zxD9QhAEPjRa5ikbd+eWebIDpAKI0hpyC/9bAgMBAAGj
11
11
  dzB1MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBT2uFRXNWDpVdbv
12
12
  +xBk8DAgJPGBPTAdBgNVHREEFjAUgRJrcHVtdWtAa3B1bXVrLmluZm8wHQYDVR0S
13
- BBYwFIESa3B1bXVrQGtwdW11ay5pbmZvMA0GCSqGSIb3DQEBCwUAA4IBAQB9bd46
14
- p2C6r49hmuxMrIFRi05MS0Nze6GvlYvF5mb2+KS9YCLWLFb1G+0zttX51qVdO3nc
15
- uw1O5ku+Up47jv5ClyguHinCntFCA5hupyYkbpnFuURZE3QIY6UZQyJ2xuIPFfnR
16
- Q8sXb5/btWSNhKXx29TL35SkEH5fzPA90DljUPGp3lLEK0+7FQk0OkRVumdyanEE
17
- LUchqnAWHnNCdQhEhsnbYhSvG0NE2uzMWeUd6uDONYsRFNRXaRwj8tykWgKZvIod
18
- j0ZkOZOMk6hzny9+AnYZ7eiUqp/XX7Hn+hqtl/AebKhbFapnTu0n7KcfM0oDaLUr
19
- Fc+FAHErSClMb7YN
13
+ BBYwFIESa3B1bXVrQGtwdW11ay5pbmZvMA0GCSqGSIb3DQEBCwUAA4IBAQBdcrpl
14
+ 32OlNaf68v38yzqYkviLELtbzRvEpRuQWZZyxOwU1OWSFAWkkALuseLWHDLYRDE8
15
+ lOzQHewKodqaSPEo63vMZ28UQ3kDP1YE+cXR12fOg4YbCH8VETrTJa3X0AOOAbgA
16
+ ZLMcZD6wu9Zu2rPhxLxs6Q/PaGGEc8bonOirCZrwVDzHFA1cPjcSoApdsyGdRiyj
17
+ 1f+XHXjCE5A1A6b8o4ffpAI6gkuaQOIrgGCyLS9oos6DSuofkvXI9g62G+2ZOmKJ
18
+ U97JEQmXCpruLEeSVT2UqR+iJAWEAxPzqzDbTzZBTSPKn+nXeuF6h81e4hsJtkeJ
19
+ HkYAoatF9iZrxT4E
20
20
  -----END CERTIFICATE-----
@@ -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!
@@ -77,6 +83,7 @@ module MetaTags
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
@@ -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
 
@@ -99,7 +105,7 @@ module MetaTags
99
105
  #
100
106
  def extract_full_title
101
107
  site_title = extract(:site) || ''
102
- title = extract_title || []
108
+ title = extract_title
103
109
  separator = extract_separator
104
110
  reverse = extract(:reverse) == true
105
111
 
@@ -112,8 +118,9 @@ module MetaTags
112
118
  #
113
119
  def extract_title
114
120
  title = extract(:title).presence
115
- return unless title
121
+ return [] unless title
116
122
 
123
+ # @type var title: Array[String]
117
124
  title = Array(title)
118
125
  return title.map(&:downcase) if extract(:lowercase) == true
119
126
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MetaTags
4
+ class Railtie < Rails::Railtie
5
+ initializer 'meta_tags.setup_action_controller' do
6
+ ActiveSupport.on_load :action_controller do
7
+ ActionController::Base.include MetaTags::ControllerHelper
8
+ end
9
+ end
10
+
11
+ initializer 'meta_tags.setup_action_view' do
12
+ ActiveSupport.on_load :action_view do
13
+ ActionView::Base.include MetaTags::ViewHelper
14
+ end
15
+ end
16
+ end
17
+ 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)
@@ -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.
@@ -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
220
  when Hash
207
221
  :process_hash
208
222
  when Array
209
223
  :process_array
210
224
  else
225
+ iprop = itemprop
211
226
  :render_tag
212
227
  end
213
- __send__(method, tags, property, content, **opts)
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.kind_of?(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