jekyll-seo-tags 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 111f5c485757cf0df3d7ebac072d9fff3ea8de9920f45270f0fb498dd377c6f8
4
+ data.tar.gz: c08f1ba3a1d3b61d484d59d22fbf4d378cea5e4392b0a2e7c84e7c8051067334
5
+ SHA512:
6
+ metadata.gz: 57ec9d4d05326a970b60d7c3f247f1d8787eed62a6d5d207cafa343e3f9b99b7e3b8a8a746b0c2990680ca3addda84674e597fa131215086fce5f5577fcb3e80
7
+ data.tar.gz: aea64cd4453bbe330a1a0fc4271667fd83dac09d3d7df56e8ab159a16f13339d738c225847720ecb407d7e854acb23e010fdf8bbbeb51a225d0be11a38ef9d97
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ .bundle
3
+ .yardoc
4
+ Gemfile.lock
5
+ pkg
6
+ spec/reports/
7
+ spec/fixtures/.jekyll-cache
8
+ tmp/
9
+ vendor/bundle
@@ -0,0 +1,17 @@
1
+ require: rubocop-jekyll
2
+ inherit_gem:
3
+ rubocop-jekyll: .rubocop.yml
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.4
7
+ Exclude:
8
+ - vendor/**/*
9
+
10
+ Layout/LineLength:
11
+ Exclude:
12
+ - spec/**/*
13
+ - jekyll-seo-tags.gemspec
14
+
15
+ Metrics/BlockLength:
16
+ Exclude:
17
+ - spec/**/*
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "jekyll", ENV["JEKYLL_VERSION"] if ENV["JEKYLL_VERSION"]
6
+ gem "kramdown-parser-gfm" if ENV["JEKYLL_VERSION"] == "~> 3.9"
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Julien Guittard
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ # jekyll-seo
@@ -0,0 +1,32 @@
1
+ require_relative "lib/jekyll-seo-tags/version"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "jekyll-seo-tags"
5
+ spec.version = Jekyll::SeoTags::VERSION
6
+ spec.authors = ["Julien Guittard"]
7
+ spec.email = ["julien.guittard@me.com"]
8
+ spec.summary = "A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content."
9
+ spec.homepage = "https://github.com/jguittard/jekyll-seo-tags"
10
+ spec.license = "MIT"
11
+
12
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
13
+ # delete this section to allow pushing this gem to any host.
14
+ if spec.respond_to?(:metadata)
15
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
+ else
17
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
18
+ end
19
+
20
+ spec.required_ruby_version = ">= 2.4.0"
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|spec|features)/!) }
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r!^exe/!) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_dependency "jekyll", ">= 3.8", "< 5.0"
28
+ spec.add_development_dependency "bundler", ">= 1.15"
29
+ spec.add_development_dependency "html-proofer", "~> 3.7"
30
+ spec.add_development_dependency "rspec", "~> 3.5"
31
+ spec.add_development_dependency "rubocop-jekyll", "~> 0.11"
32
+ end
@@ -0,0 +1,91 @@
1
+ module Jekyll
2
+ class SeoTags
3
+ # A drop representing the current page's author
4
+ #
5
+ # Author name will be pulled from:
6
+ #
7
+ # 1. The page's `author` key
8
+ # 2. The first author in the page's `authors` key
9
+ # 3. The `author` key in the site config
10
+ #
11
+ # If the result from the name search is a string, we'll also check
12
+ # for additional author metadata in `site.data.authors`
13
+ class AuthorDrop < Jekyll::Drops::Drop
14
+ # Initialize a new AuthorDrop
15
+ #
16
+ # page - The page hash (e.g., Page#to_liquid)
17
+ # site - The Jekyll::Drops::SiteDrop
18
+ def initialize(page: nil, site: nil)
19
+ raise ArgumentError unless page && site
20
+
21
+ @mutations = {}
22
+ @page = page
23
+ @site = site
24
+ end
25
+
26
+ # AuthorDrop#to_s should return name, allowing the author drop to safely
27
+ # replace `page.author`, if necessary, and remain backwards compatible
28
+ def name
29
+ author_hash["name"]
30
+ end
31
+ alias_method :to_s, :name
32
+
33
+ def twitter
34
+ return @twitter if defined? @twitter
35
+
36
+ twitter = author_hash["twitter"] || author_hash["name"]
37
+ @twitter = twitter.is_a?(String) ? twitter.sub(%r!^@!, "") : nil
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :page
43
+ attr_reader :site
44
+
45
+ # Finds the page author in the page.author, page.authors, or site.author
46
+ #
47
+ # Returns a string or hash representing the author
48
+ def resolved_author
49
+ return @resolved_author if defined? @resolved_author
50
+
51
+ sources = [page["author"]]
52
+ sources << page["authors"].first if page["authors"].is_a?(Array)
53
+ sources << site["author"]
54
+ @resolved_author = sources.find { |s| !s.to_s.empty? }
55
+ end
56
+
57
+ # If resolved_author is a string, attempts to find coresponding author
58
+ # metadata in `site.data.authors`
59
+ #
60
+ # Returns a hash representing additional metadata or an empty hash
61
+ def site_data_hash
62
+ @site_data_hash ||= begin
63
+ return {} unless resolved_author.is_a?(String)
64
+ return {} unless site.data["authors"].is_a?(Hash)
65
+
66
+ author_hash = site.data["authors"][resolved_author]
67
+ author_hash.is_a?(Hash) ? author_hash : {}
68
+ end
69
+ end
70
+
71
+ # Returns the normalized author hash representing the page author,
72
+ # including site-wide metadata if the author is provided as a string,
73
+ # or an empty hash, if the author cannot be resolved
74
+ def author_hash
75
+ @author_hash ||= begin
76
+ if resolved_author.is_a? Hash
77
+ resolved_author
78
+ elsif resolved_author.is_a? String
79
+ { "name" => resolved_author }.merge!(site_data_hash)
80
+ else
81
+ {}
82
+ end
83
+ end
84
+ end
85
+
86
+ # Since author_hash is aliased to fallback_data, any values in the hash
87
+ # will be exposed via the drop, allowing support for arbitrary metadata
88
+ alias_method :fallback_data, :author_hash
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,226 @@
1
+ module Jekyll
2
+ class SeoTag
3
+ class Drop < Jekyll::Drops::Drop
4
+ include Jekyll::SeoTags::UrlHelper
5
+
6
+ TITLE_SEPARATOR = " | "
7
+ FORMAT_STRING_METHODS = [
8
+ :markdownify, :strip_html, :normalize_whitespace, :escape_once,
9
+ ].freeze
10
+ HOMEPAGE_OR_ABOUT_REGEX = %r!^/(about/)?(index.html?)?$!.freeze
11
+
12
+ EMPTY_READ_ONLY_HASH = {}.freeze
13
+ private_constant :EMPTY_READ_ONLY_HASH
14
+
15
+ def initialize(text, context)
16
+ @obj = EMPTY_READ_ONLY_HASH
17
+ @mutations = {}
18
+ @text = text
19
+ @context = context
20
+ end
21
+
22
+ def version
23
+ Jekyll::SeoTags::VERSION
24
+ end
25
+
26
+ # Should the `<title>` tag be generated for this page?
27
+ def title?
28
+ return false unless title
29
+ return @display_title if defined?(@display_title)
30
+
31
+ @display_title = (@text !~ %r!title=false!i)
32
+ end
33
+
34
+ def site_title
35
+ @site_title ||= format_string(site["title"] || site["name"])
36
+ end
37
+
38
+ def site_tagline
39
+ @site_tagline ||= format_string site["tagline"]
40
+ end
41
+
42
+ def site_description
43
+ @site_description ||= format_string site["description"]
44
+ end
45
+
46
+ # Page title without site title or description appended
47
+ def page_title
48
+ @page_title ||= format_string(page["title"]) || site_title
49
+ end
50
+
51
+ def site_tagline_or_description
52
+ site_tagline || site_description
53
+ end
54
+
55
+ # Page title with site title or description appended
56
+ # rubocop:disable Metrics/CyclomaticComplexity
57
+ def title
58
+ @title ||= begin
59
+ if site_title && page_title != site_title
60
+ page_title + TITLE_SEPARATOR + site_title
61
+ elsif site_description && site_title
62
+ site_title + TITLE_SEPARATOR + site_tagline_or_description
63
+ else
64
+ page_title || site_title
65
+ end
66
+ end
67
+
68
+ return page_number + @title if page_number
69
+
70
+ @title
71
+ end
72
+ # rubocop:enable Metrics/CyclomaticComplexity
73
+
74
+ def name
75
+ return @name if defined?(@name)
76
+
77
+ @name = if seo_name
78
+ seo_name
79
+ elsif !homepage_or_about?
80
+ nil
81
+ elsif site_social["name"]
82
+ format_string site_social["name"]
83
+ elsif site_title
84
+ site_title
85
+ end
86
+ end
87
+
88
+ def description
89
+ @description ||= begin
90
+ format_string(page["description"] || page["excerpt"]) || site_description
91
+ end
92
+ end
93
+
94
+ # A drop representing the page author
95
+ def author
96
+ @author ||= AuthorDrop.new(:page => page, :site => site)
97
+ end
98
+
99
+ # Returns a Drop representing the page's image
100
+ # Returns nil if the image has no path, to preserve backwards compatibility
101
+ def image
102
+ @image ||= ImageDrop.new(:page => page, :context => @context)
103
+ @image if @image.path
104
+ end
105
+
106
+ def date_modified
107
+ @date_modified ||= begin
108
+ date = page_seo["date_modified"] || page["last_modified_at"].to_liquid || page["date"]
109
+ filters.date_to_xmlschema(date) if date
110
+ end
111
+ end
112
+
113
+ def date_published
114
+ @date_published ||= filters.date_to_xmlschema(page["date"]) if page["date"]
115
+ end
116
+
117
+ def links
118
+ @links ||= begin
119
+ if page_seo["links"]
120
+ page_seo["links"]
121
+ elsif homepage_or_about? && site_social["links"]
122
+ site_social["links"]
123
+ end
124
+ end
125
+ end
126
+
127
+ def logo
128
+ @logo ||= begin
129
+ return unless site["logo"]
130
+
131
+ if absolute_url? site["logo"]
132
+ filters.uri_escape site["logo"]
133
+ else
134
+ filters.uri_escape filters.absolute_url site["logo"]
135
+ end
136
+ end
137
+ end
138
+
139
+ def page_lang
140
+ @page_lang ||= page["lang"] || site["lang"] || "en_US"
141
+ end
142
+
143
+ def page_locale
144
+ @page_locale ||= (page["locale"] || site["locale"] || page_lang).tr("-", "_")
145
+ end
146
+
147
+ def canonical_url
148
+ @canonical_url ||= begin
149
+ if page["canonical_url"].to_s.empty?
150
+ filters.absolute_url(page["url"]).to_s.gsub(%r!/index\.html$!, "/")
151
+ else
152
+ page["canonical_url"]
153
+ end
154
+ end
155
+ end
156
+
157
+ private
158
+
159
+ def filters
160
+ @filters ||= Jekyll::SeoTags::Filters.new(@context)
161
+ end
162
+
163
+ def page
164
+ @page ||= @context.registers[:page].to_liquid
165
+ end
166
+
167
+ def site
168
+ @site ||= @context.registers[:site].site_payload["site"].to_liquid
169
+ end
170
+
171
+ def homepage_or_about?
172
+ page["url"] =~ HOMEPAGE_OR_ABOUT_REGEX
173
+ end
174
+
175
+ def page_number
176
+ return unless @context["paginator"] && @context["paginator"]["page"]
177
+
178
+ current = @context["paginator"]["page"]
179
+ total = @context["paginator"]["total_pages"]
180
+ paginator_message = site["seo_paginator_message"] || "Page %<current>s of %<total>s for "
181
+
182
+ format(paginator_message, :current => current, :total => total) if current > 1
183
+ end
184
+
185
+ attr_reader :context
186
+
187
+ def fallback_data
188
+ @fallback_data ||= {}
189
+ end
190
+
191
+ def format_string(string)
192
+ string = FORMAT_STRING_METHODS.reduce(string) do |memo, method|
193
+ filters.public_send(method, memo)
194
+ end
195
+
196
+ string unless string.empty?
197
+ end
198
+
199
+ def seo_name
200
+ @seo_name ||= format_string(page_seo["name"]) if page_seo["name"]
201
+ end
202
+
203
+ def page_seo
204
+ @page_seo ||= sub_hash(page, "seo")
205
+ end
206
+
207
+ def site_social
208
+ @site_social ||= sub_hash(site, "social")
209
+ end
210
+
211
+ # Safely returns a sub hash
212
+ #
213
+ # hash - the parent hash
214
+ # key - the key in the parent hash
215
+ #
216
+ # Returns the sub hash or an empty hash, if it does not exist
217
+ def sub_hash(hash, key)
218
+ if hash[key].is_a?(Hash)
219
+ hash[key]
220
+ else
221
+ EMPTY_READ_ONLY_HASH
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,12 @@
1
+ module Jekyll
2
+ class SeoTags
3
+ class Filters
4
+ include Jekyll::Filters
5
+ include Liquid::StandardFilters
6
+
7
+ def initialize(context)
8
+ @context = context
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,76 @@
1
+ module Jekyll
2
+ class SeoTags
3
+ # A drop representing the page image
4
+ # The image path will be pulled from:
5
+ #
6
+ # 1. The `image` key if it's a string
7
+ # 2. The `image.path` key if it's a hash
8
+ # 3. The `image.facebook` key
9
+ # 4. The `image.twitter` key
10
+ class ImageDrop < Jekyll::Drops::Drop
11
+ include Jekyll::SeoTags::UrlHelper
12
+
13
+ # Initialize a new ImageDrop
14
+ #
15
+ # page - The page hash (e.g., Page#to_liquid)
16
+ # context - the Liquid::Context
17
+ def initialize(page: nil, context: nil)
18
+ raise ArgumentError unless page && context
19
+
20
+ @mutations = {}
21
+ @page = page
22
+ @context = context
23
+ end
24
+
25
+ # Called path for backwards compatability, this is really
26
+ # the escaped, absolute URL representing the page's image
27
+ # Returns nil if no image path can be determined
28
+ def path
29
+ @path ||= filters.uri_escape(absolute_url) if absolute_url
30
+ end
31
+ alias_method :to_s, :path
32
+
33
+ private
34
+
35
+ attr_accessor :page
36
+ attr_accessor :context
37
+
38
+ # The normalized image hash with a `path` key (which may be nil)
39
+ def image_hash
40
+ @image_hash ||= begin
41
+ image_meta = page["image"]
42
+
43
+ if image_meta.is_a?(Hash)
44
+ { "path" => nil }.merge!(image_meta)
45
+ elsif image_meta.is_a?(String)
46
+ { "path" => image_meta }
47
+ else
48
+ { "path" => nil }
49
+ end
50
+ end
51
+ end
52
+ alias_method :fallback_data, :image_hash
53
+
54
+ def raw_path
55
+ @raw_path ||= begin
56
+ image_hash["path"] || image_hash["facebook"] || image_hash["twitter"]
57
+ end
58
+ end
59
+
60
+ def absolute_url
61
+ return unless raw_path
62
+ return @absolute_url if defined? @absolute_url
63
+
64
+ @absolute_url = if raw_path.is_a?(String) && absolute_url?(raw_path) == false
65
+ filters.absolute_url raw_path
66
+ else
67
+ raw_path
68
+ end
69
+ end
70
+
71
+ def filters
72
+ @filters ||= Jekyll::SeoTags::Filters.new(context)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,21 @@
1
+ module Jekyll
2
+ class SeoTags
3
+ # Mixin to share common URL-related methods between class
4
+ module UrlHelper
5
+ private
6
+
7
+ # Determines if the given string is an absolute URL
8
+ #
9
+ # Returns true if an absolute URL.
10
+ # Retruns false if it's a relative URL
11
+ # Returns nil if it is not a string or can't be parsed as a URL
12
+ def absolute_url?(string)
13
+ return unless string
14
+
15
+ Addressable::URI.parse(string).absolute?
16
+ rescue Addressable::URI::InvalidURIError
17
+ nil
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module Liquid; class Tag; end; end
2
+
3
+ module Jekyll
4
+ class SeoTags < Liquid::Tag
5
+ VERSION = "1.0.0"
6
+ end
7
+ end
@@ -0,0 +1,90 @@
1
+ require "jekyll"
2
+ require "jekyll-seo-tags/version"
3
+
4
+ module Jekyll
5
+ class SeoTags < Liquid::Tag
6
+ autoload :AuthorDrop, "jekyll-seo-tags/author_drop"
7
+ autoload :ImageDrop, "jekyll-seo-tags/image_drop"
8
+ autoload :UrlHelper, "jekyll-seo-tags/url_helper"
9
+ autoload :Drop, "jekyll-seo-tags/drop"
10
+ autoload :Filters, "jekyll-seo-tags/filters"
11
+
12
+ attr_accessor :context
13
+
14
+ # Matches all whitespace that follows either
15
+ # 1. A '}', which closes a Liquid tag
16
+ # 2. A '{', which opens a JSON block
17
+ # 3. A '>' followed by a newline, which closes an XML tag or
18
+ # 4. A ',' followed by a newline, which ends a JSON line
19
+ # We will strip all of this whitespace to minify the template
20
+ # We will not strip any whitespace if the next character is a '-'
21
+ # so that we do not interfere with the HTML comment at the
22
+ # very begining
23
+ MINIFY_REGEX = %r!(?<=[{}]|[>,]\n)\s+(?\!-)!.freeze
24
+
25
+ def initialize(_tag_name, text, _tokens)
26
+ super
27
+ @text = text
28
+ end
29
+
30
+ def render(context)
31
+ @context = context
32
+ SeoTags.template.render!(payload, info)
33
+ end
34
+
35
+ private
36
+
37
+ def options
38
+ {
39
+ "version" => Jekyll::SeoTags::VERSION,
40
+ "title" => title?,
41
+ }
42
+ end
43
+
44
+ def payload
45
+ # site_payload is an instance of UnifiedPayloadDrop. See https://git.io/v5ajm
46
+ context.registers[:site].site_payload.tap do |site_payload|
47
+ site_payload["page"] = context.registers[:page]
48
+ site_payload["paginator"] = context["paginator"]
49
+ site_payload["seo_tags"] = drop
50
+ end
51
+ end
52
+
53
+ def drop
54
+ if context.registers[:site].liquid_renderer.respond_to?(:cache)
55
+ Jekyll::SeoTags::Drop.new(@text, @context)
56
+ else
57
+ @drop ||= Jekyll::SeoTags::Drop.new(@text, @context)
58
+ end
59
+ end
60
+
61
+ def info
62
+ {
63
+ :registers => context.registers,
64
+ :filters => [Jekyll::Filters],
65
+ }
66
+ end
67
+
68
+ class << self
69
+ def template
70
+ @template ||= Liquid::Template.parse template_contents
71
+ end
72
+
73
+ private
74
+
75
+ def template_contents
76
+ @template_contents ||= begin
77
+ File.read(template_path).gsub(MINIFY_REGEX, "")
78
+ end
79
+ end
80
+
81
+ def template_path
82
+ @template_path ||= begin
83
+ File.expand_path "./template.html", File.dirname(__FILE__)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ Liquid::Template.register_tag("seo", Jekyll::SeoTags)
@@ -0,0 +1,108 @@
1
+ {% if seo_tag.title? %}
2
+ <title>{{ seo_tag.title }}</title>
3
+ {% endif %}
4
+
5
+ <meta name="generator" content="Jekyll v{{ jekyll.version }}" />
6
+
7
+ {% if seo_tag.page_title %}
8
+ <meta property="og:title" content="{{ seo_tag.page_title }}" />
9
+ {% endif %}
10
+
11
+ {% if seo_tag.author.name %}
12
+ <meta name="author" content="{{ seo_tag.author.name }}" />
13
+ {% endif %}
14
+
15
+ <meta property="og:locale" content="{{ seo_tag.page_locale }}" />
16
+
17
+ {% if seo_tag.description %}
18
+ <meta name="description" content="{{ seo_tag.description }}" />
19
+ <meta property="og:description" content="{{ seo_tag.description }}" />
20
+ {% endif %}
21
+
22
+ {% if site.url %}
23
+ <link rel="canonical" href="{{ seo_tag.canonical_url }}" />
24
+ <meta property="og:url" content="{{ seo_tag.canonical_url }}" />
25
+ {% endif %}
26
+
27
+ {% if seo_tag.site_title %}
28
+ <meta property="og:site_name" content="{{ seo_tag.site_title }}" />
29
+ {% endif %}
30
+
31
+ {% if seo_tag.image %}
32
+ <meta property="og:image" content="{{ seo_tag.image.path }}" />
33
+ {% if seo_tag.image.height %}
34
+ <meta property="og:image:height" content="{{ seo_tag.image.height }}" />
35
+ {% endif %}
36
+ {% if seo_tag.image.width %}
37
+ <meta property="og:image:width" content="{{ seo_tag.image.width }}" />
38
+ {% endif %}
39
+ {% endif %}
40
+
41
+ {% if page.date %}
42
+ <meta property="og:type" content="article" />
43
+ <meta property="article:published_time" content="{{ page.date | date_to_xmlschema }}" />
44
+ {% endif %}
45
+
46
+ {% if paginator.previous_page %}
47
+ <link rel="prev" href="{{ paginator.previous_page_path | absolute_url }}" />
48
+ {% endif %}
49
+ {% if paginator.next_page %}
50
+ <link rel="next" href="{{ paginator.next_page_path | absolute_url }}" />
51
+ {% endif %}
52
+
53
+ {% if seo_tag.image %}
54
+ <meta name="twitter:card" content="{{ page.twitter.card | default: site.twitter.card | default: "summary_large_image" }}" />
55
+ <meta property="twitter:image" content="{{ seo_tag.image.path }}" />
56
+ {% else %}
57
+ <meta name="twitter:card" content="summary" />
58
+ {% endif %}
59
+
60
+ {% if seo_tag.page_title %}
61
+ <meta property="twitter:title" content="{{ seo_tag.page_title }}" />
62
+ {% endif %}
63
+
64
+ {% if site.twitter %}
65
+ <meta name="twitter:site" content="@{{ site.twitter.username | remove:'@' }}" />
66
+
67
+ {% if seo_tag.author.twitter %}
68
+ <meta name="twitter:creator" content="@{{ seo_tag.author.twitter | remove:'@' }}" />
69
+ {% endif %}
70
+ {% endif %}
71
+
72
+ {% if site.facebook %}
73
+ {% if site.facebook.admins %}
74
+ <meta property="fb:admins" content="{{ site.facebook.admins }}" />
75
+ {% endif %}
76
+
77
+ {% if site.facebook.publisher %}
78
+ <meta property="article:publisher" content="{{ site.facebook.publisher }}" />
79
+ {% endif %}
80
+
81
+ {% if site.facebook.app_id %}
82
+ <meta property="fb:app_id" content="{{ site.facebook.app_id }}" />
83
+ {% endif %}
84
+ {% endif %}
85
+
86
+ {% if site.webmaster_verifications %}
87
+ {% if site.webmaster_verifications.google %}
88
+ <meta name="google-site-verification" content="{{ site.webmaster_verifications.google }}" />
89
+ {% endif %}
90
+
91
+ {% if site.webmaster_verifications.bing %}
92
+ <meta name="msvalidate.01" content="{{ site.webmaster_verifications.bing }}" />
93
+ {% endif %}
94
+
95
+ {% if site.webmaster_verifications.alexa %}
96
+ <meta name="alexaVerifyID" content="{{ site.webmaster_verifications.alexa }}" />
97
+ {% endif %}
98
+
99
+ {% if site.webmaster_verifications.yandex %}
100
+ <meta name="yandex-verification" content="{{ site.webmaster_verifications.yandex }}" />
101
+ {% endif %}
102
+
103
+ {% if site.webmaster_verifications.baidu %}
104
+ <meta name="baidu-site-verification" content="{{ site.webmaster_verifications.baidu }}" />
105
+ {% endif %}
106
+ {% elsif site.google_site_verification %}
107
+ <meta name="google-site-verification" content="{{ site.google_site_verification }}" />
108
+ {% endif %}
@@ -0,0 +1,38 @@
1
+ #!/bin/sh
2
+ # Tag and push a release.
3
+
4
+ set -e
5
+
6
+ # Make sure we're in the project root.
7
+
8
+ cd $(dirname "$0")/..
9
+
10
+ # Build a new gem archive.
11
+
12
+ rm -rf jekyll-seo-tag-*.gem
13
+ gem build -q jekyll-seo-tags.gemspec
14
+
15
+ # Make sure we're on the master branch.
16
+
17
+ (git branch | grep -q '* master') || {
18
+ echo "Only release from the master branch."
19
+ exit 1
20
+ }
21
+
22
+ # Figure out what version we're releasing.
23
+
24
+ tag=v`ls jekyll-seo-tags-*.gem | sed 's/^jekyll-seo-tag-\(.*\)\.gem$/\1/'`
25
+
26
+ # Make sure we haven't released this version before.
27
+
28
+ git fetch -t origin
29
+
30
+ (git tag -l | grep -q "$tag") && {
31
+ echo "Whoops, there's already a '${tag}' tag."
32
+ exit 1
33
+ }
34
+
35
+ # Tag it and bag it.
36
+
37
+ gem push jekyll-seo-tags-*.gem && git tag "$tag" &&
38
+ git push origin master && git push origin "$tag"
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-seo-tags
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Julien Guittard
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-01-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.8'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.8'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '1.15'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '1.15'
47
+ - !ruby/object:Gem::Dependency
48
+ name: html-proofer
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.7'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.7'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.5'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.5'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rubocop-jekyll
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.11'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.11'
89
+ description:
90
+ email:
91
+ - julien.guittard@me.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - ".gitignore"
97
+ - ".rubocop.yml"
98
+ - Gemfile
99
+ - LICENSE
100
+ - README.md
101
+ - jekyll-seo-tags.gemspec
102
+ - lib/jekyll-seo-tags/author_drop.rb
103
+ - lib/jekyll-seo-tags/drop.rb
104
+ - lib/jekyll-seo-tags/filters.rb
105
+ - lib/jekyll-seo-tags/image_drop.rb
106
+ - lib/jekyll-seo-tags/url_helper.rb
107
+ - lib/jekyll-seo-tags/version.rb
108
+ - lib/jekyll_seo_tags.rb
109
+ - lib/template.html
110
+ - scripts/release
111
+ homepage: https://github.com/jguittard/jekyll-seo-tags
112
+ licenses:
113
+ - MIT
114
+ metadata:
115
+ allowed_push_host: https://rubygems.org
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 2.4.0
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubygems_version: 3.2.7
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: A Jekyll plugin to add metadata tags for search engines and social networks
135
+ to better index and display your site's content.
136
+ test_files: []