diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 0000000..9408010
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,10 @@
+Metrics/LineLength:
+ Exclude:
+ - spec/**/*
+ - jekyll-seo-tag.gemspec
+
+Style/Documentation:
+ Enabled: false
+
+Style/FileName:
+ Enabled: false
diff --git a/Gemfile b/Gemfile
index 1475b55..a215af7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,6 +1,16 @@
source 'https://rubygems.org'
+require 'json'
+require 'open-uri'
-# Specify your gem's dependencies in jekyll_seo_tags.gemspec
gemspec
-gem 'github-pages'
+group :development, :test do
+ versions = JSON.parse(open('https://pages.github.com/versions.json').read)
+ versions.delete('ruby')
+ versions.delete('jekyll-seo-tag')
+ versions.delete('github-pages')
+
+ versions.each do |dep, version|
+ gem dep, version
+ end
+end
diff --git a/README.md b/README.md
index 75f5f65..b219211 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content.
-[![Gem Version](https://badge.fury.io/rb/jekyll-seo-tag.svg)](https://badge.fury.io/rb/jekyll-seo-tag) [![Build Status](https://travis-ci.org/benbalter/jekyll-seo-tag.svg)](https://travis-ci.org/benbalter/jekyll-seo-tag)
+[![Gem Version](https://badge.fury.io/rb/jekyll-seo-tag.svg)](https://badge.fury.io/rb/jekyll-seo-tag) [![Build Status](https://travis-ci.org/benbalter/jekyll-seo-tag.svg)](https://travis-ci.org/benbalter/jekyll-seo-tag)
## What it does
@@ -53,17 +53,22 @@ The SEO tag will respect any of the following if included in your site's `_confi
* `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.
* `twitter:username` - The site's Twitter handle. You'll want to describe it like so:
-
```yml
twitter:
username: benbalter
```
-
+* `facebook:app_id` (A Facebook app ID for Facebook insights), and/or `facebook:publisher` (A Facebook page URL or ID of the publishing entity). You'll want to describe one or both like so:
+ ```yml
+ facebook:
+ app_id: 1234
+ publisher: 1234
+ ```
* `logo` - Relative URL to a site-wide logo (e.g., `assets/your-company-logo.png`)
* `social` - For [specifying social profiles](https://developers.google.com/structured-data/customize/social-profiles). The following properties are available:
* `type` - Either `person` or `organization` (defaults to `person`)
* `name` - If the user or organization name differs from the site's name
* `links` - An array of links to social media profiles.
+* `google_site_verification` for verifying ownership via Google webmaster tools
The SEO tag will respect the following YAML front matter if included in a post, page, or document:
diff --git a/Rakefile b/Rakefile
index b7e9ed5..4c774a2 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,6 +1,6 @@
-require "bundler/gem_tasks"
-require "rspec/core/rake_task"
+require 'bundler/gem_tasks'
+require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
-task :default => :spec
+task default: :spec
diff --git a/jekyll-seo-tag.gemspec b/jekyll-seo-tag.gemspec
index bc207b0..9ba99bb 100644
--- a/jekyll-seo-tag.gemspec
+++ b/jekyll-seo-tag.gemspec
@@ -4,31 +4,31 @@ $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.name = 'jekyll-seo-tag'
spec.version = Jekyll::SeoTag::VERSION
- spec.authors = ["Ben Balter"]
- spec.email = ["ben.balter@github.com"]
- spec.summary = %q{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"
+ 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"
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
else
- raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
end
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- spec.bindir = "exe"
+ spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
- spec.require_paths = ["lib"]
-
- spec.add_dependency "jekyll", ">= 2.0"
- spec.add_development_dependency "bundler", "~> 1.10"
- spec.add_development_dependency "rake", "~> 10.0"
- spec.add_development_dependency "rspec", "~> 3.3"
- spec.add_development_dependency "html-proofer", "~> 2.5"
+ spec.require_paths = ['lib']
+ spec.add_dependency 'jekyll', '>= 2.0'
+ spec.add_development_dependency 'bundler', '~> 1.10'
+ spec.add_development_dependency 'rake', '~> 10.0'
+ spec.add_development_dependency 'rspec', '~> 3.3'
+ spec.add_development_dependency 'html-proofer', '~> 2.5'
+ spec.add_development_dependency 'rubocop', '~> 0.37'
end
diff --git a/lib/jekyll-seo-tag.rb b/lib/jekyll-seo-tag.rb
index 1b6f62b..c2e443f 100644
--- a/lib/jekyll-seo-tag.rb
+++ b/lib/jekyll-seo-tag.rb
@@ -2,9 +2,10 @@ require 'jekyll-seo-tag/filters'
module Jekyll
class SeoTag < Liquid::Tag
-
attr_accessor :context
+ MINIFY_REGEX = /(>\n|[%}]})\s+(<|{[{%])/
+
def render(context)
@context = context
output = template.render!(payload, info)
@@ -16,15 +17,16 @@ module Jekyll
def payload
{
- "page" => context.registers[:page],
- "site" => context.registers[:site].site_payload["site"]
+ 'seo_tag' => { 'version' => VERSION },
+ 'page' => context.registers[:page],
+ 'site' => context.registers[:site].site_payload['site']
}
end
def info
{
- :registers => context.registers,
- :filters => [Jekyll::Filters, JekyllSeoTag::Filters]
+ registers: context.registers,
+ filters: [Jekyll::Filters, JekyllSeoTag::Filters]
}
end
@@ -33,11 +35,15 @@ module Jekyll
end
def template_contents
- @template_contents ||= File.read(template_path).gsub(/(>\n|[%}]})\s+(<|{[{%])/,'\1\2').chomp
+ @template_contents ||= begin
+ File.read(template_path).gsub(MINIFY_REGEX, '\1\2').chomp
+ end
end
def template_path
- @template_path ||= File.expand_path "./template.html", File.dirname(__FILE__)
+ @template_path ||= begin
+ File.expand_path './template.html', File.dirname(__FILE__)
+ end
end
end
end
diff --git a/lib/jekyll-seo-tag/filters.rb b/lib/jekyll-seo-tag/filters.rb
index 0f0d6ef..24856c6 100644
--- a/lib/jekyll-seo-tag/filters.rb
+++ b/lib/jekyll-seo-tag/filters.rb
@@ -1,6 +1,5 @@
module JekyllSeoTag
module Filters
-
# This is available in Liquid from version 3 which is required by Jekyll 3
# Provided here for compatibility with Jekyll 2.x
def default(input, default_value = ''.freeze)
diff --git a/lib/jekyll-seo-tag/version.rb b/lib/jekyll-seo-tag/version.rb
index ee50ec8..01f9676 100644
--- a/lib/jekyll-seo-tag/version.rb
+++ b/lib/jekyll-seo-tag/version.rb
@@ -3,6 +3,6 @@ module Liquid; class Tag; end; end
module Jekyll
class SeoTag < Liquid::Tag
- VERSION = "1.0.0"
+ VERSION = '1.1.0'.freeze
end
end
diff --git a/lib/template.html b/lib/template.html
index d432727..1e38b69 100644
--- a/lib/template.html
+++ b/lib/template.html
@@ -1,31 +1,35 @@
-
+
{% if site.url %}
{% assign seo_url = site.url | append: site.baseurl %}
{% endif %}
{% assign seo_url = seo_url | default: site.github.url %}
-
{% assign seo_site_title = site.title | default: site.name %}
{% if page.title %}
{% assign seo_title = page.title %}
{% assign seo_page_title = page.title %}
+
{% if seo_site_title %}
{% assign seo_title = seo_title | append:" - " | append: seo_site_title %}
{% endif %}
{% elsif seo_site_title %}
{% assign seo_title = seo_site_title %}
{% assign seo_page_title = seo_site_title %}
+
{% if site.description %}
{% assign seo_title = seo_title | append:" - " | append: site.description %}
{% endif %}
{% endif %}
+
{% if seo_title %}
{% assign seo_title = seo_title | markdownify | strip_html | strip_newlines | escape_once %}
{% endif %}
+
{% if seo_site_title %}
{% assign seo_site_title = seo_site_title | markdownify | strip_html | strip_newlines | escape_once %}
{% endif %}
+
{% if seo_page_title %}
{% assign seo_page_title = seo_page_title | markdownify | strip_html | strip_newlines | escape_once %}
{% endif %}
@@ -64,6 +68,7 @@
{% if seo_author_name %}
{% assign seo_author_name = seo_author_name | strip_html | escape_once %}
{% endif %}
+
{% if seo_author_twitter %}
{% assign seo_author_twitter = seo_author_twitter | replace:"@","" | prepend:"@" | strip_html | escape_once %}
{% endif %}
@@ -104,12 +109,16 @@
{% if page.date %}
+
+
{% if page.next.url %}
{% endif %}
+
{% if page.previous.url %}
{% endif %}
+
}m)[1]
data = JSON.parse(data)
- expect(data["name"]).to eql("Foo")
- expect(data["url"]).to eql("http://example.invalid")
+ expect(data['name']).to eql('Foo')
+ expect(data['url']).to eql('http://example.invalid')
end
- it "outputs post meta" do
- post = post({"title" => "post", "description" => "description", "image" => "/img.png" })
- context = context({ :page => post })
+ it 'outputs post meta' do
+ post = post('title' => 'post', 'description' => 'description', 'image' => '/img.png')
+ context = context(page: post)
output = subject.render(context)
- expected = //
+ expected = %r{}
expect(output).to match(expected)
- data = output.match(/}m)[1]
data = JSON.parse(data)
- expect(data["headline"]).to eql("post")
- expect(data["description"]).to eql("description")
- expect(data["image"]).to eql("/img.png")
+ expect(data['headline']).to eql('post')
+ expect(data['description']).to eql('description')
+ expect(data['image']).to eql('/img.png')
end
- it "outputs twitter card meta" do
- site = site({"twitter" => { "username" => "jekyllrb" }})
- page = page({"author" => "benbalter"})
- context = context({ :site => site, :page => page })
+ it 'outputs twitter card meta' do
+ site = site('twitter' => { 'username' => 'jekyllrb' })
+ page = page('author' => 'benbalter')
+ context = context(site: site, page: page)
- expected = //
+ expected = %r{}
expect(subject.render(context)).to match(expected)
- expected = //
+ expected = %r{}
expect(subject.render(context)).to match(expected)
end
- it "outputs social meta" do
- links = ["http://foo.invalid", "http://bar.invalid"]
- site = site({"social" => { "name" => "Ben", "links" => links }})
- context = context({ :site => site })
+ it 'outputs social meta' do
+ links = ['http://foo.invalid', 'http://bar.invalid']
+ site = site('social' => { 'name' => 'Ben', 'links' => links })
+ context = context(site: site)
output = subject.render(context)
- data = output.match(/}m)[1]
data = JSON.parse(data)
- expect(data["@type"]).to eql("person")
- expect(data["name"]).to eql("Ben")
- expect(data["sameAs"]).to eql(links)
+ expect(data['@type']).to eql('person')
+ expect(data['name']).to eql('Ben')
+ expect(data['sameAs']).to eql(links)
end
- it "outputs the logo" do
- site = site({"logo" => "logo.png", "url" => "http://example.invalid" })
- context = context({ :site => site })
+ it 'outputs the logo' do
+ site = site('logo' => 'logo.png', 'url' => 'http://example.invalid')
+ context = context(site: site)
output = subject.render(context)
- data = output.match(/}m)[1]
data = JSON.parse(data)
- expect(data["logo"]).to eql("http://example.invalid/logo.png")
- expect(data["url"]).to eql("http://example.invalid")
+ expect(data['logo']).to eql('http://example.invalid/logo.png')
+ expect(data['url']).to eql('http://example.invalid')
end
- it "outputs the image" do
- page = page({ "image" => "foo.png" })
- site = site({ "url" => "http://example.invalid" })
- context = context({ :page => page, :site => site })
- expected = %r!!
+ it 'outputs the image' do
+ page = page('image' => 'foo.png')
+ site = site('url' => 'http://example.invalid')
+ context = context(page: page, site: site)
+ expected = %r{}
expect(subject.render(context)).to match(expected)
end
- it "uses site.name if site.title is not present" do
- site = site({"name" => "Site Name", "title" => nil })
- context = context({ :site => site })
- expected = %r!!
+ it 'uses site.name if site.title is not present' do
+ site = site('name' => 'Site Name', 'title' => nil)
+ context = context(site: site)
+ expected = %r{}
expect(subject.render(context)).to match(expected)
end
- it "uses site.tile if both site.title and site.name are present" do
- site = site({"name" => "Site Name", "title" => "Site Title" })
- context = context({ :site => site })
- expected = %r!!
+ it 'uses site.tile if both site.title and site.name are present' do
+ site = site('name' => 'Site Name', 'title' => 'Site Title')
+ context = context(site: site)
+ expected = %r{}
expect(subject.render(context)).to match(expected)
end
- it "supports author data as an object" do
- site = site({"twitter" => { "username" => "jekyllrb" }})
- page = page({"author" => {"twitter" => "@test"}})
- context = context({ :site => site, :page => page })
- expected = %r!!
+ it 'supports author data as an object' do
+ site = site('twitter' => { 'username' => 'jekyllrb' })
+ page = page('author' => { 'twitter' => '@test' })
+ context = context(site: site, page: page)
+ expected = %r{}
expect(subject.render(context)).to match(expected)
end
- it "outputs valid HTML" do
+ it 'outputs valid HTML' do
site.process
options = {
- :check_html => true,
- :checks_to_ignore => ["ScriptCheck", "LinkCheck", "ImageCheck"]
+ check_html: true,
+ checks_to_ignore: %w(ScriptCheck LinkCheck ImageCheck)
}
status = HTML::Proofer.new(dest_dir, options).run
expect(status).to eql(true)
end
+
+ it 'outputs the plugin version' do
+ version = Jekyll::SeoTag::VERSION
+ expect(subject.render(context)).to match(/Jekyll SEO tag v#{version}/i)
+ end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index a391dd0..ed7ff23 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -3,41 +3,41 @@ require 'jekyll'
require 'jekyll-seo-tag'
require 'html/proofer'
-ENV["JEKYLL_LOG_LEVEL"] = "error"
+ENV['JEKYLL_LOG_LEVEL'] = 'error'
def dest_dir
- File.expand_path("../tmp/dest", File.dirname(__FILE__))
+ File.expand_path('../tmp/dest', File.dirname(__FILE__))
end
def source_dir
- File.expand_path("./fixtures", File.dirname(__FILE__))
+ File.expand_path('./fixtures', File.dirname(__FILE__))
end
CONFIG_DEFAULTS = {
- "source" => source_dir,
- "destination" => dest_dir,
- "gems" => ["jekyll-seo-tag"]
-}
+ 'source' => source_dir,
+ 'destination' => dest_dir,
+ 'gems' => ['jekyll-seo-tag']
+}.freeze
-def page(options={})
- page = Jekyll::Page.new site, CONFIG_DEFAULTS["source"], "", "page.md"
+def page(options = {})
+ page = Jekyll::Page.new site, CONFIG_DEFAULTS['source'], '', 'page.md'
page.data = options
page
end
-def post(options={})
- filename = File.expand_path("2015-01-01-post.md", CONFIG_DEFAULTS["source"])
- config = { :site => site, :collection => site.collections["posts"] }
+def post(options = {})
+ filename = File.expand_path('2015-01-01-post.md', CONFIG_DEFAULTS['source'])
+ config = { site: site, collection: site.collections['posts'] }
page = Jekyll::Document.new filename, config
page.merge_data!(options)
page
end
-def site(options={})
+def site(options = {})
config = Jekyll.configuration CONFIG_DEFAULTS.merge(options)
Jekyll::Site.new(config)
end
-def context(registers={})
- Liquid::Context.new({}, {}, { :site => site, :page => page }.merge(registers))
+def context(registers = {})
+ Liquid::Context.new({}, {}, { site: site, page: page }.merge(registers))
end