page_meta 1.1.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89a7406728480d6a3eb785869d6cae90f32b3bfe2fd3e0f8a6a6ced5c03da4b3
4
- data.tar.gz: e5db2e7b705299c0f736164fa5352242e2211a1c6bed9d12802263643cec2930
3
+ metadata.gz: 732b10b45a16c54c1d95e8f20440bc52cbac065e378e1eed2284c6d99c2f9d47
4
+ data.tar.gz: 0266ece7ba5fbd03f8e0c9f4b77ff3097192ef8999292342680149b77cd8577c
5
5
  SHA512:
6
- metadata.gz: e3961943c7d5506baaa3ce0f28d06819dc430aa3c3f38e503324cb52277c1aa2163ef224e4be4f2cfd41fa2e322cc087e0fd6d3680674ccd036e3d9bb6a34c61
7
- data.tar.gz: bf19f1d84e6fdcb8ad48b8d44a898d3682316680459c34d661f5844797912fa21f704cde143d6d079ac8d32895be2182c29f58d068df3fa2795e314beab5f11c
6
+ metadata.gz: a9eef3c915a3d762e53aef9d75ab95c11ccd76d5a2385d07f7159c69cae9e48488295100d36e349369c65cb4e8e255a7d8078c058cd40cbdc5bc0c704de07c05
7
+ data.tar.gz: a4e04ac623c1e2963b23c747008d7d2e84fac6d4bfda74bf7b516258a2b71e5032e215fce03c89d57f68532e1e336e5239dae9f432b233e4f800ed05ddd1bffe
@@ -19,17 +19,17 @@ jobs:
19
19
  strategy:
20
20
  fail-fast: false
21
21
  matrix:
22
- ruby: ["2.7", "3.0", "3.1"]
22
+ ruby: ["3.1", "3.2", "3.3"]
23
23
  gemfile:
24
24
  - Gemfile
25
+ - gemfiles/7_1.gemfile
25
26
  - gemfiles/7_0.gemfile
26
27
  - gemfiles/6_1.gemfile
27
- - gemfiles/6_0.gemfile
28
28
 
29
29
  steps:
30
- - uses: actions/checkout@v3
30
+ - uses: actions/checkout@v4
31
31
 
32
- - uses: actions/cache@v3
32
+ - uses: actions/cache@v4
33
33
  with:
34
34
  path: vendor/bundle
35
35
  key: >
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ inherit_gem:
3
3
  rubocop-fnando: .rubocop.yml
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 3.1
7
7
  NewCops: enable
8
8
  Exclude:
9
9
  - test/support/dummy.rb
@@ -11,9 +11,6 @@ AllCops:
11
11
  - bin/**/*
12
12
  - gemfiles/vendor/**/*
13
13
 
14
- Layout/LineLength:
15
- Enabled: false
16
-
17
14
  Metrics:
18
15
  Enabled: false
19
16
 
@@ -22,3 +19,6 @@ Minitest/MultipleAssertions:
22
19
 
23
20
  Gemspec/DevelopmentDependencies:
24
21
  Enabled: false
22
+
23
+ Minitest/EmptyLineBeforeAssertionMethods:
24
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -11,6 +11,18 @@ Prefix your message with one of the following:
11
11
  - [Security] in case of vulnerabilities.
12
12
  -->
13
13
 
14
+ ## 1.3.0
15
+
16
+ - [Added] `page_meta.base` will now set the base url.
17
+ - [Changed] Some tags will be enforced to show up first. It loosely follows
18
+ https://rviscomi.github.io/capo.js/user/rules/.
19
+
20
+ ## 1.2.0
21
+
22
+ - [Added] The meta tag's content can also be any object that responds to the
23
+ method `call`, like procs.
24
+ - [Fixed] Fixed case where meta tags were being rendered with blank content.
25
+
14
26
  ## 1.1.0
15
27
 
16
28
  - [Added] `<meta name="viewport" content="width=device-width,initial-scale=1">`
data/README.md CHANGED
@@ -46,8 +46,8 @@ en:
46
46
  title: "Welcome to MyApp"
