use ruby to generate json-ld
This commit is contained in:
parent
337bffa3bc
commit
66aff234ca
|
@ -3,6 +3,7 @@ require "jekyll-seo-tag/version"
|
|||
|
||||
module Jekyll
|
||||
class SeoTag < Liquid::Tag
|
||||
autoload :JSONLD, "jekyll-seo-tag/json_ld"
|
||||
autoload :Drop, "jekyll-seo-tag/drop"
|
||||
autoload :Filters, "jekyll-seo-tag/filters"
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
module Jekyll
|
||||
class SeoTag
|
||||
class Drop < Jekyll::Drops::Drop
|
||||
include Jekyll::SeoTag::JSONLD
|
||||
|
||||
TITLE_SEPARATOR = " | ".freeze
|
||||
FORMAT_STRING_METHODS = %i[
|
||||
markdownify strip_html normalize_whitespace escape_once
|
||||
|
@ -91,10 +93,12 @@ module Jekyll
|
|||
|
||||
def date_modified
|
||||
@date_modified ||= begin
|
||||
if page["seo"] && page["seo"]["date_modified"]
|
||||
return page["seo"]["date_modified"]
|
||||
end
|
||||
page["last_modified_at"] || page["date"]
|
||||
date = if page["seo"] && page["seo"]["date_modified"]
|
||||
page["seo"]["date_modified"]
|
||||
else
|
||||
page["last_modified_at"] || page["date"]
|
||||
end
|
||||
filters.date_to_xmlschema(date) if date
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -164,6 +168,10 @@ module Jekyll
|
|||
@page_lang ||= page["lang"] || site["lang"] || "en_US"
|
||||
end
|
||||
|
||||
def canonical_url
|
||||
@canonical_url ||= filters.absolute_url(page["url"]).gsub(%r!/index\.html$!, "/")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filters
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
module Jekyll
|
||||
class SeoTag
|
||||
module JSONLD
|
||||
|
||||
# A hash of instance methods => key in resulting JSON-LD hash
|
||||
METHODS_KEYS = {
|
||||
:json_context => "@context",
|
||||
:type => "@type",
|
||||
:name => "name",
|
||||
:page_title => "headline",
|
||||
:json_author => "author",
|
||||
:image_path => "image",
|
||||
:date_modified => "dateModified",
|
||||
:description => "description",
|
||||
:publisher => "publisher",
|
||||
:main_entity => "mainEntityOfPage",
|
||||
:links => "sameAs",
|
||||
:canonical_url => "url",
|
||||
}.freeze
|
||||
|
||||
def json_ld
|
||||
@json_ld ||= begin
|
||||
output = {}
|
||||
METHODS_KEYS.each do |method, key|
|
||||
value = send(method)
|
||||
output[key] = value unless value.nil?
|
||||
end
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def json_context
|
||||
"http://schema.org"
|
||||
end
|
||||
|
||||
def json_author
|
||||
return unless author
|
||||
{
|
||||
"@type" => "Person",
|
||||
"name" => author["name"],
|
||||
}
|
||||
end
|
||||
|
||||
def image_path
|
||||
image["path"] if image
|
||||
end
|
||||
|
||||
def date
|
||||
filters.date_to_xmlschema(page["date"]) if page["date"]
|
||||
end
|
||||
|
||||
def publisher
|
||||
return unless logo
|
||||
output = {
|
||||
"@type" => "Organization",
|
||||
"logo" => {
|
||||
"@type" => "ImageObject",
|
||||
"url" => logo,
|
||||
},
|
||||
}
|
||||
output["name"] = author["name"] if author
|
||||
output
|
||||
end
|
||||
|
||||
def main_entity
|
||||
return unless %w(BlogPosting CreativeWork).include?(type)
|
||||
{
|
||||
"@type" => "WebPage",
|
||||
"@id" => canonical_url,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -19,8 +19,8 @@
|
|||
{% endif %}
|
||||
|
||||
{% if site.url %}
|
||||
<link rel="canonical" href="{{ page.url | replace:'/index.html','/' | absolute_url }}" />
|
||||
<meta property="og:url" content="{{ page.url | replace:'/index.html','/' | absolute_url }}" />
|
||||
<link rel="canonical" href="{{ seo_tag.canonical_url }}" />
|
||||
<meta property="og:url" content="{{ seo_tag.canonical_url }}" />
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.site_title %}
|
||||
|
@ -99,70 +99,7 @@
|
|||
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
|
||||
{% if seo_tag.type %}
|
||||
"@type": {{ seo_tag.type | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.name %}
|
||||
"name": {{ seo_tag.name | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.page_title %}
|
||||
"headline": {{ seo_tag.page_title | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.author %}
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": {{ seo_tag.author.name | jsonify }}
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.image %}
|
||||
"image": {{ seo_tag.image.path | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
{% if page.date %}
|
||||
"datePublished": {{ page.date | date_to_xmlschema | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.date_modified %}
|
||||
"dateModified": {{ seo_tag.date_modified | date_to_xmlschema | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.description %}
|
||||
"description": {{ seo_tag.description | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.logo %}
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
{% if seo_tag.author %}
|
||||
"name": {{ seo_tag.author.name | jsonify }},
|
||||
{% endif %}
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": {{ seo_tag.logo | jsonify }}
|
||||
}
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.type == "BlogPosting" or seo_tag.type == "CreativeWork"%}
|
||||
"mainEntityOfPage": {
|
||||
"@type": "WebPage",
|
||||
"@id": {{ page.url | replace:'/index.html','/' | absolute_url | jsonify }}
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
{% if seo_tag.links %}
|
||||
"sameAs": {{ seo_tag.links | jsonify }},
|
||||
{% endif %}
|
||||
|
||||
"url": {{ page.url | replace:'/index.html','/' | absolute_url | jsonify }}
|
||||
}
|
||||
{{ seo_tag.json_ld | jsonify }}
|
||||
</script>
|
||||
|
||||
<!-- End Jekyll SEO tag -->
|
||||
|
|
|
@ -244,26 +244,26 @@ RSpec.describe Jekyll::SeoTag::Drop do
|
|||
|
||||
context "date modified" do
|
||||
context "with seo.date_modified" do
|
||||
let(:page_meta) { { "seo" => { "date_modified" => "tuesday" } } }
|
||||
let(:page_meta) { { "seo" => { "date_modified" => "2017-01-01" } } }
|
||||
|
||||
it "uses seo.date_modified" do
|
||||
expect(subject.date_modified).to eql("tuesday")
|
||||
expect(subject.date_modified).to eql("2017-01-01T00:00:00-05:00")
|
||||
end
|
||||
end
|
||||
|
||||
context "with page.last_modified_at" do
|
||||
let(:page_meta) { { "last_modified_at" => "tuesday" } }
|
||||
let(:page_meta) { { "last_modified_at" => "2017-01-01" } }
|
||||
|
||||
it "uses page.last_modified_at" do
|
||||
expect(subject.date_modified).to eql("tuesday")
|
||||
expect(subject.date_modified).to eql("2017-01-01T00:00:00-05:00")
|
||||
end
|
||||
end
|
||||
|
||||
context "date" do
|
||||
let(:page_meta) { { "date" => "tuesday" } }
|
||||
let(:page_meta) { { "date" => "2017-01-01" } }
|
||||
|
||||
it "uses page.date" do
|
||||
expect(subject.date_modified).to eql("tuesday")
|
||||
expect(subject.date_modified).to eql("2017-01-01T00:00:00-05:00")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
RSpec.describe Jekyll::SeoTag::JSONLD do
|
||||
let(:metadata) do
|
||||
{
|
||||
"title" => "title",
|
||||
"author" => "author",
|
||||
"image" => "image",
|
||||
"date" => "2017-01-01",
|
||||
"description" => "description",
|
||||
"seo" => {
|
||||
"name" => "seo name",
|
||||
"date_modified" => "2017-01-01",
|
||||
"links" => %w(a b),
|
||||
},
|
||||
}
|
||||
end
|
||||
let(:config) do
|
||||
{
|
||||
"logo" => "logo",
|
||||
}
|
||||
end
|
||||
let(:page) { make_page(metadata) }
|
||||
let(:site) { make_site(config) }
|
||||
let(:context) { make_context(:page => page, :site => site) }
|
||||
subject { Jekyll::SeoTag::Drop.new("", context).json_ld }
|
||||
|
||||
it "returns the context" do
|
||||
expect(subject).to have_key("@context")
|
||||
expect(subject["@context"]).to eql("http://schema.org")
|
||||
end
|
||||
|
||||
it "returns the type" do
|
||||
expect(subject).to have_key("@type")
|
||||
expect(subject["@type"]).to eql("BlogPosting")
|
||||
end
|
||||
|
||||
it "returns the name" do
|
||||
expect(subject).to have_key("name")
|
||||
expect(subject["name"]).to eql("seo name")
|
||||
end
|
||||
|
||||
it "returns the headline" do
|
||||
expect(subject).to have_key("headline")
|
||||
expect(subject["headline"]).to eql("title")
|
||||
end
|
||||
|
||||
it "returns the author" do
|
||||
expect(subject).to have_key("author")
|
||||
expect(subject["author"]).to be_a(Hash)
|
||||
expect(subject["author"]).to have_key("@type")
|
||||
expect(subject["author"]["@type"]).to eql("Person")
|
||||
expect(subject["author"]).to have_key("name")
|
||||
expect(subject["author"]["name"]).to eql("author")
|
||||
end
|
||||
|
||||
it "returns the image" do
|
||||
expect(subject).to have_key("image")
|
||||
expect(subject["image"]).to eql("/image")
|
||||
end
|
||||
|
||||
it "returns the dateModified" do
|
||||
expect(subject).to have_key("dateModified")
|
||||
expect(subject["dateModified"]).to eql("2017-01-01T00:00:00-05:00")
|
||||
end
|
||||
|
||||
it "returns the description" do
|
||||
expect(subject).to have_key("description")
|
||||
expect(subject["description"]).to eql("description")
|
||||
end
|
||||
|
||||
it "returns the publisher" do
|
||||
expect(subject).to have_key("publisher")
|
||||
|
||||
publisher = subject["publisher"]
|
||||
expect(publisher).to be_a(Hash)
|
||||
|
||||
expect(publisher).to have_key("@type")
|
||||
expect(publisher["@type"]).to eql("Organization")
|
||||
expect(publisher).to have_key("logo")
|
||||
|
||||
logo = publisher["logo"]
|
||||
expect(logo).to have_key("@type")
|
||||
expect(logo["@type"]).to eql("ImageObject")
|
||||
expect(logo).to have_key("url")
|
||||
expect(logo["url"]).to eql("/logo")
|
||||
end
|
||||
|
||||
it "returns the main entity of page" do
|
||||
expect(subject).to have_key("mainEntityOfPage")
|
||||
expect(subject["mainEntityOfPage"]).to be_a(Hash)
|
||||
expect(subject["mainEntityOfPage"]).to have_key("@type")
|
||||
expect(subject["mainEntityOfPage"]["@type"]).to eql("WebPage")
|
||||
expect(subject["mainEntityOfPage"]).to have_key("@id")
|
||||
expect(subject["mainEntityOfPage"]["@id"]).to eql("/page.html")
|
||||
end
|
||||
|
||||
it "returns sameAs" do
|
||||
expect(subject).to have_key("sameAs")
|
||||
expect(subject["sameAs"]).to be_a(Array)
|
||||
expect(subject["sameAs"]).to eql(%w(a b))
|
||||
end
|
||||
|
||||
it "returns the url" do
|
||||
expect(subject).to have_key("url")
|
||||
expect(subject["url"]).to eql("/page.html")
|
||||
end
|
||||
end
|
|
@ -331,10 +331,8 @@ EOS
|
|||
end
|
||||
|
||||
it "minifies JSON-LD" do
|
||||
expected = <<-EOS
|
||||
{"@context": "http://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": "post",
|
||||
expected = <<-EOS.strip
|
||||
{"@context":"http://schema.org","@type":"BlogPosting","headline":"post",
|
||||
EOS
|
||||
expect(output).to match(expected)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue