-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add tags to JSON metadata #151
Conversation
Fixes missing author and name in blogPosting types with organization.
lib/template.html
Outdated
@@ -221,6 +228,9 @@ | |||
{% if seo_site_logo %} | |||
"publisher": { | |||
"@type": "Organization", | |||
{% if seo_author_name %} | |||
"Name": {{ seo_author_name | jsonify }}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be name
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It should. I'll change that shortly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
lib/template.html
Outdated
@@ -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 %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
lib/template.html
Outdated
@@ -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 %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add Author Name
lib/template.html
Outdated
{% if seo_author_name %} | ||
"author": {{ seo_author_name | jsonify }}, | ||
{% endif %} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add Author Name
lib/template.html
Outdated
}, | ||
{% else %} | ||
"image": {{ seo_page_image | jsonify }}, | ||
{% endif %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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).
lib/template.html
Outdated
{% elseif page.date %} | ||
"dateModified": {{ page.date | date_to_xmlschema | jsonify }}, | ||
{% endif %} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
lib/template.html
Outdated
{% 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 %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add Author Name.
lib/template.html
Outdated
"@id": {{ page.url | replace:'/index.html','/' | absolute_url | jsonify }} | ||
}, | ||
{% endif %} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add mainEntityOfPage when BlogPosting type is chosen.
Better explained in this StackOverflow post.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
lib/template.html
Outdated
{% if seo_author %} | ||
<meta name="author" content="{{ seo_author }}" /> | ||
{% endif %} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still 👎 on this with out a clear use case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write explanations for code changes.
lib/template.html
Outdated
{% if seo_author %} | ||
<meta name="author" content="{{ seo_author }}" /> | ||
{% endif %} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still 👎 on this with out a clear use case
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. |
README.md
Outdated
@@ -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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
spec/jekyll_seo_tag_spec.rb
Outdated
@@ -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") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll defer this one. I don't have the experience with tests to make a good judgement here. Just wafting around code smell. 💨
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we'll save it for when we refactor the tests to bring our coverage back up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve requested a few clarifications.
Overall, I’m excited for this and think it will improve our plugin 👍
spec/jekyll_seo_tag_spec.rb
Outdated
@@ -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") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary here? Context is "with page author"
says nothing about logo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I was referring to the logo
bits. Is that necessary here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
lib/template.html
Outdated
@@ -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 %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would seem that if date_modified
or similar is not set, we do not have a value available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.