47
47
  ```
48
48
 
49
- Previously, you could also use the `page_meta.{titles,description,keywords}` scopes, but this is now
50
- deprecated in favor of the above.
49
+ Previously, you could also use the `page_meta.{titles,description,keywords}`
50
+ scopes, but this is now deprecated in favor of the above.
51
51
 
52
52
  ```yaml
53
53
  ---
@@ -112,6 +112,14 @@ en:
112
112
  keywords: "myapp, thing, other thing"
113
113
  ```
114
114
 
115
+ ### Defining base url
116
+
117
+ You can define the base url.
118
+
119
+ ```ruby
120
+ page_meta.base "https://example.com/"
121
+ ```
122
+
115
123
  ### Defining meta tags
116
124
 
117
125
  To define other meta tags, you have to use `PageMeta::Base#tag` like the
@@ -127,6 +135,11 @@ class Workshops Controller < ApplicationController
127
135
  end
128
136
  ```
129
137
 
138
+ > [!TIP]
139
+ >
140
+ > The meta tag's content can also be any object that responds to the method
141
+ > `call`. This way you can lazy evaluate the content.
142
+
130
143
  You can define default meta/link tags in a `before_action`:
131
144
 
132
145
  ```ruby
@@ -3,4 +3,4 @@
3
3
  source "https://rubygems.org"
4
4
  gemspec path: ".."
5
5
 
6
- gem "rails", "~> 6.0.0"
6
+ gem "rails", "~> 7.1.0"
@@ -6,11 +6,29 @@ module PageMeta
6
6
  language
7
7
  charset
8
8
  title
9
+ viewport
9
10
  keywords
10
11
  description
11
- viewport
12
12
  ].freeze
13
13
 
14
+ DEFAULT_ORDER = 99
15
+
16
+ META_TAG_ORDER = {
17
+ pragma: -1,
18
+ cache_control: -1,
19
+ expires: -1,
20
+ refresh: -1,
21
+ dns_prefetch_control: 4
22
+ }.freeze
23
+
24
+ LINK_ORDER = {
25
+ preconnect: 6,
26
+ preload: 7,
27
+ modulepreload: 8,
28
+ prefetch: 9,
29
+ dns_prefetch: 10
30
+ }.freeze
31
+
14
32
  attr_reader :controller, :store
15
33
 
16
34
  delegate :[], :[]=, to: :store
@@ -21,86 +39,119 @@ module PageMeta
21
39
  @store = {}
22
40
  end
23
41
 
24
- def meta_tags
25
- @meta_tags ||= {}
42
+ def items
43
+ @items ||= []
26
44
  end
27
45
 
28
- def links
29
- @links ||= []
46
+ # Add a new `<base>` tag.
47
+ def base(href)
48
+ items << {
49
+ type: :tag,
50
+ name: :base,
51
+ value: {href:},
52
+ order: 2,
53
+ open: true
54
+ }
30
55
  end
31
56
 
32
- def tag(name, value)
33
- meta_tags[name] = value
57
+ # Add a new meta tag.
58
+ def tag(name, value = nil, order: nil, **kwargs)
59
+ order = order || META_TAG_ORDER[name] || DEFAULT_ORDER
60
+ items << {type: :meta, name:, value: value || kwargs, order:}
34
61
  end
35
62
 
36
- def link(rel, options)
37
- links << {rel: rel, options: options}
63
+ # Add a new link tag.
64
+ def link(rel, order: nil, **options)
65
+ order = order || LINK_ORDER[rel] || DEFAULT_ORDER
66
+ items << {type: :link, rel:, options:, order:}
38
67
  end
39
68
 
69
+ # Add new html tag, like `<base>` or `<title>`.
70
+ def html(name, value, open: false, order: DEFAULT_ORDER)
71
+ items << {type: :tag, name:, order:, open:, value:}
72
+ end
73
+
74
+ # The title translation.
40
75
  def title
41
76
  @title ||= Translator.new(:titles, naming, store)
42
77
  end
43
78
 
79
+ # The description translation.
44
80
  def description(html: false)
45
- @description[html] ||= Translator.new(:descriptions, naming, store.merge(html: html))
81
+ @description[html] ||= Translator.new(
82
+ :descriptions,
83
+ naming,
84
+ store.merge(html:)
85
+ )
46
86
  end
