meta-tags 2.12.0 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
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