meta_tags-rails 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +21 -0
- data/CHANGELOG.md +135 -0
- data/Gemfile +13 -0
- data/MIT-LICENSE +22 -0
- data/README.md +627 -0
- data/Rakefile +28 -0
- data/lib/meta_tags-rails.rb +37 -0
- data/lib/meta_tags-rails/configuration.rb +21 -0
- data/lib/meta_tags-rails/content_tag.rb +14 -0
- data/lib/meta_tags-rails/controller_helper.rb +44 -0
- data/lib/meta_tags-rails/meta_tags_collection.rb +176 -0
- data/lib/meta_tags-rails/renderer.rb +253 -0
- data/lib/meta_tags-rails/tag.rb +25 -0
- data/lib/meta_tags-rails/text_normalizer.rb +148 -0
- data/lib/meta_tags-rails/version.rb +4 -0
- data/lib/meta_tags-rails/view_helper.rb +205 -0
- data/meta-tags.gemspec +30 -0
- data/spec/configuration_spec.rb +14 -0
- data/spec/controller_helper_spec.rb +42 -0
- data/spec/spec_helper.rb +84 -0
- data/spec/text_normalizer/normalize_title_spec.rb +43 -0
- data/spec/text_normalizer/truncate_array_spec.rb +60 -0
- data/spec/view_helper/charset_spec.rb +16 -0
- data/spec/view_helper/custom_spec.rb +67 -0
- data/spec/view_helper/description_spec.rb +61 -0
- data/spec/view_helper/icon_spec.rb +42 -0
- data/spec/view_helper/keywords_spec.rb +58 -0
- data/spec/view_helper/links_spec.rb +125 -0
- data/spec/view_helper/module_spec.rb +41 -0
- data/spec/view_helper/noindex_spec.rb +107 -0
- data/spec/view_helper/open_graph_spec.rb +86 -0
- data/spec/view_helper/open_search_spec.rb +33 -0
- data/spec/view_helper/refresh_spec.rb +32 -0
- data/spec/view_helper/title_spec.rb +155 -0
- data/spec/view_helper/twitter_spec.rb +31 -0
- data/spec/view_helper_spec.rb +57 -0
- metadata +172 -0
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task test: :spec
|
8
|
+
task default: :spec
|
9
|
+
|
10
|
+
desc 'Starts irb with MetaTags gem loaded'
|
11
|
+
task :console do
|
12
|
+
require 'irb'
|
13
|
+
|
14
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
15
|
+
require 'meta_tags'
|
16
|
+
ARGV.clear
|
17
|
+
IRB.start
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'yard'
|
21
|
+
YARD::Rake::YardocTask.new(:yard) do |t|
|
22
|
+
t.options = ['--title', 'MetaTags Documentation']
|
23
|
+
if ENV['PRIVATE']
|
24
|
+
t.options.concat ['--protected', '--private']
|
25
|
+
else
|
26
|
+
t.options.concat ['--protected', '--no-private']
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
require 'action_view'
|
3
|
+
|
4
|
+
# MetaTags gem namespace.
|
5
|
+
module MetaTags
|
6
|
+
# Returns MetaTags gem configuration.
|
7
|
+
#
|
8
|
+
def self.config
|
9
|
+
@@config ||= Configuration.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# Configures MetaTags gem.
|
13
|
+
#
|
14
|
+
# @yield [Configuration] configuration object.
|
15
|
+
# @example
|
16
|
+
#
|
17
|
+
# MetaTags.configure do |config|
|
18
|
+
# # config.title_limit = 100
|
19
|
+
# end
|
20
|
+
def self.configure
|
21
|
+
yield config
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'meta_tags-rails/version'
|
26
|
+
|
27
|
+
require 'meta_tags-rails/configuration'
|
28
|
+
require 'meta_tags-rails/controller_helper'
|
29
|
+
require 'meta_tags-rails/meta_tags_collection'
|
30
|
+
require 'meta_tags-rails/renderer'
|
31
|
+
require 'meta_tags-rails/tag'
|
32
|
+
require 'meta_tags-rails/content_tag'
|
33
|
+
require 'meta_tags-rails/text_normalizer'
|
34
|
+
require 'meta_tags-rails/view_helper'
|
35
|
+
|
36
|
+
ActionView::Base.send :include, MetaTags::ViewHelper
|
37
|
+
ActionController::Base.send :include, MetaTags::ControllerHelper
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MetaTags
|
2
|
+
# MetaTags configuration.
|
3
|
+
class Configuration
|
4
|
+
# How many characters to truncate title to.
|
5
|
+
attr_accessor :title_limit
|
6
|
+
# How many characters to truncate description to.
|
7
|
+
attr_accessor :description_limit
|
8
|
+
# How many characters to truncate keywords to.
|
9
|
+
attr_accessor :keywords_limit
|
10
|
+
# Keywords separator - a string to join keywords with.
|
11
|
+
attr_accessor :keywords_separator
|
12
|
+
|
13
|
+
# Initializes a new instance of Configuration class.
|
14
|
+
def initialize
|
15
|
+
@title_limit = 70
|
16
|
+
@description_limit = 160
|
17
|
+
@keywords_limit = 255
|
18
|
+
@keywords_separator = ', '
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module MetaTags
|
2
|
+
# Represents an HTML meta tag with content (<tag></tag>).
|
3
|
+
# Content should be passed as a `:content` attribute.
|
4
|
+
class ContentTag < Tag
|
5
|
+
# Render tag into a Rails view.
|
6
|
+
#
|
7
|
+
# @param [ActionView::Base] view instance of a Rails view.
|
8
|
+
# @return [String] HTML string for the tag.
|
9
|
+
#
|
10
|
+
def render(view)
|
11
|
+
view.content_tag(name, attributes[:content], attributes.except(:content))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module MetaTags
|
2
|
+
# Contains methods to use in controllers.
|
3
|
+
#
|
4
|
+
# You can define several instance variables to set meta tags:
|
5
|
+
# @page_title = 'Member Login'
|
6
|
+
# @page_description = 'Member login page.'
|
7
|
+
# @page_keywords = 'Site, Login, Members'
|
8
|
+
#
|
9
|
+
# Also you can use {#set_meta_tags} method, that have the same parameters
|
10
|
+
# as {ViewHelper#set_meta_tags}.
|
11
|
+
#
|
12
|
+
module ControllerHelper
|
13
|
+
extend ActiveSupport::Concern
|
14
|
+
|
15
|
+
included do
|
16
|
+
alias_method_chain :render, :meta_tags
|
17
|
+
end
|
18
|
+
|
19
|
+
# Processes the <tt>@page_title</tt>, <tt>@page_keywords</tt>, and
|
20
|
+
# <tt>@page_description</tt> instance variables and calls +render+.
|
21
|
+
def render_with_meta_tags(*args, &block)
|
22
|
+
self.meta_tags[:title] = @page_title if @page_title
|
23
|
+
self.meta_tags[:keywords] = @page_keywords if @page_keywords
|
24
|
+
self.meta_tags[:description] = @page_description if @page_description
|
25
|
+
|
26
|
+
render_without_meta_tags(*args, &block)
|
27
|
+
end
|
28
|
+
protected :render_with_meta_tags
|
29
|
+
|
30
|
+
# Set meta tags for the page.
|
31
|
+
#
|
32
|
+
# See <tt>MetaTags::ViewHelper#set_meta_tags</tt> for details.
|
33
|
+
def set_meta_tags(meta_tags)
|
34
|
+
self.meta_tags.update(meta_tags)
|
35
|
+
end
|
36
|
+
protected :set_meta_tags
|
37
|
+
|
38
|
+
# Get meta tags for the page.
|
39
|
+
def meta_tags
|
40
|
+
@meta_tags ||= MetaTagsCollection.new
|
41
|
+
end
|
42
|
+
protected :meta_tags
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module MetaTags
|
2
|
+
# Class represents a collection of meta tags. Basically a wrapper around
|
3
|
+
# HashWithIndifferentAccess, with some additional helper methods.
|
4
|
+
class MetaTagsCollection
|
5
|
+
attr_reader :meta_tags
|
6
|
+
|
7
|
+
# Initializes a new instance of MetaTagsCollection.
|
8
|
+
#
|
9
|
+
def initialize
|
10
|
+
@meta_tags = HashWithIndifferentAccess.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns meta tag value by name.
|
14
|
+
#
|
15
|
+
# @param [String, Symbol] name meta tag name.
|
16
|
+
# @return meta tag value.
|
17
|
+
#
|
18
|
+
def [](name)
|
19
|
+
@meta_tags[name]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sets meta tag value by name.
|
23
|
+
#
|
24
|
+
# @param [String, Symbol] name meta tag name.
|
25
|
+
# @param value meta tag value.
|
26
|
+
# @return meta tag value.
|
27
|
+
#
|
28
|
+
def []=(name, value)
|
29
|
+
@meta_tags[name] = value
|
30
|
+
end
|
31
|
+
|
32
|
+
# Recursively merges a Hash of meta tag attributes into current list.
|
33
|
+
#
|
34
|
+
# @param [Hash] meta_tags meta tags Hash to merge into current list.
|
35
|
+
# @return [Hash] result of the merge.
|
36
|
+
#
|
37
|
+
def update(meta_tags = {})
|
38
|
+
@meta_tags.deep_merge! normalize_open_graph(meta_tags)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Temporary merges defaults with current meta tags list and yields the block.
|
42
|
+
#
|
43
|
+
# @param [Hash] defaults list of default meta tag attributes.
|
44
|
+
# @return result of the block call.
|
45
|
+
#
|
46
|
+
def with_defaults(defaults = {})
|
47
|
+
old_meta_tags = @meta_tags
|
48
|
+
@meta_tags = normalize_open_graph(defaults).deep_merge!(self.meta_tags)
|
49
|
+
yield
|
50
|
+
ensure
|
51
|
+
@meta_tags = old_meta_tags
|
52
|
+
end
|
53
|
+
|
54
|
+
# Constructs the full title as if it would be rendered in title meta tag.
|
55
|
+
#
|
56
|
+
# @param [Hash] defaults list of default meta tag attributes.
|
57
|
+
# @return [String] page title.
|
58
|
+
#
|
59
|
+
def full_title(defaults = {})
|
60
|
+
with_defaults(defaults) { extract_full_title }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Deletes and returns a meta tag value by name.
|
64
|
+
#
|
65
|
+
# @param [String, Symbol] name meta tag name.
|
66
|
+
# @return [Object] meta tag value.
|
67
|
+
#
|
68
|
+
def extract(name)
|
69
|
+
@meta_tags.delete(name)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Deletes specified meta tags.
|
73
|
+
#
|
74
|
+
# @param [Array<String, Symbol>] names a list of meta tags to delete.
|
75
|
+
#
|
76
|
+
def delete(*names)
|
77
|
+
names.each { |name| @meta_tags.delete(name) }
|
78
|
+
end
|
79
|
+
|
80
|
+
# Extracts full page title and deletes all related meta tags.
|
81
|
+
#
|
82
|
+
# @return [String] page title.
|
83
|
+
#
|
84
|
+
def extract_full_title
|
85
|
+
site_title = extract(:site) || ''
|
86
|
+
title = extract_title || []
|
87
|
+
separator = extract_separator
|
88
|
+
reverse = extract(:reverse) === true
|
89
|
+
|
90
|
+
TextNormalizer.normalize_title(site_title, title, separator, reverse)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Extracts page title as an array of segments without site title and separators.
|
94
|
+
#
|
95
|
+
# @return [Array<String>] segments of page title.
|
96
|
+
#
|
97
|
+
def extract_title
|
98
|
+
title = extract(:title).presence
|
99
|
+
return unless title
|
100
|
+
|
101
|
+
title = Array(title)
|
102
|
+
title.each(&:downcase!) if extract(:lowercase) === true
|
103
|
+
title
|
104
|
+
end
|
105
|
+
|
106
|
+
# Extracts title separator as a string.
|
107
|
+
#
|
108
|
+
# @return [String] page title separator.
|
109
|
+
#
|
110
|
+
def extract_separator
|
111
|
+
if meta_tags[:separator] === false
|
112
|
+
# Special case: if separator is hidden, do not display suffix/prefix
|
113
|
+
prefix = separator = suffix = ''
|
114
|
+
else
|
115
|
+
prefix = extract_separator_section(:prefix, ' ')
|
116
|
+
separator = extract_separator_section(:separator, '|')
|
117
|
+
suffix = extract_separator_section(:suffix, ' ')
|
118
|
+
end
|
119
|
+
delete(:separator, :prefix, :suffix)
|
120
|
+
|
121
|
+
TextNormalizer.safe_join([prefix, separator, suffix], '')
|
122
|
+
end
|
123
|
+
|
124
|
+
# Extracts noindex settings as a Hash mapping noindex tag name to value.
|
125
|
+
#
|
126
|
+
# @return [Hash<String,String>] noindex attributes.
|
127
|
+
#
|
128
|
+
def extract_noindex
|
129
|
+
noindex_name, noindex_value = extract_noindex_attribute(:noindex)
|
130
|
+
nofollow_name, nofollow_value = extract_noindex_attribute(:nofollow)
|
131
|
+
|
132
|
+
if noindex_name == nofollow_name
|
133
|
+
{ noindex_name => [noindex_value, nofollow_value].compact.join(', ') }
|
134
|
+
else
|
135
|
+
{ noindex_name => noindex_value, nofollow_name => nofollow_value }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
protected
|
140
|
+
|
141
|
+
# Converts input hash to HashWithIndifferentAccess and renames :open_graph to :og.
|
142
|
+
#
|
143
|
+
# @param [Hash] meta_tags list of meta tags.
|
144
|
+
# @return [HashWithIndifferentAccess] normalized meta tags list.
|
145
|
+
#
|
146
|
+
def normalize_open_graph(meta_tags)
|
147
|
+
meta_tags = meta_tags.is_a?(HashWithIndifferentAccess) ? meta_tags.dup : meta_tags.with_indifferent_access
|
148
|
+
meta_tags[:og] = meta_tags.delete(:open_graph) if meta_tags.key?(:open_graph)
|
149
|
+
meta_tags
|
150
|
+
end
|
151
|
+
|
152
|
+
# Extracts separator segment without deleting it from meta tags list.
|
153
|
+
# If the value is false, empty string will be returned.
|
154
|
+
#
|
155
|
+
# @param [Symbol, String] name separator segment name.
|
156
|
+
# @param [String] default default value.
|
157
|
+
# @return [String] separator segment value.
|
158
|
+
#
|
159
|
+
def extract_separator_section(name, default)
|
160
|
+
meta_tags[name] === false ? '' : (meta_tags[name] || default)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Extracts noindex attribute name and value without deleting it from meta tags list.
|
164
|
+
#
|
165
|
+
# @param [String, Symbol] name noindex attribute name.
|
166
|
+
# @return [Array<String>] pair of noindex attribute name and value.
|
167
|
+
#
|
168
|
+
def extract_noindex_attribute(name)
|
169
|
+
noindex = extract(name)
|
170
|
+
noindex_name = String === noindex ? noindex : 'robots'
|
171
|
+
noindex_value = noindex ? name.to_s : nil
|
172
|
+
|
173
|
+
[ noindex_name, noindex_value ]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
module MetaTags
|
2
|
+
# This class is used by MetaTags gems to render HTML meta tags into page.
|
3
|
+
class Renderer
|
4
|
+
attr_reader :meta_tags, :normalized_meta_tags
|
5
|
+
|
6
|
+
# Initialized a new instance of Renderer.
|
7
|
+
#
|
8
|
+
# @param [MetaTagsCollection] meta_tags meta tags object to render.
|
9
|
+
#
|
10
|
+
def initialize(meta_tags)
|
11
|
+
@meta_tags = meta_tags
|
12
|
+
@normalized_meta_tags = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
# Renders meta tags on the page.
|
16
|
+
#
|
17
|
+
# @param [ActionView::Base] view Rails view object.
|
18
|
+
def render(view)
|
19
|
+
tags = []
|
20
|
+
|
21
|
+
render_charset(tags)
|
22
|
+
render_title(tags)
|
23
|
+
render_icon(tags)
|
24
|
+
render_with_normalization(tags, :description)
|
25
|
+
render_with_normalization(tags, :keywords)
|
26
|
+
render_refresh(tags)
|
27
|
+
render_noindex(tags)
|
28
|
+
render_alternate(tags)
|
29
|
+
render_open_search(tags)
|
30
|
+
render_links(tags)
|
31
|
+
|
32
|
+
render_hash(tags, :og, name_key: :property)
|
33
|
+
render_hashes(tags)
|
34
|
+
render_custom(tags)
|
35
|
+
|
36
|
+
tags.compact.map { |tag| tag.render(view) }.join("\n").html_safe
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
|
42
|
+
# Renders charset tag.
|
43
|
+
#
|
44
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
45
|
+
#
|
46
|
+
def render_charset(tags)
|
47
|
+
if charset = meta_tags.extract(:charset)
|
48
|
+
tags << Tag.new(:meta, charset: charset) if charset.present?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Renders title tag.
|
53
|
+
#
|
54
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
55
|
+
#
|
56
|
+
def render_title(tags)
|
57
|
+
title = meta_tags.extract_full_title
|
58
|
+
normalized_meta_tags[:title] = title
|
59
|
+
tags << ContentTag.new(:title, content: title) if title.present?
|
60
|
+
end
|
61
|
+
|
62
|
+
# Renders icon(s) tag.
|
63
|
+
#
|
64
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
65
|
+
#
|
66
|
+
def render_icon(tags)
|
67
|
+
if icon = meta_tags.extract(:icon)
|
68
|
+
if String === icon
|
69
|
+
tags << Tag.new(:link, rel: 'icon', href: icon, type: 'image/x-icon')
|
70
|
+
else
|
71
|
+
icon = [icon] if Hash === icon
|
72
|
+
icon.each do |icon_params|
|
73
|
+
icon_params = { rel: 'icon', type: 'image/x-icon' }.with_indifferent_access.merge(icon_params)
|
74
|
+
tags << Tag.new(:link, icon_params)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Renders meta tag with normalization (should have a corresponding normalize_
|
81
|
+
# method in TextNormalizer).
|
82
|
+
#
|
83
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
84
|
+
# @see TextNormalizer
|
85
|
+
#
|
86
|
+
def render_with_normalization(tags, name)
|
87
|
+
value = TextNormalizer.public_send("normalize_#{name}", meta_tags.extract(name))
|
88
|
+
normalized_meta_tags[name] = value
|
89
|
+
tags << Tag.new(:meta, name: name, content: value) if value.present?
|
90
|
+
end
|
91
|
+
|
92
|
+
# Renders noindex and nofollow meta tags.
|
93
|
+
#
|
94
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
95
|
+
#
|
96
|
+
def render_noindex(tags)
|
97
|
+
meta_tags.extract_noindex.each do |name, content|
|
98
|
+
tags << Tag.new(:meta, name: name, content: content) if content.present?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Renders refresh meta tag.
|
103
|
+
#
|
104
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
105
|
+
#
|
106
|
+
def render_refresh(tags)
|
107
|
+
if refresh = meta_tags.extract(:refresh)
|
108
|
+
tags << Tag.new(:meta, 'http-equiv' => 'refresh', content: refresh.to_s) if refresh.present?
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Renders alternate link tags.
|
113
|
+
#
|
114
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
115
|
+
#
|
116
|
+
def render_alternate(tags)
|
117
|
+
if alternate = meta_tags.extract(:alternate)
|
118
|
+
if Hash === alternate
|
119
|
+
alternate.each do |hreflang, href|
|
120
|
+
tags << Tag.new(:link, rel: 'alternate', href: href, hreflang: hreflang) if href.present?
|
121
|
+
end
|
122
|
+
elsif Array === alternate
|
123
|
+
alternate.each do |link_params|
|
124
|
+
tags << Tag.new(:link, { rel: 'alternate' }.with_indifferent_access.merge(link_params))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Renders open_search link tag.
|
131
|
+
#
|
132
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
133
|
+
#
|
134
|
+
def render_open_search(tags)
|
135
|
+
if open_search = meta_tags.extract(:open_search)
|
136
|
+
href = open_search[:href]
|
137
|
+
title = open_search[:title]
|
138
|
+
if href.present?
|
139
|
+
type = "application/opensearchdescription+xml"
|
140
|
+
tags << Tag.new(:link, rel: 'search', type: type, href: href, title: title)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Renders links.
|
146
|
+
#
|
147
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
148
|
+
#
|
149
|
+
def render_links(tags)
|
150
|
+
[ :canonical, :prev, :next, :author, :publisher ].each do |tag_name|
|
151
|
+
href = meta_tags.extract(tag_name)
|
152
|
+
if href.present?
|
153
|
+
@normalized_meta_tags[tag_name] = href
|
154
|
+
tags << Tag.new(:link, rel: tag_name, href: href)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Renders complex hash objects.
|
160
|
+
#
|
161
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
162
|
+
#
|
163
|
+
def render_hashes(tags, options = {})
|
164
|
+
meta_tags.meta_tags.each do |property, data|
|
165
|
+
if data.is_a?(Hash)
|
166
|
+
process_hash(tags, property, data, options)
|
167
|
+
meta_tags.extract(property)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Renders a complex hash object by key.
|
173
|
+
#
|
174
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
175
|
+
#
|
176
|
+
def render_hash(tags, key, options = {})
|
177
|
+
data = meta_tags.meta_tags[key]
|
178
|
+
if data.is_a?(Hash)
|
179
|
+
process_hash(tags, key, data, options)
|
180
|
+
meta_tags.extract(key)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Renders custom meta tags.
|
185
|
+
#
|
186
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
187
|
+
#
|
188
|
+
def render_custom(tags)
|
189
|
+
meta_tags.meta_tags.each do |name, data|
|
190
|
+
Array(data).each do |val|
|
191
|
+
tags << Tag.new(:meta, name: name, content: val)
|
192
|
+
end
|
193
|
+
meta_tags.extract(name)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Recursive method to process all the hashes and arrays on meta tags
|
198
|
+
#
|
199
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
200
|
+
# @param [String, Symbol] property a Hash or a String to render as meta tag.
|
201
|
+
# @param [Hash, Array, String, Symbol] content text content or a symbol reference to
|
202
|
+
# top-level meta tag.
|
203
|
+
#
|
204
|
+
def process_tree(tags, property, content, options = {})
|
205
|
+
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, options)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Recursive method to process a hash with meta tags
|
217
|
+
#
|
218
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
219
|
+
# @param [String, Symbol] property a Hash or a String to render as meta tag.
|
220
|
+
# @param [Hash] content nested meta tag attributes.
|
221
|
+
#
|
222
|
+
def process_hash(tags, property, content, options = {})
|
223
|
+
content.each do |key, value|
|
224
|
+
key = key.to_s == '_' ? property : "#{property}:#{key}"
|
225
|
+
value = normalized_meta_tags[value] if value.is_a?(Symbol)
|
226
|
+
process_tree(tags, key, value, options)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Recursive method to process a hash with meta tags
|
231
|
+
#
|
232
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
233
|
+
# @param [String, Symbol] property a Hash or a String to render as meta tag.
|
234
|
+
# @param [Array] content array of nested meta tag attributes or values.
|
235
|
+
#
|
236
|
+
def process_array(tags, property, content, options = {})
|
237
|
+
content.each { |v| process_tree(tags, property, v, options) }
|
238
|
+
end
|
239
|
+
|
240
|
+
# Recursive method to process a hash with meta tags
|
241
|
+
#
|
242
|
+
# @param [Array<Tag>] tags a buffer object to store tag in.
|
243
|
+
# @param [String, Symbol] name a Hash or a String to render as meta tag.
|
244
|
+
# @param [String, Symbol] value text content or a symbol reference to
|
245
|
+
# top-level meta tag.
|
246
|
+
#
|
247
|
+
def render_tag(tags, name, value, options = {})
|
248
|
+
name_key = options.fetch(:name_key, :name)
|
249
|
+
value_key = options.fetch(:value_key, :content)
|
250
|
+
tags << Tag.new(:meta, name_key => name.to_s, value_key => value) unless value.blank?
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|