47
87
 
88
+ # The keywords translation.
48
89
  def keywords
49
90
  @keywords ||= Translator.new(:keywords, naming, store)
50
91
  end
51
92
 
52
93
  def render
53
- compute_default_meta_tags
54
- render_meta_tags + render_links
94
+ compute_default_items
95
+
96
+ items
97
+ .sort_by { _1[:order] }
98
+ .map { send(:"build_#{_1[:type]}", _1).render }
99
+ .join
100
+ .html_safe
55
101
  end
56
102
  alias to_s render
57
103
 
58
- def naming
59
- @naming ||= Naming.new(controller)
104
+ private def build_tag(item)
105
+ klass = item[:open] ? OpenTag : Tag
106
+
107
+ klass.build(item[:name], item[:value])
60
108
  end
61
109
 
62
- def render_meta_tags
63
- meta_tags
64
- .map {|name, value| MetaTag.build(name, value).render }
65
- .join
66
- .html_safe
110
+ private def build_meta(item)
111
+ MetaTag.build(item[:name], item[:value])
67
112
  end
68
113
 
69
- def render_links
70
- links
71
- .map {|info| Link.build(info[:rel], info[:options]).render }
72
- .join
73
- .html_safe
114
+ private def build_link(item)
115
+ Link.build(item[:rel], item[:options])
74
116
  end
75
117
 
76
- def compute_default_meta_tags
118
+ private def naming
119
+ @naming ||= Naming.new(controller)
120
+ end
121
+
122
+ private def compute_default_items
77
123
  DEFAULT_META_TAGS.each do |method_name|
78
- public_send("compute_default_#{method_name}")
124
+ send(:"compute_default_#{method_name}")
79
125
  end
80
126
  end
81
127
 
82
- def compute_default_language
128
+ private def compute_default_language
83
129
  tag(:language, I18n.locale)
84
130
  end
85
131
 
86
- def compute_default_title
87
- tag(:title, title) unless title.to_s.empty?
132
+ private def compute_default_title
133
+ return if title.to_s.blank?
134
+
135
+ html(:title, title.to_s, order: 3)
136
+ tag(:title, title)
88
137
  end
89
138
 
90
- def compute_default_charset
91
- tag(:charset, Rails.configuration.encoding)
139
+ private def compute_default_charset
140
+ tag(:charset, Rails.configuration.encoding, order: 0)
92
141
  end
93
142
 
94
- def compute_default_keywords
95
- tag(:keywords, keywords.to_s) unless keywords.to_s.empty?
143
+ private def compute_default_keywords
144
+ tag(:keywords, keywords.to_s) unless keywords.to_s.blank?
96
145
  end
97
146
 
98
- def compute_default_description
99
- tag(:description, description.to_s) unless description.to_s.empty?
147
+ private def compute_default_description
148
+ tag(:description, description.to_s) unless description.to_s.blank?
100
149
  end
101
150
 
102
- def compute_default_viewport
103
- tag(:viewport, "width=device-width,initial-scale=1") unless meta_tags[:viewport]
151
+ private def compute_default_viewport
152
+ return if items.any? { _1[:name] == :viewport && _1[:type] == :tag }
153
+
154
+ tag(:viewport, "width=device-width,initial-scale=1", order: 1)
104
155
  end
105
156
  end
106
157
  end
@@ -6,10 +6,18 @@ module PageMeta
6
6
  return if content.empty?
7
7
 
8
8
  content.each_with_object([]) do |(attr, value), buffer|
9
+ value = value.call if value.respond_to?(:call)
10
+ value = value.to_s
11
+
9
12
  next if value.blank?
10
13
 
11
14
  attr = attr.to_s.tr("_", ":")
12
- buffer << helpers.tag(:meta, property: "#{base_name}:#{attr}", content: value)
15
+
16
+ buffer << helpers.tag(
17
+ :meta,
18
+ property: "#{base_name}:#{attr}",
19
+ content: value
20
+ )
13
21
  end.join
14
22
  end
15
23
  end
@@ -20,7 +20,7 @@ module PageMeta
20
20
  end
21
21
 
22
22
  def render
