jekyll-seo-tags 1.0.0

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