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

Merged
merged 37 commits into from Apr 6, 2017

Conversation

Projects
None yet
6 participants
@aav7fl
Contributor

aav7fl commented Jan 16, 2017

  • Add Feature
  • Add Docs
  • Add Tests

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.

aav7fl added some commits Jan 16, 2017

Fix Google Structured Data Requests
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 }},

This comment has been minimized.

@pathawks

pathawks Jan 16, 2017

Member

Shouldn't this be name?

This comment has been minimized.

@aav7fl

aav7fl Jan 16, 2017

Contributor

Yes. It should. I'll change that shortly.

@pathawks

This comment has been minimized.

Member

pathawks commented Jan 16, 2017

Does this fix #96?

/cc: @renshuki

@aav7fl

Changed casing.

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Jan 16, 2017

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).

@pathawks

This comment has been minimized.

Member

pathawks commented Jan 16, 2017

I can get around to that soon. It's something I would like to add as well.

I was just curious. We've got a PR for that in #103 👍

@aav7fl aav7fl changed the title from Add Author/Name tags in JSON metadata to Add tags to JSON metadata Jan 17, 2017

Add the rest of the JSON tags to pass blogPosting Errors/Warnings
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).
@aav7fl

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 %}

This comment has been minimized.

@aav7fl

aav7fl Jan 17, 2017

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.

@@ -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 %}

This comment has been minimized.

@aav7fl

aav7fl Jan 17, 2017

Contributor

Add Author Name

{% if seo_author_name %}
"author": {{ seo_author_name | jsonify }},
{% endif %}

This comment has been minimized.

@aav7fl

aav7fl Jan 17, 2017

Contributor

Add Author Name

},
{% else %}
"image": {{ seo_page_image | jsonify }},
{% endif %}

This comment has been minimized.

@aav7fl

aav7fl Jan 17, 2017

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.

This comment has been minimized.

@benbalter

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).

{% elseif page.date %}
"dateModified": {{ page.date | date_to_xmlschema | jsonify }},
{% endif %}

This comment has been minimized.

@aav7fl

aav7fl Jan 17, 2017

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.

{% 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 %}

This comment has been minimized.

@aav7fl

aav7fl Jan 17, 2017

Contributor

Add Author Name.

"@id": {{ page.url | replace:'/index.html','/' | absolute_url | jsonify }}
},
{% endif %}

This comment has been minimized.

@aav7fl

aav7fl Jan 17, 2017

Contributor

Add mainEntityOfPage when BlogPosting type is chosen.
Better explained in this StackOverflow post.

This comment has been minimized.

@jhabdas

jhabdas Feb 15, 2017

Contributor

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.

This comment has been minimized.

@aav7fl

aav7fl Feb 15, 2017

Contributor

Thanks! I've added this to my local branch, along with a test.

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Jan 17, 2017

Whoops. Wrong language. Left an 'e' in my elsif.
Fixed.

Fix language mistake
Well.... looks like I added an 'e'. Whoops.
@aav7fl

Removed a silly letter ('e').

Add pull request documentation
Adds documentation on new image behavior, dateModified, and author field.
@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Jan 17, 2017

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.

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Jan 18, 2017

This makes changes to the JSON-LD information. Fixes warning/errors reported by Google Structured Data Testing Tool.

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 %}

This comment has been minimized.

@aav7fl

aav7fl Jan 25, 2017

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).

This comment has been minimized.

@pathawks

pathawks Jan 25, 2017

Member

I am still 👎 on this with out a clear use case

This comment has been minimized.

@DirtyF

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?

This comment has been minimized.

@renshuki

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 😃

@aav7fl

Write explanations for code changes.

{% if seo_author %}
<meta name="author" content="{{ seo_author }}" />
{% endif %}

This comment has been minimized.

@pathawks

pathawks Jan 25, 2017

Member

I am still 👎 on this with out a clear use case

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Jan 25, 2017

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.

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Apr 3, 2017

@jhabdas I like that idea. It would help me remove the blocking code and get this accepted if it's ok that there are two features here (Date modified and author field).

I'm going to remove the image changes from this PR.

aav7fl added some commits Apr 3, 2017

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Apr 3, 2017

@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.

This comment has been minimized.

@jhabdas

jhabdas Apr 3, 2017

Contributor

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.

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

Contributor

On it.

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

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.
@@ -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") }

This comment has been minimized.

@jhabdas

jhabdas Apr 3, 2017

Contributor

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?

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

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.

This comment has been minimized.

@jhabdas

jhabdas Apr 3, 2017

Contributor

I'll defer this one. I don't have the experience with tests to make a good judgement here. Just wafting around code smell. 💨

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

Contributor

Maybe we'll save it for when we refactor the tests to bring our coverage back up.

This comment has been minimized.

@pathawks

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.

@jhabdas

This comment has been minimized.

Contributor

jhabdas commented Apr 3, 2017

This is looking great! Much easier to grok now. Just one small question/comment about the test logic and I'm a :shipit: personally.

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Apr 3, 2017

Alright. It should be ready now.

@pathawks

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") }

This comment has been minimized.

@pathawks

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.

end
context "with page author" do
let(:site) { make_site("logo" => "/logo.png", "url" => "http://example.invalid") }

This comment has been minimized.

@pathawks

pathawks Apr 3, 2017

Member

Is this necessary here? Context is "with page author" says nothing about logo.

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

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.

http://i.imgur.com/xnu0JG7.png

This comment has been minimized.

@pathawks

pathawks Apr 3, 2017

Member

Sorry, I was referring to the logo bits. Is that necessary here?

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

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.

@@ -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 %}

This comment has been minimized.

@pathawks

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?

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

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.

This comment has been minimized.

@pathawks

pathawks Apr 3, 2017

Member

It would seem that if date_modified or similar is not set, we do not have a value available.

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

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.

This comment has been minimized.

@aav7fl

aav7fl Apr 3, 2017

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

This comment has been minimized.

@pathawks

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.

This comment has been minimized.

@aav7fl

aav7fl Apr 4, 2017

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.

@benbalter

Nice work! Thanks for working through the feedback.

@benbalter benbalter referenced this pull request Apr 4, 2017

Merged

Add og:locale support #166

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Apr 4, 2017

Thanks for working with me on this!

aav7fl added some commits Apr 4, 2017

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Apr 4, 2017

@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!

@benbalter

This comment has been minimized.

Collaborator

benbalter commented Apr 6, 2017

Think this can be merged now?

@aav7fl

This comment has been minimized.

Contributor

aav7fl commented Apr 6, 2017

It looks good to me. 😃

@benbalter benbalter merged commit 11cd72c into jekyll:master Apr 6, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@pathawks

This comment has been minimized.

Member

pathawks commented Apr 6, 2017

@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 👍🎉

@benbalter

This comment has been minimized.

Collaborator

benbalter commented Apr 6, 2017

Thanks @aav7fl! 🥇 🌵 🍰

@benbalter

This comment has been minimized.

Collaborator

benbalter commented Apr 6, 2017

Going to get a new release out right now with this in it.

@jhabdas

This comment has been minimized.

Contributor

jhabdas commented Apr 6, 2017

\o/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment