Class: MetaTags::Renderer

Inherits:
Object show all
Defined in:
lib/meta_tags/renderer.rb,
sig/lib/meta_tags/renderer.rbs

Overview

This class is used by the MetaTags gem to render HTML meta tags on a page.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(meta_tags) ⇒ Renderer

Initializes a new instance of Renderer.



11
12
13
14
# File 'lib/meta_tags/renderer.rb', line 11

def initialize(meta_tags)
  @meta_tags = meta_tags
  @normalized_meta_tags = {}
end

Instance Attribute Details

#meta_tagsMetaTagsCollection (readonly)

Returns the value of attribute meta_tags.



6
7
8
# File 'lib/meta_tags/renderer.rb', line 6

def meta_tags
  @meta_tags
end

#normalized_meta_tagsHash[Symbol, meta_value] (readonly)

Returns the value of attribute normalized_meta_tags.



6
7
8
# File 'lib/meta_tags/renderer.rb', line 6

def normalized_meta_tags
  @normalized_meta_tags
end

Instance Method Details

#configured_name_key(name) ⇒ Symbol

Returns the meta tag property name for a given meta tag based on the configured list of property tags in MetaTags::Configuration#property_tags.



312
313
314
315
316
317
318
# File 'lib/meta_tags/renderer.rb', line 312

def configured_name_key(name)
  name = name.to_s
  is_property_tag = MetaTags.config.property_tags.any? do |tag_name|
    property_tag?(name, tag_name.to_s)
  end
  is_property_tag ? :property : :name
end

#process_array(tags, property, content, itemprop: nil) ⇒ void

This method returns an undefined value.

Recursive method to process an array of meta tags.



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/meta_tags/renderer.rb', line 261

def process_array(tags, property, content, itemprop: nil)
  unless MetaTags.config.resolve_symbolic_references_in_arrays
    symbol_reference = content.find { |value| value.is_a?(Symbol) }
    if symbol_reference
      MetaTags.deprecator.warn(
        "Passing #{symbol_reference.inspect} directly inside a nested meta tag Array is deprecated. " \
          "It is rendered literally in MetaTags 2.x but will be interpreted as a mirrored reference in MetaTags 3.0. " \
          "Set MetaTags.config.resolve_symbolic_references_in_arrays = true to opt in now; this behavior will " \
          "become the default in MetaTags 3.0. Use a String to keep a literal value."
      )
    end
  end

  content.each { |value| process_tree(tags, property, value, itemprop: itemprop) }
end

#process_hash(tags, property, content, itemprop: nil) ⇒ void

This method returns an undefined value.

Recursive method to process a hash of meta tags.



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/meta_tags/renderer.rb', line 232

def process_hash(tags, property, content, itemprop: nil)
  itemprop_key = content.key?(:itemprop) ? :itemprop : "itemprop"
  current_itemprop = content.key?(itemprop_key) ? content[itemprop_key] : itemprop

  content.each do |key, value|
    next if key.to_s == "itemprop"

    if key.to_s == "_"
      key = property
      next_itemprop = current_itemprop
    else
      key = "#{property}:#{key}"
      next_itemprop = nil
    end

    if value.is_a?(Symbol)
      process_reference(tags, key, value, itemprop: next_itemprop)
    else
      process_tree(tags, key, value, itemprop: next_itemprop)
    end
  end
end

#process_reference(tags, property, reference, itemprop: nil) ⇒ void

This method returns an undefined value.

Resolves a Symbol reference and processes its normalized value once.



283
284
285
286
287
288
289
290
291
292
293
# File 'lib/meta_tags/renderer.rb', line 283

def process_reference(tags, property, reference, itemprop: nil)
  content = normalized_meta_tags[reference]
  case content
  when Hash
    process_hash(tags, property, content, itemprop: itemprop)
  when Array
    process_array(tags, property, content, itemprop: itemprop)
  else
    render_tag(tags, property, content, itemprop: itemprop)
  end
end

#process_tree(tags, property, content, itemprop: nil) ⇒ void

This method returns an undefined value.

Recursive method to process all hashes and arrays in meta tags.



211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/meta_tags/renderer.rb', line 211

