jekyll-seo-tag-2.6.1/ 0000755 0000041 0000041 00000000000 13514322475 014405 5 ustar www-data www-data jekyll-seo-tag-2.6.1/docs/ 0000755 0000041 0000041 00000000000 13514322475 015335 5 ustar www-data www-data jekyll-seo-tag-2.6.1/docs/advanced-usage.md 0000644 0000041 0000041 00000013312 13514322475 020526 0 ustar www-data www-data ## Advanced usage
Jekyll SEO Tag is designed to implement SEO best practices by default and to be the right fit for most sites right out of the box. If for some reason, you need more control over the output, read on:
### Disabling `
` output
If for some reason, you don't want the plugin to output `` tags on each page, simply invoke the plugin within your template like so:
```
{% seo title=false %}
```
### Author information
Author information is used to propagate the `creator` field of Twitter summary cards. This should be an author-specific, not site-wide Twitter handle (the site-wide username be stored as `site.twitter.username`).
*TL;DR: In most cases, put `author: [your Twitter handle]` in the document's front matter, for sites with multiple authors. If you need something more complicated, read on.*
There are several ways to convey this author-specific information. Author information is found in the following order of priority:
1. An `author` object, in the documents's front matter, e.g.:
```yml
author:
twitter: benbalter
```
2. An `author` object, in the site's `_config.yml`, e.g.:
```yml
author:
twitter: benbalter
```
3. `site.data.authors[author]`, if an author is specified in the document's front matter, and a corresponding key exists in `site.data.authors`. E.g., you have the following in the document's front matter:
```yml
author: benbalter
```
And you have the following in `_data/authors.yml`:
```yml
benbalter:
picture: /img/benbalter.png
twitter: jekyllrb
potus:
picture: /img/potus.png
twitter: whitehouse
```
In the above example, the author `benbalter`'s Twitter handle will be resolved to `@jekyllrb`. This allows you to centralize author information in a single `_data/authors` file for site with many authors that require more than just the author's username.
*Pro-tip: If `authors` is present in the document's front matter as an array (and `author` is not), the plugin will use the first author listed, as Twitter supports only one author.*
4. An author in the document's front matter (the simplest way), e.g.:
```yml
author: benbalter
```
5. An author in the site's `_config.yml`, e.g.:
```yml
author: benbalter
```
### Customizing JSON-LD output
The following options can be set for any particular page. While the default options are meant to serve most users in the most common circumstances, there may be situations where more precise control is necessary.
* `seo`
* `name` - If the name of the thing that the page represents is different from the page title. (i.e.: "Frank's Café" vs "Welcome to Frank's Café")
* `type` - The type of things that the page represents. This must be a [Schema.org type](http://schema.org/docs/schemas.html), and will probably usually be something like [`BlogPosting`](http://schema.org/BlogPosting), [`NewsArticle`](http://schema.org/NewsArticle), [`Person`](http://schema.org/Person), [`Organization`](http://schema.org/Organization), etc.
* `links` - An array of other URLs that represent the same thing that this page represents. For instance, Jane's bio page might include links to Jane's GitHub and Twitter profiles.
* `date_modified` - Manually specify the `dateModified` field in the JSON-LD output to override Jekyll's own `dateModified`.
This field will take **first priority** for the `dateModified` JSON-LD output. This is useful when the file timestamp does not match the true time that the content was modified. A user may also install [Last Modified At](https://github.com/gjtorikian/jekyll-last-modified-at) which will offer an alternative way of providing for the `dateModified` field.
### Customizing image output
For most users, setting `image: [path-to-image]` on a per-page basis should be enough. If you need more control over how images are represented, the `image` property can also be an object, with the following options:
* `path` - The relative path to the image. Same as `image: [path-to-image]`
* `height` - The height of the Open Graph (`og:image`) image
* `width` - The width of the Open Graph (`og:image`) image
You can use any of the above, optional properties, like so:
```yml
image:
path: /img/twitter.png
height: 100
width: 100
```
### Setting a default image
You can define a default image using [Front Matter default](https://jekyllrb.com/docs/configuration/#front-matter-defaults), to provide a default Twitter Card or OGP image to all of your posts and pages.
Here is a very basic example, that you are encouraged to adapt to your needs:
```yml
defaults:
- scope:
path: ""
values:
image: /assets/images/default-card.png
```
### SmartyPants Titles
Titles will be processed using [Jekyll's `smartify` filter](https://jekyllrb.com/docs/templates/). This will use SmartyPants to translate plain ASCII punctuation into "smart" typographic punctuation. This will not render or strip any Markdown you may be using in a page title.
### Setting customized Canonical URL
You can set custom Canonical URL for a page by specifying canonical_url option in page front-matter.
E.g., you have the following in the page's front matter:
```yml
layout: post
title: Title of Your Post
canonical_url: 'https://github.com/jekyll/jekyll-seo-tag/'
```
Which will generate canonical_url with specified link in canonical_url.
```html
```
If no canonical_url option was specified, then uses page url for generating canonical_url.
E.g., you have not specified canonical_url in front-matter:
```yml
layout: post
title: Title of Your Post
```
Which will generate following canonical_url:
```html
```
jekyll-seo-tag-2.6.1/docs/README.md 0000644 0000041 0000041 00000003260 13514322475 016615 0 ustar www-data www-data ## About Jekyll SEO Tag
A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content.
[](https://badge.fury.io/rb/jekyll-seo-tag) [](https://travis-ci.org/jekyll/jekyll-seo-tag)
## What it does
Jekyll SEO Tag adds the following meta tags to your site:
* Page title, with site title or description appended
* Page description
* Canonical URL
* Next and previous URLs on paginated pages
* [JSON-LD Site and post metadata](https://developers.google.com/structured-data/) for richer indexing
* [Open Graph](http://ogp.me/) title, description, site title, and URL (for Facebook, LinkedIn, etc.)
* [Twitter Summary Card](https://dev.twitter.com/cards/overview) metadata
While you could theoretically add the necessary metadata tags yourself, Jekyll SEO Tag provides a battle-tested template of crowdsourced best-practices.
## What it doesn't do
Jekyll SEO tag is designed to output machine-readable metadata for search engines and social networks to index and display. If you're looking for something to analyze your Jekyll site's structure and content (e.g., more traditional SEO optimization), take a look at [The Jekyll SEO Gem](https://github.com/pmarsceill/jekyll-seo-gem).
Jekyll SEO tag isn't designed to accommodate every possible use case. It should work for most site out of the box and without a laundry list of configuration options that serve only to confuse most users.
## Documentation
For more information, see:
* [Installation](installation.md)
* [Usage](usage.md)
* [Advanced usage](advanced-usage.md)
jekyll-seo-tag-2.6.1/docs/_layouts/ 0000755 0000041 0000041 00000000000 13514322475 017174 5 ustar www-data www-data jekyll-seo-tag-2.6.1/docs/_layouts/default.html 0000644 0000041 0000041 00000001052 13514322475 021504 0 ustar www-data www-data
{% seo %}
{{ site.title }}
{{ content }}
jekyll-seo-tag-2.6.1/docs/usage.md 0000644 0000041 0000041 00000006257 13514322475 016775 0 ustar www-data www-data ## Usage
The SEO tag will respect any of the following if included in your site's `_config.yml` (and simply not include them if they're not defined):
* `title` - Your site's title (e.g., Ben's awesome site, The GitHub Blog, etc.)
* `description` - A short description (e.g., A blog dedicated to reviewing cat gifs)
* `url` - The full URL to your site. Note: `site.github.url` will be used by default.
* `author` - global author information (see [Advanced usage](advanced-usage.md#author-information))
* `twitter` - The following properties are available:
* `twitter:card` - The site's default card type
* `twitter:username` - The site's Twitter handle. You'll want to describe it like so:
```yml
twitter:
username: benbalter
card: summary
```
* `facebook` - The following properties are available:
* `facebook:app_id` - a Facebook app ID for Facebook insights
* `facebook:publisher` - a Facebook page URL or ID of the publishing entity
* `facebook:admins` - a Facebook user ID for domain insights linked to a personal account
You'll want to describe one or more like so:
```yml
facebook:
app_id: 1234
publisher: 1234
admins: 1234
```
* `logo` - URL to a site-wide logo (e.g., `/assets/your-company-logo.png`) - If you would like the "publisher" property to be present, you must add this field to your site's configuration, during the validation of the structured data by Google web master tools, if the `logo` field is not validated, you will find errors inherent to the publisher in the [structured datas test](https://search.google.com/structured-data/testing-tool/u/0/)
* `social` - For [specifying social profiles](https://developers.google.com/structured-data/customize/social-profiles). The following properties are available:
* `name` - If the user or organization name differs from the site's name
* `links` - An array of links to social media profiles.
```yml
social:
name: Ben Balter
links:
- https://twitter.com/BenBalter
- https://www.facebook.com/ben.balter
- https://www.linkedin.com/in/BenBalter
- https://plus.google.com/+BenBalter
- https://github.com/benbalter
- https://keybase.io/benbalter
```
* `google_site_verification` for verifying ownership via Google webmaster tools
* Alternatively, verify ownership with several services at once using the following format:
```yml
webmaster_verifications:
google: 1234
bing: 1234
alexa: 1234
yandex: 1234
baidu: 1234
```
* `lang` - The locale these tags are marked up in. Of the format `language_TERRITORY`. Default is `en_US`.
The SEO tag will respect the following YAML front matter if included in a post, page, or document:
* `title` - The title of the post, page, or document
* `description` - A short description of the page's content
* `image` - URL to an image associated with the post, page, or document (e.g., `/assets/page-pic.jpg`)
* `author` - Page-, post-, or document-specific author information (see [Advanced usage](advanced-usage.md#author-information))
* `lang` - Page-, post-, or document-specific language information
*Note:* Front matter defaults can be used for any of the above values as described in advanced usage with an image example.
jekyll-seo-tag-2.6.1/docs/installation.md 0000644 0000041 0000041 00000000710 13514322475 020356 0 ustar www-data www-data # Installing Jekyll SEO Tag
1. Add the following to your site's `Gemfile`:
```ruby
gem 'jekyll-seo-tag'
```
2. Add the following to your site's `_config.yml`:
```yml
plugins:
- jekyll-seo-tag
```
If you are using a Jekyll version less than `3.5.0`, use the `gems` key instead of `plugins`.
3. Add the following right before `` in your site's template(s):
```liquid
{% seo %}
```
jekyll-seo-tag-2.6.1/docs/_config.yml 0000644 0000041 0000041 00000000377 13514322475 017473 0 ustar www-data www-data title: Jekyll SEO Tag
description: A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content.
permalink: pretty
plugins:
- jekyll-seo-tag
- jekyll-sitemap
theme: jekyll-theme-primer
jekyll-seo-tag-2.6.1/.travis.yml 0000644 0000041 0000041 00000000430 13514322475 016513 0 ustar www-data www-data language: ruby
cache: bundler
rvm:
- 2.4
- 2.6
before_install:
- gem update --system
- gem install bundler
script: script/cibuild
env:
global:
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
matrix:
- JEKYLL_VERSION="~> 3.3"
- JEKYLL_VERSION=">= 4.0.0.pre.alpha1"
jekyll-seo-tag-2.6.1/jekyll-seo-tag.gemspec 0000644 0000041 0000041 00000002757 13514322475 020614 0 ustar www-data www-data # frozen_string_literal: true
lib = File.expand_path("lib", __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "jekyll-seo-tag/version"
Gem::Specification.new do |spec|
spec.name = "jekyll-seo-tag"
spec.version = Jekyll::SeoTag::VERSION
spec.authors = ["Ben Balter"]
spec.email = ["ben.balter@github.com"]
spec.summary = "A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content."
spec.homepage = "https://github.com/benbalter/jekyll-seo-tag"
spec.license = "MIT"
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
# delete this section to allow pushing this gem to any host.
if spec.respond_to?(:metadata)
spec.metadata["allowed_push_host"] = "https://rubygems.org"
else
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
end
spec.required_ruby_version = ">= 2.3.0"
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|spec|features)/!) }
spec.bindir = "exe"
spec.executables = spec.files.grep(%r!^exe/!) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.add_dependency "jekyll", ">= 3.3", "< 5.0"
spec.add_development_dependency "bundler", ">= 1.15"
spec.add_development_dependency "html-proofer", "~> 3.7"
spec.add_development_dependency "rspec", "~> 3.5"
spec.add_development_dependency "rubocop-jekyll", "~> 0.4"
end
jekyll-seo-tag-2.6.1/.rspec 0000644 0000041 0000041 00000000036 13514322475 015521 0 ustar www-data www-data --color
--require spec_helper
jekyll-seo-tag-2.6.1/.rubocop.yml 0000644 0000041 0000041 00000000443 13514322475 016660 0 ustar www-data www-data inherit_from: .rubocop_todo.yml
require: rubocop-jekyll
inherit_gem:
rubocop-jekyll: .rubocop.yml
AllCops:
TargetRubyVersion: 2.3
Exclude:
- vendor/**/*
Metrics/LineLength:
Exclude:
- spec/**/*
- jekyll-seo-tag.gemspec
Metrics/BlockLength:
Exclude:
- spec/**/*
jekyll-seo-tag-2.6.1/.gitignore 0000644 0000041 0000041 00000000151 13514322475 016372 0 ustar www-data www-data /.bundle/
/.yardoc
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
/bin/
*.gem
_site
jekyll-seo-tag-2.6.1/script/ 0000755 0000041 0000041 00000000000 13514322475 015711 5 ustar www-data www-data jekyll-seo-tag-2.6.1/script/release 0000755 0000041 0000041 00000001361 13514322475 017260 0 ustar www-data www-data #!/bin/sh
# Tag and push a release.
set -e
# Make sure we're in the project root.
cd $(dirname "$0")/..
# Build a new gem archive.
rm -rf jekyll-seo-tag-*.gem
gem build -q jekyll-seo-tag.gemspec
# Make sure we're on the master branch.
(git branch | grep -q '* master') || {
echo "Only release from the master branch."
exit 1
}
# Figure out what version we're releasing.
tag=v`ls jekyll-seo-tag-*.gem | sed 's/^jekyll-seo-tag-\(.*\)\.gem$/\1/'`
# Make sure we haven't released this version before.
git fetch -t origin
(git tag -l | grep -q "$tag") && {
echo "Whoops, there's already a '${tag}' tag."
exit 1
}
# Tag it and bag it.
gem push jekyll-seo-tag-*.gem && git tag "$tag" &&
git push origin master && git push origin "$tag"
jekyll-seo-tag-2.6.1/script/site 0000755 0000041 0000041 00000000062 13514322475 016601 0 ustar www-data www-data #!/bin/sh
bundle exec jekyll serve --source docs
jekyll-seo-tag-2.6.1/script/cibuild 0000755 0000041 0000041 00000000155 13514322475 017253 0 ustar www-data www-data #!/bin/sh
set -ex
bundle exec rspec
bundle exec rubocop -S -D
bundle exec gem build jekyll-seo-tag.gemspec
jekyll-seo-tag-2.6.1/script/bootstrap 0000755 0000041 0000041 00000000043 13514322475 017651 0 ustar www-data www-data #!/bin/sh
set -ex
bundle install
jekyll-seo-tag-2.6.1/.rubocop_todo.yml 0000644 0000041 0000041 00000000774 13514322475 017714 0 ustar www-data www-data # This configuration was generated by
# `rubocop --auto-gen-config`
# on 2019-03-25 11:42:06 +0100 using RuboCop version 0.66.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 1
# Cop supports --auto-correct.
Lint/ToJSON:
Exclude:
- 'lib/jekyll-seo-tag/json_ld_drop.rb'
jekyll-seo-tag-2.6.1/lib/ 0000755 0000041 0000041 00000000000 13514322475 015153 5 ustar www-data www-data jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/ 0000755 0000041 0000041 00000000000 13514322475 020002 5 ustar www-data www-data jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/url_helper.rb 0000644 0000041 0000041 00000001102 13514322475 022462 0 ustar www-data www-data # frozen_string_literal: true
module Jekyll
class SeoTag
# Mixin to share common URL-related methods between class
module UrlHelper
private
# Determines if the given string is an absolute URL
#
# Returns true if an absolute URL.
# Retruns false if it's a relative URL
# Returns nil if it is not a string or can't be parsed as a URL
def absolute_url?(string)
return unless string
Addressable::URI.parse(string).absolute?
rescue Addressable::URI::InvalidURIError
nil
end
end
end
end
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/version.rb 0000644 0000041 0000041 00000000247 13514322475 022017 0 ustar www-data www-data # frozen_string_literal: true
# Prevent bundler errors
module Liquid; class Tag; end; end
module Jekyll
class SeoTag < Liquid::Tag
VERSION = "2.6.1"
end
end
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/drop.rb 0000644 0000041 0000041 00000013556 13514322475 021305 0 ustar www-data www-data # frozen_string_literal: true
module Jekyll
class SeoTag
class Drop < Jekyll::Drops::Drop
include Jekyll::SeoTag::UrlHelper
TITLE_SEPARATOR = " | "
FORMAT_STRING_METHODS = [
:markdownify, :strip_html, :normalize_whitespace, :escape_once,
].freeze
HOMEPAGE_OR_ABOUT_REGEX = %r!^/(about/)?(index.html?)?$!.freeze
def initialize(text, context)
@obj = {}
@mutations = {}
@text = text
@context = context
end
def version
Jekyll::SeoTag::VERSION
end
# Should the `` tag be generated for this page?
def title?
return false unless title
return @display_title if defined?(@display_title)
@display_title = (@text !~ %r!title=false!i)
end
def site_title
@site_title ||= format_string(site["title"] || site["name"])
end
def site_description
@site_description ||= format_string site["description"]
end
# Page title without site title or description appended
def page_title
@page_title ||= format_string(page["title"]) || site_title
end
# Page title with site title or description appended
# rubocop:disable Metrics/CyclomaticComplexity
def title
@title ||= begin
if site_title && page_title != site_title
page_title + TITLE_SEPARATOR + site_title
elsif site_description && site_title
site_title + TITLE_SEPARATOR + site_description
else
page_title || site_title
end
end
return page_number + @title if page_number
@title
end
# rubocop:enable Metrics/CyclomaticComplexity
def name
return @name if defined?(@name)
@name = if seo_name
seo_name
elsif !homepage_or_about?
nil
elsif site_social["name"]
format_string site_social["name"]
elsif site_title
site_title
end
end
def description
@description ||= begin
format_string(page["description"] || page["excerpt"]) || site_description
end
end
# A drop representing the page author
def author
@author ||= AuthorDrop.new(:page => page, :site => site)
end
# A drop representing the JSON-LD output
def json_ld
@json_ld ||= JSONLDDrop.new(self)
end
# Returns a Drop representing the page's image
# Returns nil if the image has no path, to preserve backwards compatability
def image
@image ||= ImageDrop.new(:page => page, :context => @context)
@image if @image.path
end
def date_modified
@date_modified ||= begin
date = if page_seo["date_modified"]
page_seo["date_modified"]
elsif page["last_modified_at"]
page["last_modified_at"].to_liquid
else
page["date"]
end
filters.date_to_xmlschema(date) if date
end
end
def date_published
@date_published ||= filters.date_to_xmlschema(page["date"]) if page["date"]
end
def type
@type ||= begin
if page_seo["type"]
page_seo["type"]
elsif homepage_or_about?
"WebSite"
elsif page["date"]
"BlogPosting"
else
"WebPage"
end
end
end
def links
@links ||= begin
if page_seo["links"]
page_seo["links"]
elsif homepage_or_about? && site_social["links"]
site_social["links"]
end
end
end
def logo
@logo ||= begin
return unless site["logo"]
if absolute_url? site["logo"]
filters.uri_escape site["logo"]
else
filters.uri_escape filters.absolute_url site["logo"]
end
end
end
def page_lang
@page_lang ||= page["lang"] || site["lang"] || "en_US"
end
def canonical_url
@canonical_url ||= begin
if page["canonical_url"].to_s.empty?
filters.absolute_url(page["url"]).to_s.gsub(%r!/index\.html$!, "/")
else
page["canonical_url"]
end
end
end
private
def filters
@filters ||= Jekyll::SeoTag::Filters.new(@context)
end
def page
@page ||= @context.registers[:page].to_liquid
end
def site
@site ||= @context.registers[:site].site_payload["site"].to_liquid
end
def homepage_or_about?
page["url"] =~ HOMEPAGE_OR_ABOUT_REGEX
end
def page_number
return unless @context["paginator"] && @context["paginator"]["page"]
current = @context["paginator"]["page"]
total = @context["paginator"]["total_pages"]
return "Page #{current} of #{total} for " if current > 1
end
attr_reader :context
def fallback_data
@fallback_data ||= {}
end
def format_string(string)
string = FORMAT_STRING_METHODS.reduce(string) do |memo, method|
filters.public_send(method, memo)
end
string unless string.empty?
end
def seo_name
@seo_name ||= format_string(page_seo["name"]) if page_seo["name"]
end
def page_seo
@page_seo ||= sub_hash(page, "seo")
end
def site_social
@site_social ||= sub_hash(site, "social")
end
# Safely returns a sub hash
#
# hash - the parent hash
# key - the key in the parent hash
#
# Returns the sub hash or an empty hash, if it does not exist
def sub_hash(hash, key)
if hash[key].is_a?(Hash)
hash[key]
else
{}
end
end
end
end
end
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/filters.rb 0000644 0000041 0000041 00000000350 13514322475 021775 0 ustar www-data www-data # frozen_string_literal: true
module Jekyll
class SeoTag
class Filters
include Jekyll::Filters
include Liquid::StandardFilters
def initialize(context)
@context = context
end
end
end
end
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/json_ld_drop.rb 0000644 0000041 0000041 00000004305 13514322475 023005 0 ustar www-data www-data # frozen_string_literal: true
module Jekyll
class SeoTag
class JSONLDDrop < Jekyll::Drops::Drop
extend Forwardable
def_delegator :page_drop, :name, :name
def_delegator :page_drop, :description, :description
def_delegator :page_drop, :canonical_url, :url
def_delegator :page_drop, :page_title, :headline
def_delegator :page_drop, :date_modified, :dateModified
def_delegator :page_drop, :date_published, :datePublished
def_delegator :page_drop, :links, :sameAs
def_delegator :page_drop, :logo, :logo
def_delegator :page_drop, :type, :type
# Expose #type and #logo as private methods and #@type as a public method
alias_method :"@type", :type
private :type
private :logo
# page_drop should be an instance of Jekyll::SeoTag::Drop
def initialize(page_drop)
@mutations = {}
@page_drop = page_drop
end
def fallback_data
{
"@context" => "https://schema.org",
}
end
def author
return unless page_drop.author["name"]
{
"@type" => "Person",
"name" => page_drop.author["name"],
}
end
def image
return unless page_drop.image
return page_drop.image.path if page_drop.image.keys.length == 1
hash = page_drop.image.to_h
hash["url"] = hash.delete("path")
hash["@type"] = "imageObject"
hash
end
def publisher
return unless logo
output = {
"@type" => "Organization",
"logo" => {
"@type" => "ImageObject",
"url" => logo,
},
}
output["name"] = page_drop.author.name if page_drop.author.name
output
end
def main_entity
return unless %w(BlogPosting CreativeWork).include?(type)
{
"@type" => "WebPage",
"@id" => page_drop.canonical_url,
}
end
alias_method :mainEntityOfPage, :main_entity
private :main_entity
def to_json
to_h.reject { |_k, v| v.nil? }.to_json
end
private
attr_reader :page_drop
end
end
end
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/json_ld.rb 0000644 0000041 0000041 00000001761 13514322475 021764 0 ustar www-data www-data # frozen_string_literal: true
module Jekyll
class SeoTag
# This module is deprecated, but is included in the Gem to avoid a breaking
# change and should be removed at the next major version bump
module JSONLD
METHODS_KEYS = {
:json_context => "@context",
:type => "@type",
:name => "name",
:page_title => "headline",
:json_author => "author",
:json_image => "image",
:date_published => "datePublished",
:date_modified => "dateModified",
:description => "description",
:publisher => "publisher",
:main_entity => "mainEntityOfPage",
:links => "sameAs",
:canonical_url => "url",
}.freeze
# Self should be a Jekyll::SeoTag::Drop instance (when extending the module)
def json_ld
Jekyll.logger.warn "Jekyll::SeoTag::JSONLD is deprecated"
@json_ld ||= JSONLDDrop.new(self)
end
end
end
end
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/image_drop.rb 0000644 0000041 0000041 00000004171 13514322475 022440 0 ustar www-data www-data # frozen_string_literal: true
module Jekyll
class SeoTag
# A drop representing the page image
# The image path will be pulled from:
#
# 1. The `image` key if it's a string
# 2. The `image.path` key if it's a hash
# 3. The `image.facebook` key
# 4. The `image.twitter` key
class ImageDrop < Jekyll::Drops::Drop
include Jekyll::SeoTag::UrlHelper
# Initialize a new ImageDrop
#
# page - The page hash (e.g., Page#to_liquid)
# context - the Liquid::Context
def initialize(page: nil, context: nil)
raise ArgumentError unless page && context
@mutations = {}
@page = page
@context = context
end
# Called path for backwards compatability, this is really
# the escaped, absolute URL representing the page's image
# Returns nil if no image path can be determined
def path
@path ||= filters.uri_escape(absolute_url) if absolute_url
end
alias_method :to_s, :path
private
attr_accessor :page
attr_accessor :context
# The normalized image hash with a `path` key (which may be nil)
def image_hash
@image_hash ||= if page["image"].is_a?(Hash)
{ "path" => nil }.merge(page["image"])
elsif page["image"].is_a?(String)
{ "path" => page["image"] }
else
{ "path" => nil }
end
end
alias_method :fallback_data, :image_hash
def raw_path
@raw_path ||= begin
image_hash["path"] || image_hash["facebook"] || image_hash["twitter"]
end
end
def absolute_url
return unless raw_path
return @absolute_url if defined? @absolute_url
@absolute_url = if raw_path.is_a?(String) && absolute_url?(raw_path) == false
filters.absolute_url raw_path
else
raw_path
end
end
def filters
@filters ||= Jekyll::SeoTag::Filters.new(context)
end
end
end
end
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag/author_drop.rb 0000644 0000041 0000041 00000005564 13514322475 022667 0 ustar www-data www-data # frozen_string_literal: true
module Jekyll
class SeoTag
# A drop representing the current page's author
#
# Author name will be pulled from:
#
# 1. The page's `author` key
# 2. The first author in the page's `authors` key
# 3. The `author` key in the site config
#
# If the result from the name search is a string, we'll also check
# for additional author metadata in `site.data.authors`
class AuthorDrop < Jekyll::Drops::Drop
# Initialize a new AuthorDrop
#
# page - The page hash (e.g., Page#to_liquid)
# site - The Jekyll::Drops::SiteDrop
def initialize(page: nil, site: nil)
raise ArgumentError unless page && site
@mutations = {}
@page = page
@site = site
end
# AuthorDrop#to_s should return name, allowing the author drop to safely
# replace `page.author`, if necessary, and remain backwards compatible
def name
author_hash["name"]
end
alias_method :to_s, :name
def twitter
return @twitter if defined? @twitter
twitter = author_hash["twitter"] || author_hash["name"]
@twitter = twitter.is_a?(String) ? twitter.sub(%r!^@!, "") : nil
end
private
attr_reader :page
attr_reader :site
# Finds the page author in the page.author, page.authors, or site.author
#
# Returns a string or hash representing the author
def resolved_author
return @resolved_author if defined? @resolved_author
sources = [page["author"]]
sources << page["authors"].first if page["authors"].is_a?(Array)
sources << site["author"]
@resolved_author = sources.find { |s| !s.to_s.empty? }
end
# If resolved_author is a string, attempts to find coresponding author
# metadata in `site.data.authors`
#
# Returns a hash representing additional metadata or an empty hash
def site_data_hash
@site_data_hash ||= begin
return {} unless resolved_author.is_a?(String)
return {} unless site.data["authors"].is_a?(Hash)
author_hash = site.data["authors"][resolved_author]
author_hash.is_a?(Hash) ? author_hash : {}
end
end
# Returns the normalized author hash representing the page author,
# including site-wide metadata if the author is provided as a string,
# or an empty hash, if the author cannot be resolved
def author_hash
if resolved_author.is_a? Hash
resolved_author
elsif resolved_author.is_a? String
{ "name" => resolved_author }.merge(site_data_hash)
else
{}
end
end
# Since author_hash is aliased to fallback_data, any values in the hash
# will be exposed via the drop, allowing support for arbitrary metadata
alias_method :fallback_data, :author_hash
end
end
end
jekyll-seo-tag-2.6.1/lib/template.html 0000755 0000041 0000041 00000007273 13514322475 017670 0 ustar www-data www-data
{% if seo_tag.title? %}
{{ seo_tag.title }}
{% endif %}
{% if seo_tag.page_title %}
{% endif %}
{% if seo_tag.author.name %}
{% endif %}
{% if seo_tag.description %}
{% endif %}
{% if site.url %}
{% endif %}
{% if seo_tag.site_title %}
{% endif %}
{% if seo_tag.image %}
{% if seo_tag.image.height %}
{% endif %}
{% if seo_tag.image.width %}
{% endif %}
{% endif %}
{% if page.date %}
{% endif %}
{% if paginator.previous_page %}
{% endif %}
{% if paginator.next_page %}
{% endif %}
{% if site.twitter %}
{% if seo_tag.image %}
{% else %}
{% endif %}
{% if seo_tag.author.twitter %}
{% endif %}
{% endif %}
{% if site.facebook %}
{% if site.facebook.admins %}
{% endif %}
{% if site.facebook.publisher %}
{% endif %}
{% if site.facebook.app_id %}
{% endif %}
{% endif %}
{% if site.webmaster_verifications %}
{% if site.webmaster_verifications.google %}
{% endif %}
{% if site.webmaster_verifications.bing %}
{% endif %}
{% if site.webmaster_verifications.alexa %}
{% endif %}
{% if site.webmaster_verifications.yandex %}
{% endif %}
{% if site.webmaster_verifications.baidu %}
{% endif %}
{% elsif site.google_site_verification %}
{% endif %}
jekyll-seo-tag-2.6.1/lib/jekyll-seo-tag.rb 0000644 0000041 0000041 00000004762 13514322475 020340 0 ustar www-data www-data # frozen_string_literal: true
require "jekyll"
require "jekyll-seo-tag/version"
module Jekyll
class SeoTag < Liquid::Tag
autoload :JSONLD, "jekyll-seo-tag/json_ld"
autoload :AuthorDrop, "jekyll-seo-tag/author_drop"
autoload :ImageDrop, "jekyll-seo-tag/image_drop"
autoload :JSONLDDrop, "jekyll-seo-tag/json_ld_drop"
autoload :UrlHelper, "jekyll-seo-tag/url_helper"
autoload :Drop, "jekyll-seo-tag/drop"
autoload :Filters, "jekyll-seo-tag/filters"
attr_accessor :context
# Matches all whitespace that follows either
# 1. A '}', which closes a Liquid tag
# 2. A '{', which opens a JSON block
# 3. A '>' followed by a newline, which closes an XML tag or
# 4. A ',' followed by a newline, which ends a JSON line
# We will strip all of this whitespace to minify the template
# We will not strip any whitespace if the next character is a '-'
# so that we do not interfere with the HTML comment at the
# very begining
MINIFY_REGEX = %r!(?<=[{}]|[>,]\n)\s+(?\!-)!.freeze
def initialize(_tag_name, text, _tokens)
super
@text = text
end
def render(context)
@context = context
SeoTag.template.render!(payload, info)
end
private
def options
{
"version" => Jekyll::SeoTag::VERSION,
"title" => title?,
}
end
def payload
# site_payload is an instance of UnifiedPayloadDrop. See https://git.io/v5ajm
Jekyll::Utils.deep_merge_hashes(
context.registers[:site].site_payload,
"page" => context.registers[:page],
"paginator" => context["paginator"],
"seo_tag" => drop
)
end
def drop
if context.registers[:site].liquid_renderer.respond_to?(:cache)
Jekyll::SeoTag::Drop.new(@text, @context)
else
@drop ||= Jekyll::SeoTag::Drop.new(@text, @context)
end
end
def info
{
:registers => context.registers,
:filters => [Jekyll::Filters],
}
end
class << self
def template
@template ||= Liquid::Template.parse template_contents
end
private
def template_contents
@template_contents ||= begin
File.read(template_path).gsub(MINIFY_REGEX, "")
end
end
def template_path
@template_path ||= begin
File.expand_path "./template.html", File.dirname(__FILE__)
end
end
end
end
end
Liquid::Template.register_tag("seo", Jekyll::SeoTag)
jekyll-seo-tag-2.6.1/History.markdown 0000644 0000041 0000041 00000007131 13514322475 017614 0 ustar www-data www-data ## 2.6.1 / 2019-05-17
### Development Fixes
* Test against Jekyll 4.x (#336)
## 2.6.0 / 2019-03-16
### Minor Enhancements
* Twitter Image and Title (#330)
### Bug Fixes
* Do not cache the drop payload for SeoTag (#306)
* Update url of schema website (#296)
### Development Fixes
* Relax version constraint on Bundler (#325)
* chore(ci): Add Ruby 2.6, drop Ruby 2.3 (#326)
* chore (ci): remove deprecated `sudo: false` in .travis.yml (#333)
* Lint Ruby code with rubocop-jekyll gem (#302)
* chore(deps): bump rubocop-jekyll to v0.4 (#320)
* chore(deps): bump rubocop-jekyll to v0.3 (#316)
* Correct RuboCop offenses in spec files (#319)
### Documentation
* Rectify error in Usage documentation (#328)
## 2.5.0 / 2018-05-18
* Docs: Prevent GitHub Pages from processing Liquid raw tag (#276)
### Documentation
* Use gems config key for Jekyll < 3.5.0 (#255)
* docs/usage - replace "below" with correct link (#280)
### Development Fixes
* Test against Ruby 2.5 (#260)
* add tests for twitter.card types (#289)
* Target Ruby 2.3 and Rubocop 0.56.0 (#292)
### Minor Enhancements
* Add webmaster_verifications for baidu (#263)
* Include page number in title (#250)
* Configure default Twitter summary card type (V2) (#225)
## 2.4.0 / 2017-12-04
### Minor
* Add meta generator (#236)
* Consistently use self-closing tags (#246)
* Strip null values from JSON-LD hash (#249)
### Documentation
* Avoid deprecation warning when building docs (#243)
### Development Fixes
* Test against latest Rubies (#242)
* Use Nokigiri on CI (#181)
## 2.3.0
### Minor Enhancements
* Use canonical_url specified in page if present #211
* Fix for image.path causing an invalid url error #228
* Ensure `site.data.authors` is properly formatted before attempting to retrieve author meta #227
* Convert author, image, and JSON-LD to dedicated drops #229
* Cache parsed template #231
* Define path with `__dir__` #232
### Documentation
* gems: is deprecated in current Jekyll version of github-pages #230
## 2.2.3
* Guard against the author's Twitter handle being Nil when stripping @'s #203
* Guard against empty title or description strings #206
## 2.2.2
### Minor Enhancements
* Guard against arrays in subhashes #197
* Guard against invalid or missing URLs #199
### Development fixes
* Remove dynamic GitHub Pages logic from Gemfile #194
## 2.2.1
* Convert template logic to a Liquid Drop (significant performance improvement) (#184)
* Fix for JSON-LD validation warning for images missing required properties (#183)
## 2.2.0
### Major Enhancements
* Add author meta (#103)
* Add og:locale support #166
* Add support for Bing and Yandex webmaster tools. Closes #147 (#148)
* Add SEO author and date modified to validate JSON-LD output (#151)
### Minor Enhancements
* Use `|` for title separator (#162)
* Use `og:image` for twitter image (#174)
### Development Fixes
* Style fixes (#170, #157, #149)
* Test against latest version of Jekyll (#171)
* Bump dev dependencies (#172)
* Remove Rake dependency (#180)
## 2.1.0
### Major Enhancement
* Use new URL filters (#123)
### Minor Enhancements
* Wraps logo image json data in a publisher property (#133)
* Fix duplicated `escape_once` (#93)
* Simplify minify regex (#125)
* Don't mangle text with newlines #126
### Documentation
* Add front matter default example for image (#132)
* Fix tiny typo (#106)
* add example usage of social profiles (#139)
### Development
* Inherit Jekyll's rubocop config for consistency (#109)
* Correct spelling in .travis.yml (#112)
jekyll-seo-tag-2.6.1/Gemfile 0000644 0000041 0000041 00000000204 13514322475 015674 0 ustar www-data www-data # frozen_string_literal: true
source "https://rubygems.org"
gemspec
gem "jekyll", ENV["JEKYLL_VERSION"] if ENV["JEKYLL_VERSION"]
jekyll-seo-tag-2.6.1/LICENSE.txt 0000644 0000041 0000041 00000002141 13514322475 016226 0 ustar www-data www-data The MIT License (MIT)
Copyright (c) 2015-present Ben Balter and the jekyll-seo-tag contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.