23
- helpers.tag(:link, options.merge(rel: rel)) unless options.empty?
23
+ helpers.tag(:link, options.merge(rel:)) unless options.empty?
24
24
  end
25
25
 
26
26
  def helpers
@@ -4,8 +4,15 @@ module PageMeta
4
4
  class MetaTag
5
5
  class DnsPrefetchControl < MetaTag
6
6
  def render
7
- helpers.tag(:meta, "http-equiv" => "x-dns-prefetch-control", content: "on") +
8
- helpers.tag(:link, rel: "dns-prefetch", href: content)
7
+ meta = helpers.tag(
8
+ :meta,
9
+ "http-equiv" => "x-dns-prefetch-control",
10
+ content: "on"
11
+ )
12
+
13
+ link = helpers.tag(:link, rel: "dns-prefetch", href: content)
14
+
15
+ meta + link
9
16
  end
10
17
  end
11
18
  end
@@ -4,8 +4,8 @@ module PageMeta
4
4
  class MetaTag
5
5
  class Language < MetaTag
6
6
  def render
7
- helpers.tag(:meta, name: name, content: content) +
8
- helpers.tag(:meta, itemprop: name, content: content)
7
+ helpers.tag(:meta, name:, content:) +
8
+ helpers.tag(:meta, itemprop: name, content:)
9
9
  end
10
10
  end
11
11
  end
@@ -4,8 +4,7 @@ module PageMeta
4
4
  class MetaTag
5
5
  class Title < MetaTag
6
6
  def render
7
- helpers.content_tag(:title, content.to_s) +
8
- helpers.tag(:meta, name: "DC.title", content: content.simple) +
7
+ helpers.tag(:meta, name: "DC.title", content: content.simple) +
9
8
  helpers.tag(:meta, itemprop: "name", content: content.simple)
10
9
  end
11
10
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module PageMeta
4
4
  class MetaTag
5
- attr_reader :name, :content
5
+ attr_reader :name
6
6
 
7
7
  def self.build(name, content)
8
8
  klass_name = "::PageMeta::MetaTag::#{name.to_s.camelize}"
@@ -16,11 +16,19 @@ module PageMeta
16
16
 
17
17
  def initialize(name, content)
18
18
  @name = name.to_s.dasherize
19
- @content = content
19
+ @raw_content = content
20
+ end
21
+
22
+ def content
23
+ @content ||= if @raw_content.respond_to?(:call)
24
+ @raw_content.call
25
+ else
26
+ @raw_content
27
+ end
20
28
  end
21
29
 
22
30
  def render
23
- helpers.tag(:meta, name: name, content: content) unless content.empty?
31
+ helpers.tag(:meta, name:, content:) unless content.blank?
24
32
  end
25
33
 
26
34
  def helpers
@@ -29,18 +37,18 @@ module PageMeta
29
37
 
30
38
  class MultipleMetaTag < MetaTag
31
39
  def render
32
- return if content.empty?
40
+ return if content.blank?
33
41
 
34
- helpers.tag(:meta, name: name, content: content) +
35
- helpers.tag(:meta, itemprop: name, content: content)
42
+ helpers.tag(:meta, name:, content:) +
43
+ helpers.tag(:meta, itemprop: name, content:)
36
44
  end
37
45
  end
38
46
 
39
47
  class HttpEquiv < MetaTag
40
48
  def render
41
- return if content.empty?
49
+ return if content.blank?
42
50
 
43
- helpers.tag(:meta, "http-equiv" => name, content: content)
51
+ helpers.tag(:meta, "http-equiv" => name, content:)
44
52
  end
45
53
  end
46
54
 
@@ -18,7 +18,7 @@ module PageMeta
18
18
  .class
19
19
  .name
20
20
  .underscore
21
- .gsub(/_controller/, "")
21
+ .gsub("_controller", "")
22
22
  .tr("/", ".")
23
23
  end