def process_tree(tags, property, content, itemprop: nil)
  case content
  when Hash
    process_hash(tags, property, content, itemprop: itemprop)
  when Array
    process_array(tags, property, content, itemprop: itemprop)
  else
    if content.is_a?(Symbol) && MetaTags.config.resolve_symbolic_references_in_arrays
      process_reference(tags, property, content, itemprop: itemprop)
    else
      render_tag(tags, property, content, itemprop: itemprop)
    end
  end
end

#property_tag?(name, tag_name) ⇒ Boolean

Returns true when a configured property tag matches the exact meta tag name or the start of a colon-delimited namespace.



326
327
328
329
330
331
332
333
334
# File 'lib/meta_tags/renderer.rb', line 326

def property_tag?(name, tag_name)
  return false unless name.start_with?(tag_name)

  tag_name_length = tag_name.bytesize
  return true if name.bytesize == tag_name_length
  return true if tag_name.getbyte(tag_name_length - 1) == 58

  name.getbyte(tag_name_length) == 58
end

#render(view) ⇒ String

Renders meta tags on the page.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/meta_tags/renderer.rb', line 19

def render(view)
  tags = [] # : Array[Tag]

  render_charset(tags)
  render_title(tags)
  render_icon(tags)
  render_with_normalization(tags, :description)
  render_with_normalization(tags, :keywords)
  render_refresh(tags)
  render_canonical_link(tags)
  render_noindex(tags)
  render_alternate(tags)
  render_open_search(tags)
  render_links(tags)

  render_hashes(tags)
  render_custom(tags)

  rendered_tags = tags.tap(&:compact!).map { |tag| tag.render(view) }
  view.safe_join rendered_tags, MetaTags.config.minify_output ? "" : "\n"
end

#render_alternate(tags) ⇒ void

This method returns an undefined value.

Renders alternate link tags.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/meta_tags/renderer.rb', line 116

def render_alternate(tags)
  alternate = meta_tags.extract(:alternate)
  return unless alternate

  if alternate.is_a?(Hash)
    alternate.each do |hreflang, href|
      tags << Tag.new(:link, rel: "alternate", href: href, hreflang: hreflang) if href.present?
    end
  elsif alternate.is_a?(Array)
    alternate.each do |link_params|
      link_params = {rel: "alternate"}.with_indifferent_access.merge(link_params)
      tags << Tag.new(:link, link_params) if link_params[:href].present?
    end
  end
end

This method returns an undefined value.

Renders the canonical link.



162
163
164
165
166
167
168
169
# File 'lib/meta_tags/renderer.rb', line 162

def render_canonical_link(tags)
  href = meta_tags.extract(:canonical) # extract, so it's not used anywhere else
  return if MetaTags.config.skip_canonical_links_on_noindex && meta_tags.noindex?
  return if href.blank?

  @normalized_meta_tags[:canonical] = href
  tags << Tag.new(:link, rel: :canonical, href: href)
end

#render_charset(tags) ⇒ void

This method returns an undefined value.

Renders charset tag.



46
47
48
49
# File 'lib/meta_tags/renderer.rb', line 46

def render_charset(tags)
  charset = meta_tags.extract(:charset)
  tags << Tag.new(:meta, charset: charset) if charset.present?
end

#render_custom(tags) ⇒ void

This method returns an undefined value.

Renders custom meta tags.



195
196
197
198
199
200
201
202
# File 'lib/meta_tags/renderer.rb', line 195

def render_custom(tags)
  meta_tags.meta_tags.each do |name, data|
    Array(data).each do |val|
      tags << Tag.new(:meta, configured_name_key(name) => name, :content => val)
    end
    meta_tags.extract(name)
  end
end

#render_hash(tags, key) ⇒ void

This method returns an undefined value.

Renders a complex hash object by key.



184
185
186
187
188
189
190
# File 'lib/meta_tags/renderer.rb', line 184

def render_hash(tags, key)
  data = meta_tags.meta_tags[key]
  return unless data.is_a?(Hash)

  process_hash(tags, key, data)
  meta_tags.extract(key)
end

#render_hashes(tags) ⇒ void

