Add tags to JSON metadata #151
Conversation
Fixes missing author and name in blogPosting types with organization.
@@ -221,6 +228,9 @@ | |||
{% if seo_site_logo %} | |||
"publisher": { | |||
"@type": "Organization", | |||
{% if seo_author_name %} | |||
"Name": {{ seo_author_name | jsonify }}, |
aav7fl
Jan 16, 2017
Author
Contributor
Yes. It should. I'll change that shortly.
Yes. It should. I'll change that shortly.
Changed casing. |
It does not fix #96. I can get around to that soon. It's something I would like to add as well. This only adds the proper JSON tags to pass the errors (but not the warnings). |
I was just curious. We've got a PR for that in #103 |
This adds the rest of the JSON fields to pass all errors and blog postings. - Adds page.image.url for the image url. (Will default to image if not present). - Add page.image.height and page.image.width for an image object (Will default back to image url if not present). - Add dateModified (will capture from yaml if present, if not it will use datePublished) - (I feel there should be a manual option for this as I sometimes save parts of my blog that shouldn't update the modified field, but still change the file timestamp). This should create JSON that will pass all warnings/strong recommendations/errors from [Google's Structured Data Testing Tool](https://search.google.com/structured-data/testing-tool).
Proposing a few changes following the already present code styling. I would love to have these feature implemented as they clear all warnings/errors in the JSON; leaving it properly formatted. |
@@ -89,7 +92,7 @@ | |||
{% endif %} | |||
|
|||
{% if page.image %} | |||
{% assign seo_page_image = page.image.path | default: page.image.facebook | default: page.image %} | |||
{% assign seo_page_image = page.image.path | default: page.image.url | default: page.image.facebook | default: page.image %} |
aav7fl
Jan 17, 2017
Author
Contributor
Allow for page.image.url here, else there will be a mess of if interpreting the yaml object when it encounters this unknown yaml field.
Allow for page.image.url here, else there will be a mess of if interpreting the yaml object when it encounters this unknown yaml field.
@@ -62,6 +62,9 @@ | |||
{% endif %} | |||
{% endif %} | |||
{% assign seo_author_twitter = seo_author_twitter | replace:"@","" %} | |||
{% if seo_author.name %} | |||
{% assign seo_author_name = seo_author.name %} | |||
{% endif %} |
aav7fl
Jan 17, 2017
Author
Contributor
Add Author Name
Add Author Name
{% if seo_author_name %} | ||
"author": {{ seo_author_name | jsonify }}, | ||
{% endif %} | ||
|
aav7fl
Jan 17, 2017
Author
Contributor
Add Author Name
Add Author Name
}, | ||
{% else %} | ||
"image": {{ seo_page_image | jsonify }}, | ||
{% endif %} |
aav7fl
Jan 17, 2017
Author
Contributor
Create image object (as it needs). Height and width are probably required now for some future thinking. Think AMP where they require this information in the markup.
Will default back if either no width/height are present, or if no image url is present.
Create image object (as it needs). Height and width are probably required now for some future thinking. Think AMP where they require this information in the markup.
Will default back if either no width/height are present, or if no image url is present.
benbalter
Feb 15, 2017
Collaborator
For a future iteration, it'd be great if we could calculate the height and width for local images (assuming we can do so safely without adding something like imagemagic).
For a future iteration, it'd be great if we could calculate the height and width for local images (assuming we can do so safely without adding something like imagemagic).
{% elseif page.date %} | ||
"dateModified": {{ page.date | date_to_xmlschema | jsonify }}, | ||
{% endif %} | ||
|
aav7fl
Jan 17, 2017
Author
Contributor
Add a date modified field. Useful when wanting to control this manually. Like when I make a change to the markup file, but I want to override the timestamp given.
Will default to page.date if never "modified". Will not exist if neither field present.
Add a date modified field. Useful when wanting to control this manually. Like when I make a change to the markup file, but I want to override the timestamp given.
Will default to page.date if never "modified". Will not exist if neither field present.
{% if seo_description %} | ||
"description": {{ seo_description | jsonify }}, | ||
{% endif %} | ||
|
||
{% if seo_site_logo %} | ||
"publisher": { | ||
"@type": "Organization", | ||
{% if seo_author_name %} | ||
"name": {{ seo_author_name | jsonify }}, | ||
{% endif %} |
aav7fl
Jan 17, 2017
Author
Contributor
Add Author Name.
Add Author Name.
"@id": {{ page.url | replace:'/index.html','/' | absolute_url | jsonify }} | ||
}, | ||
{% endif %} | ||
|
aav7fl
Jan 17, 2017
Author
Contributor
Add mainEntityOfPage when BlogPosting type is chosen.
Better explained in this StackOverflow post.
Add mainEntityOfPage when BlogPosting type is chosen.
Better explained in this StackOverflow post.
ghost
Feb 15, 2017
I tried read that post 6 six times, studied Schema.org and still couldn't understand this until I saw your example. 😂 Given Schema.org says all webpages are implicitly of Type WebPage (if not defined) this makes sense. Given this tag also applies to "CreativeWork", it would be useful to add that here while we're making this change as it will help with Structured Data validation for that common type.
I tried read that post 6 six times, studied Schema.org and still couldn't understand this until I saw your example.
aav7fl
Feb 15, 2017
Author
Contributor
Thanks! I've added this to my local branch, along with a test.
Thanks! I've added this to my local branch, along with a test.
Whoops. Wrong language. Left an 'e' in my elsif. |
Well.... looks like I added an 'e'. Whoops.
Removed a silly letter ('e'). |
Adds documentation on new image behavior, dateModified, and author field.
Added updated documentation for changes. Working on tests next. Also noticed a small change I needed to make. It will be in a new pull eventually. |
Travis didn't like my date/dateModified tests because of time-zone issues. I had to pull those specific ones. Fixed up the rubocop styling. Looks like everything is good for an inspection. |
{% if seo_author %} | ||
<meta name="author" content="{{ seo_author }}" /> | ||
{% endif %} | ||
|
aav7fl
Jan 25, 2017
Author
Contributor
Added in content of PR #103 along with tests (because it made sense to add the author meta field when I was already doing it in the JSON).
Added in content of PR #103 along with tests (because it made sense to add the author meta field when I was already doing it in the JSON).
pathawks
Jan 25, 2017
Member
I am still 👎 on this with out a clear use case
I am still
DirtyF
Jan 25, 2017
•
Member
meta author is not recognized by Google (https://support.google.com/webmasters/answer/79812?hl=en) et was deprecated in favor of Rich Snippets. What is the intent in adding this if it is ignored by search engines?
meta author is not recognized by Google (https://support.google.com/webmasters/answer/79812?hl=en) et was deprecated in favor of Rich Snippets. What is the intent in adding this if it is ignored by search engines?
renshuki
Jan 26, 2017
Contributor
Well it's ignored by Google but not by Facebook. The purpose of this change is to show up the author name of an article when you share it on Facebook. If the meta name="author"
is not set the author name will not be displayed when you share a jekyll blog article on Facebook (Issue #96). If the author of the article has a Facebook account you can use the meta property="article:author"
which his ID / profile URL instead but it's not always the case.
If someone have any other suggestion to resolve this problem it would be greatly appreciated 😃
Well it's ignored by Google but not by Facebook. The purpose of this change is to show up the author name of an article when you share it on Facebook. If the meta name="author"
is not set the author name will not be displayed when you share a jekyll blog article on Facebook (Issue #96). If the author of the article has a Facebook account you can use the meta property="article:author"
which his ID / profile URL instead but it's not always the case.
If someone have any other suggestion to resolve this problem it would be greatly appreciated
Write explanations for code changes. |
{% if seo_author %} | ||
<meta name="author" content="{{ seo_author }}" /> | ||
{% endif %} | ||
|
pathawks
Jan 25, 2017
Member
I am still 👎 on this with out a clear use case
I am still
Ok. Yea. I guess I'm stuck in the past. I can't find any good documentation that clearly states that it is used anymore. Even for markup. Most places with use JSON-LD or OG tags. Removing author meta tag & test. |
@benbalter @jhabdas Removed image changes from this PR. #174 is handling image changes. Should be more straight forward if it's ok having these changes in a single PR. If not, I can continue pulling these out, but they seem to go together. Additions in this PR exist to appease Google Structured Data Testing Tool. |
@@ -78,6 +78,8 @@ The SEO tag will respect any of the following if included in your site's `_confi | |||
* `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. | |||
* `date_modified` - (YYYY-MM-DD hh:mm) A manual override for the `dateModified` field in the JSON-LD output. This field will take **first priority** for the `dateModified` output. This is useful when the file timestamp does not match the true time that the content was modified. |
ghost
Apr 3, 2017
•
For clarity, I feel we should mention what's being overridden. Also, given Jekyll supports use of ISO 8601 dates, perhaps it's best if we left any formatting out of the example so as not to lead implementations (which might otherwise choose to include the Timezone offset). Also, and now I'm being persnickety, it would be great if this and the next bullet could be condensed into one.
For clarity, I feel we should mention what's being overridden. Also, given Jekyll supports use of ISO 8601 dates, perhaps it's best if we left any formatting out of the example so as not to lead implementations (which might otherwise choose to include the Timezone offset). Also, and now I'm being persnickety, it would be great if this and the next bullet could be condensed into one.
aav7fl
Apr 3, 2017
Author
Contributor
On it.
On it.
aav7fl
Apr 3, 2017
•
Author
Contributor
How about this:
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 which will offer an alternative way of providing for the dateModified
field.
How about this:
date_modified
- Manually specify thedateModified
field in the JSON-LD output to override Jekyll's owndateModified
. This field will take first priority for thedateModified
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 which will offer an alternative way of providing for thedateModified
field.
@@ -237,11 +237,49 @@ | |||
end | |||
|
|||
context "with absolute site.logo" do | |||
let(:site) { make_site("logo" => "http://cdn.example.invalid/logo.png", "url" => "http://example.invalid") } | |||
let(:site) { make_site("logo" => "http://cdn.example.invalid/logo.png", "url" => "http://example.invalid", "author" => "Mr. Foo") } |
ghost
Apr 3, 2017
Feels like this should be broken into a different context so we're not conflating test logic between existing and new features. Does that make sense?
Feels like this should be broken into a different context so we're not conflating test logic between existing and new features. Does that make sense?
aav7fl
Apr 3, 2017
•
Author
Contributor
I guess. But it feels like there are unnecessary LOC when the actual test is given with context in line 246.
Mostly because I remember a talk about refactoring to shrink things down; wondered if this would be part of that example.
I guess. But it feels like there are unnecessary LOC when the actual test is given with context in line 246.
Mostly because I remember a talk about refactoring to shrink things down; wondered if this would be part of that example.
ghost
Apr 3, 2017
I'll defer this one. I don't have the experience with tests to make a good judgement here. Just wafting around code smell. 💨
I'll defer this one. I don't have the experience with tests to make a good judgement here. Just wafting around code smell.
aav7fl
Apr 3, 2017
Author
Contributor
Maybe we'll save it for when we refactor the tests to bring our coverage back up.
Maybe we'll save it for when we refactor the tests to bring our coverage back up.
pathawks
Apr 3, 2017
Member
I don't think I understand the connection between author
and logo
.
If we're adding something new, we should add new tests, not modify existing tests.
I don't think I understand the connection between author
and logo
.
If we're adding something new, we should add new tests, not modify existing tests.
This is looking great! Much easier to grok now. Just one small question/comment about the test logic and I'm a |
Alright. It should be ready now. |
I’ve requested a few clarifications. Overall, I’m excited for this and think it will improve our plugin |
@@ -237,11 +237,49 @@ | |||
end | |||
|
|||
context "with absolute site.logo" do | |||
let(:site) { make_site("logo" => "http://cdn.example.invalid/logo.png", "url" => "http://example.invalid") } | |||
let(:site) { make_site("logo" => "http://cdn.example.invalid/logo.png", "url" => "http://example.invalid", "author" => "Mr. Foo") } |
pathawks
Apr 3, 2017
Member
I don't think I understand the connection between author
and logo
.
If we're adding something new, we should add new tests, not modify existing tests.
I don't think I understand the connection between author
and logo
.
If we're adding something new, we should add new tests, not modify existing tests.
end | ||
|
||
context "with page author" do | ||
let(:site) { make_site("logo" => "/logo.png", "url" => "http://example.invalid") } |
pathawks
Apr 3, 2017
Member
Is this necessary here? Context is "with page author"
says nothing about logo.
Is this necessary here? Context is "with page author"
says nothing about logo.
aav7fl
Apr 3, 2017
Author
Contributor
Sure. The lovely Google Structured Data Testing Tool complains when the publisher object (required to pass..) does not have a name. For the purposes of a blog (What Jekyll is), the name is the author.
Sure. The lovely Google Structured Data Testing Tool complains when the publisher object (required to pass..) does not have a name. For the purposes of a blog (What Jekyll is), the name is the author.
pathawks
Apr 3, 2017
Member
Sorry, I was referring to the logo
bits. Is that necessary here?
Sorry, I was referring to the logo
bits. Is that necessary here?
aav7fl
Apr 3, 2017
Author
Contributor
Kind of. I think I understand what you are asking;
If I have the publisher object
"publisher": {"@type": "Organization",
"name": "Kyle Niewiada",
"logo": {"@type": "ImageObject",
"url": "https://www.kyleniewiada.org/assets/img/logo.png"}},
I need to have both logo and author together. If I remove just the author, it's an error. If I remove just the logo, it's an error. So they need to be both implemented together. That means when I make the site in the test, I need the logo and the author together.
Kind of. I think I understand what you are asking;
If I have the publisher object
"publisher": {"@type": "Organization",
"name": "Kyle Niewiada",
"logo": {"@type": "ImageObject",
"url": "https://www.kyleniewiada.org/assets/img/logo.png"}},
I need to have both logo and author together. If I remove just the author, it's an error. If I remove just the logo, it's an error. So they need to be both implemented together. That means when I make the site in the test, I need the logo and the author together.
@@ -65,6 +65,10 @@ | |||
{% assign seo_author_twitter = seo_author_twitter | replace:"@","" %} | |||
{% endif %} | |||
|
|||
{% if page.date_modified or page.last_modified_at or page.date %} | |||
{% assign seo_date_modified = page.seo.date_modified | default: page.last_modified_at | default: page.date %} |
pathawks
Apr 3, 2017
Member
I don't know if we want to set seo_date_modified
at all if all we have is page.date
. What is the motivation?
I don't know if we want to set seo_date_modified
at all if all we have is page.date
. What is the motivation?
aav7fl
Apr 3, 2017
•
Author
Contributor
Google will complain if there is no "dateModified", even if it is the exact same.
The dateModified field is recommended. Please provide a value if available.
Google will complain if there is no "dateModified", even if it is the exact same.
The dateModified field is recommended. Please provide a value if available.
pathawks
Apr 3, 2017
Member
It would seem that if date_modified
or similar is not set, we do not have a value available.
It would seem that if date_modified
or similar is not set, we do not have a value available.
aav7fl
Apr 3, 2017
•
Author
Contributor
I would hope so, but the warning from their tool gives no indication if missing this field is a 'include it if you use it, ignore it if you don't", I can leave it out. But I wanted to remove all warnings in case it had an impact. I would like to keep it because of the warning, but I will take it out if you request.
I would hope so, but the warning from their tool gives no indication if missing this field is a 'include it if you use it, ignore it if you don't", I can leave it out. But I wanted to remove all warnings in case it had an impact. I would like to keep it because of the warning, but I will take it out if you request.
aav7fl
Apr 3, 2017
Author
Contributor
Addition: When I check out websites that already use JSON-LD, I note that they use dateModified even if it is the same as the publish date.
view-source:http://www.theverge.com/2017/4/3/15123170/bmw-520i-2017-5-series-review
Addition: When I check out websites that already use JSON-LD, I note that they use dateModified even if it is the same as the publish date.
view-source:http://www.theverge.com/2017/4/3/15123170/bmw-520i-2017-5-series-review
pathawks
Apr 4, 2017
Member
The difference between this plugin and The Verge is that they control every aspect of their site, and this plugin has to serve a more general use case. We have no way of knowing that a document’s date is the same as (or even a good approximation of) its updated date. I assert that the absence of data is better than made up daya.
When you say “Google will complain,” do you mean validation fails, or Google complains loudly? If validation fails, I guess we'll do what's needed to fix that. If it's merely a warning, that seems like A Good Thing! Publishers should be made aware that including modified information is an important thing to do, and we can't just hand-wave over that.
The difference between this plugin and The Verge is that they control every aspect of their site, and this plugin has to serve a more general use case. We have no way of knowing that a document’s date is the same as (or even a good approximation of) its updated date. I assert that the absence of data is better than made up daya.
When you say “Google will complain,” do you mean validation fails, or Google complains loudly? If validation fails, I guess we'll do what's needed to fix that. If it's merely a warning, that seems like A Good Thing! Publishers should be made aware that including modified information is an important thing to do, and we can't just hand-wave over that.
aav7fl
Apr 4, 2017
Author
Contributor
It's merely a warning.
That is a valid point that the document's date is not the same as its upload date.
I will pull that last default snippet to exclude the page.date
.
It's merely a warning.
That is a valid point that the document's date is not the same as its upload date.
I will pull that last default snippet to exclude the page.date
.
Nice work! Thanks for working through the feedback. |
Thanks for working with me on this! |
@pathawks Date handling complete. Thanks for pointing out that the file date may not properly represent the publish date; and all of the other valid points that I missed along the way! |
Think this can be merged now? |
It looks good to me. |
@benbalter Yes, LGTM. Sorry; I didn't realize that I was the one holding things up. @aav7fl Thanks for making those changes, and for your patience. This will be a great addition to the plugin |
Thanks @aav7fl! |
Going to get a new release out right now with this in it. |
\o/ |
This is just to add in the Author field (which is helpful for blog posts/articles when searching for articles + rich text formatting from Google).
This also allows the Google Structured Data Testing Tool to pass without any errors for the type BlogPosting (now there are only warnings).
BlogPosting was chosen instead of WebSite because of Google will treat this content type differently when it displays Rich Cards.