24
24
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PageMeta
4
+ class OpenTag
5
+ def self.build(tag, attrs)
6
+ new(tag, attrs)
7
+ end
8
+
9
+ attr_reader :tag, :attrs
10
+
11
+ def initialize(tag, attrs)
12
+ @tag = tag
13
+ @attrs = attrs
14
+ end
15
+
16
+ def render
17
+ helpers.tag(tag, attrs)
18
+ end
19
+
20
+ def helpers
21
+ ActionController::Base.helpers
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PageMeta
4
+ class Tag
5
+ def self.build(tag, content)
6
+ new(tag, content)
7
+ end
8
+
9
+ attr_reader :tag, :content
10
+
11
+ def initialize(tag, content)
12
+ @tag = tag
13
+ @content = content
14
+ end
15
+
16
+ def render
17
+ helpers.content_tag(tag, content) unless content.blank?
18
+ end
19
+
20
+ def helpers
21
+ ActionController::Base.helpers
22
+ end
23
+ end
24
+ end
@@ -14,7 +14,11 @@ module PageMeta
14
14
  end
15
15
 
16
16
  def singular_scope
17
- @singular_scope ||= scope == :keywords ? "keywords" : scope.to_s.singularize
17
+ @singular_scope ||= if scope == :keywords
18
+ "keywords"
19
+ else
20
+ scope.to_s.singularize
21
+ end
18
22
  end
19
23
 
20
24
  def to_s
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PageMeta
4
- VERSION = "1.1.0"
4
+ VERSION = "1.3.0"
5
5
  end
data/lib/page_meta.rb CHANGED
@@ -16,6 +16,8 @@ module PageMeta
16
16
  require "page_meta/meta_tag/twitter"
17
17
  require "page_meta/link"
18
18
  require "page_meta/helpers"
19
+ require "page_meta/tag"
20
+ require "page_meta/open_tag"
19
21
  require "page_meta/action"
20
22
  require "page_meta/naming"
21
23
  require "page_meta/translator"
data/page_meta.gemspec CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |spec|
6
6
  spec.name = "page_meta"
7
7
  spec.version = PageMeta::VERSION
8
8
  spec.authors = ["Nando Vieira"]
9
- spec.email = ["fnando.vieira@gmail.com"]
10
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
9
+ spec.email = ["me@fnando.com"]
10
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.1.0")
11
11
  spec.metadata = {
12
12
  "rubygems_mfa_required" => "true"
13
13
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: page_meta
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-30 00:00:00.000000000 Z
11
+ date: 2024-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -125,7 +125,7 @@ dependencies:
125
125
  description: Easily define <meta> and <link> tags. I18n support for descriptions,
126
126
  keywords and titles.
127
127
  email:
128
- - fnando.vieira@gmail.com
128
+ - me@fnando.com
129
129
  executables: []
130
130
  extensions: []
131
131
  extra_rdoc_files: []
@@ -148,9 +148,9 @@ files:
148
148
  - Rakefile
149
149
  - bin/console
150
150
  - bin/setup
151
- - gemfiles/6_0.gemfile
152
151
  - gemfiles/6_1.gemfile
153
152
  - gemfiles/7_0.gemfile
153
+ - gemfiles/7_1.gemfile
154
154
  - lib/page_meta.rb
155
155
  - lib/page_meta/action.rb
156
156
  - lib/page_meta/base.rb
@@ -165,7 +165,9 @@ files:
165
165
  - lib/page_meta/meta_tag/title.rb
166
166
  - lib/page_meta/meta_tag/twitter.rb
167
167
  - lib/page_meta/naming.rb
168
+ - lib/page_meta/open_tag.rb
168
169
  - lib/page_meta/railtie.rb
170
+ - lib/page_meta/tag.rb
169
171
  - lib/page_meta/translator.rb
170
172
  - lib/page_meta/version.rb
171
173
  - page_meta.gemspec
@@ -182,14 +184,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
184
  requirements:
183
185
  - - ">="
184
186
  - !ruby/object:Gem::Version
185
- version: 2.7.0
187
+ version: 3.1.0
186
188
  required_rubygems_version: !ruby/object:Gem::Requirement
187
189
  requirements:
188
190
  - - ">="
189
191
  - !ruby/object:Gem::Version
190
192
  version: '0'
191
193
  requirements: []
192
- rubygems_version: 3.4.5
194
+ rubygems_version: 3.5.9
193
195
  signing_key:
194
196
  specification_version: 4
195
197
  summary: Easily define <meta> and <link> tags. I18n support for descriptions, keywords