This method returns an undefined value.

Renders complex hash objects.



174
175
176
177
178
# File 'lib/meta_tags/renderer.rb', line 174

def render_hashes(tags)
  meta_tags.meta_tags.each_key do |property|
    render_hash(tags, property)
  end
end

#render_icon(tags) ⇒ void

This method returns an undefined value.

Renders icon(s) tag.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/meta_tags/renderer.rb', line 69

def render_icon(tags)
  icon = meta_tags.extract(:icon)
  return unless icon

  # String? Value is an href
  icon = [{href: icon}] if icon.is_a?(String)
  # Hash? Single icon instead of a list of icons
  icon = [icon] if icon.is_a?(Hash)

  icon.each do |icon_params|
    icon_params = {rel: "icon", type: "image/x-icon"}.with_indifferent_access.merge(icon_params)
    tags << Tag.new(:link, icon_params) if icon_params[:href].present?
  end
end

This method returns an undefined value.

Renders links.



149
150
151
152
153
154
155
156
157
# File 'lib/meta_tags/renderer.rb', line 149

def render_links(tags)
  [:amphtml, :prev, :next, :image_src, :manifest].each do |tag_name|
    href = meta_tags.extract(tag_name)
    if href.present?
      @normalized_meta_tags[tag_name] = href
      tags << Tag.new(:link, rel: tag_name, href: href)
    end
  end
end

#render_noindex(tags) ⇒ void

This method returns an undefined value.

Renders noindex and nofollow meta tags.



99
100
101
102
103
# File 'lib/meta_tags/renderer.rb', line 99

def render_noindex(tags)
  meta_tags.extract_robots.each do |name, content|
    tags << Tag.new(:meta, name: name, content: content) if content.present?
  end
end

#render_open_search(tags) ⇒ void

This method returns an undefined value.

Renders the OpenSearch link tag.



135
136
137
138
139
140
141
142
143
144
# File 'lib/meta_tags/renderer.rb', line 135

def render_open_search(tags)
  open_search = meta_tags.extract(:open_search)
  return unless open_search

  href = open_search[:href]
  title = open_search[:title]

  type = "application/opensearchdescription+xml"
  tags << Tag.new(:link, rel: "search", type: type, href: href, title: title) if href.present?
end

#render_refresh(tags) ⇒ void

This method returns an undefined value.

Renders refresh meta tag.



108
109
110
111
# File 'lib/meta_tags/renderer.rb', line 108

def render_refresh(tags)
  refresh = meta_tags.extract(:refresh)
  tags << Tag.new(:meta, "http-equiv" => "refresh", :content => refresh.to_s) if refresh.present?
end

#render_tag(tags, name, value, itemprop: nil) ⇒ void

This method returns an undefined value.

Renders a single meta tag.



302
303
304
305
# File 'lib/meta_tags/renderer.rb', line 302

def render_tag(tags, name, value, itemprop: nil)
  name_key ||= configured_name_key(name)
  tags << Tag.new(:meta, name_key => name.to_s, :content => value, :itemprop => itemprop) if value.present?
end

#render_title(tags) ⇒ void

This method returns an undefined value.

Renders title tag.



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/meta_tags/renderer.rb', line 54

def render_title(tags)
  normalized_meta_tags[:title] = meta_tags.page_title
  normalized_meta_tags[:site] = meta_tags[:site]
  title = meta_tags.extract_full_title
  normalized_meta_tags[:full_title] = title
  default_attributes = MetaTags.config.title_tag_attributes || {}

  if title.present?
    tags << .new(:title, {content: title}.with_defaults(default_attributes))
  end
end

#render_with_normalization(tags, name) ⇒ void

This method returns an undefined value.

Renders meta tag with normalization (should have a corresponding normalize_ method in TextNormalizer).

See Also:



90
91
92
93
94
# File 'lib/meta_tags/renderer.rb', line 90

def render_with_normalization(tags, name)
  value = TextNormalizer.public_send(:"normalize_#{name}", meta_tags.extract(name))
  normalized_meta_tags[name] = value
  tags << Tag.new(:meta, name: name, content: value) if value.present?
end