Multiple entities in schema.org - schema.org

How do I nest one or multiple recipes in a NewsArticle or BlogPosting.
I tried this but Google's Structured Data Testing Tool throws an error complaining about recipe1 key. I'm not sure what to change recipe1 key to:
<script type="application/ld+json">
{
"#context" : "http://schema.org",
"#type" : "NewsArticle",
"author" : { "#type" : "Person",
"name" : "hgezim"
},
"dateModified" : "2016-09-21T06:25:35+00:00",
"datePublished" : "2016-09-21T06:25:35+00:00",
"headline" : "Chicken Papriak",
"mainEntityOfPage" : "http://localhost:8080/2016/09/21/chicken-papriak/",
"publisher" : { "#type" : "Organization",
"name" : "Dev Blog"
},
"recipe1": {
"#context": "http://schema.org",
"#type": "Recipe",
"author": "John Smith",
"cookTime": "PT1H",
"datePublished": "2009-05-08",
"description": "This classic banana bread recipe comes from my mom -- the walnuts add a nice texture and flavor to the banana bread.",
"image": "bananabread.jpg",
"recipeIngredient": [
"3 or 4 ripe bananas, smashed",
"1 egg",
"3/4 cup of sugar"
],
"interactionStatistic": {
"#type": "InteractionCounter",
"interactionType": "http://schema.org/Comment",
"userInteractionCount": "140"
},
"name": "Mom's World Famous Banana Bread",
"nutrition": {
"#type": "NutritionInformation",
"calories": "240 calories",
"fatContent": "9 grams fat"
},
"prepTime": "PT15M",
"recipeInstructions": "Preheat the oven to 350 degrees. Mix in the ingredients in a bowl. Add the flour last. Pour the mixture into a loaf pan and bake for one hour.",
"recipeYield": "1 loaf",
"suitableForDiet": "http://schema.org/LowFatDiet"
}
}
</script>

It depends on how the entities are related to each other. You have to use a property that is defined to convey this relation.
To look for a suitable property, check BlogPosting for properties that have Recipe or one of its parent types (CreativeWork, Thing) as expected value.
For example:
about could be used if the blog post is about this specific recipe (e.g., you describe how you liked it)
hasPart could be used if the recipe forms a part of the blog post
mentions could be used if you just reference this recipe in the blog post
…

Thanks #unor. I've used hasPart as follows:
<script type="application/ld+json">
{ "#context" : "http://schema.org",
"#type" : "NewsArticle",
"author" : { "#type" : "Person",
"name" : "hgezim"
},
"dateModified" : "2016-09-21T06:25:35+00:00",
"datePublished" : "2016-09-21T06:25:35+00:00",
"hasPart" : { "#context" : "http://schema.org",
"#type" : "Recipe",
"author" : "John Smith",
"cookTime" : "PT1H",
"datePublished" : "2009-05-08",
"description" : "This classic banana bread recipe comes from my mom -- the walnuts add a nice texture and flavor to the banana bread.",
"image" : "bananabread.jpg",
"interactionStatistic" : { "#type" : "InteractionCounter",
"interactionType" : "http://schema.org/Comment",
"userInteractionCount" : "140"
},
"name" : "Mom's World Famous Banana Bread",
"nutrition" : { "#type" : "NutritionInformation",
"calories" : "240 calories",
"fatContent" : "9 grams fat"
},
"prepTime" : "PT15M",
"recipeIngredient" : [ "3 or 4 ripe bananas, smashed",
"1 egg",
"3/4 cup of sugar"
],
"recipeInstructions" : "Preheat the oven to 350 degrees. Mix in the ingredients in a bowl. Add the flour last. Pour the mixture into a loaf pan and bake for one hour.",
"recipeYield" : "1 loaf",
"suitableForDiet" : "http://schema.org/LowFatDiet"
},
"headline" : "Chicken Papriak",
"mainEntityOfPage" : "http://localhost:8080/2016/09/21/chicken-papriak/",
"publisher" : { "#type" : "Organization",
"name" : "Dev Blog"
}
}
</script>
It validates as validates JSON-LD.

Related

Simple JOLT transformation. Add one level and paste part of attributes here

Please, help to modify next json. I need add one level and paste part of attributes here.
Input:
{
"Name" : "Some order",
"Status" : "New",
"Project" : "Some project",
"Goal" : "Some goal",
"Urgency" : "",
"URL" : "",
"table_name": "Order"
}
Desired output:
{
"row": {
"Name" : "Some order",
"Status" : "New",
"Project" : "Some project",
"Goal" : "Some goal",
"Urgency" : "",
"URL" : ""
},
"table_name": "Order"
}
If you have some cool sources about JOLT, please, share.
You can use the following shift transformation spec
[
{
"operation": "shift",
"spec": {
"table_name": "&",
"*": "row.&"
}
}
]
where you just need to nest the elements under row key other than the element with table_name key. &(&0) represents the nearest key(without going up any level, eg. in that case you would need to use &1,&2...etc in order to go 1,2,.. levels up)
You can check this site out as a nice reference.

"description" vs. "reviewBody" for Review

I am wondering what is the right Schema.org use for a review in a product. I see two different suggestions:
Majory of sites I've checked use this structure:
"review": {
"#type": "Review",
"author": "Daniela",
"datePublished": "2016-11-01",
"description": "Fantastic product! It really helped me. I would recommend to all my friends and family.",
"name": "Awesome!",
"reviewRating": {
"#type": "Rating",
"bestRating": "5",
"ratingValue": "5",
"worstRating": "1"
}
}
And it's correctly validated in structured data test tool.
However structured data helper and docs show this format:
"review" : {
"#type" : "Review",
"author" : {
"#type" : "Person",
"name" : "Daniela"
},
"datePublished" : "2017-06-08",
"reviewRating" : {
"#type" : "Rating",
"ratingValue" : "5",
"bestRating" : "5",
"worstRating" : "0"
},
"reviewBody" : "Fantastic product! It really helped me. I would recommend to all my friends and family. "
}
They are similar, the only big difference is description vs. reviewBody.
Which is correct?
They are different properties:
description gives a (typically short) description/summary/teaser of the review
reviewBody gives the full review
There is no reason to choose only one here. If you have the data for both, you can use both properties.
For Google’s Review rich result, simply check the documentation:
for a "Critic review", description is required
for a "Review snippet", reviewBody is recommended

Schema.org TVEpisode entries for multi-source playback page

I'm expanding a static site with playable videos contextualized in a TV Series and I would like to know how to properly fill in the tags url and datePublished.
Currently, with only one embeddable source, the JSON-LD generated is:
<script type="application/ld+json">
{
"#context" : "http://schema.org",
"#type" : "TVEpisode",
"partOfTVSeries" : {
"#type" : "TVSeries",
"name" : "Name of the Show"
},
"keywords": "a,list,of,comma,separated,tags",
"partOfSeason" : {
"#type" : "TVSeason",
"seasonNumber" : "1"
},
"episodeNumber" : "1",
"image" : "absolute/path/to/video/image.jpg",
"url" : "permalink",
"review" : {
"#type" : "Review",
"author" : {
"#type" : "Person",
"name" : "Summary Author Name"
},
"reviewBody" : "Summary"
}
}
</script>
With only one embeddable source it was just a matter of using the template functions to retrieve the Permalink and the Date in which the video has been published.
But I don't know how to do it for multiple sources.
I tried to simply duplicate the whole block, simulating an iteration, changing the mentioned values but when testing with Structured Data Testing Tool, although no errors were reported, the second entry was ignored.
In JSON-LD, if you have multiple values for a property, you have to use an array as value instead of repeating the property.
You could provide multiple VideoObject items for the TVEpisode, by using TVEpisode’s associatedMedia/encoding property:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "TVEpisode",
"associatedMedia": [
{
"#type": "VideoObject",
"name": "Source 1"
},
{
"#type": "VideoObject",
"name": "Source 2"
}
]
}
</script>
Now you can differentiate between the metadata for the TV episode and for its videos.

How to do either operation in IRItemplate in a Hydra:Operation?

My hydra vocab is similar to Markus-lanthaler Vocab.Here is one of my operation on User Class to retrieve collection of Users.
{
"#id": "payu:retrieve_users",
"#type": "hydra:Operation",
"method": "GET",
"label": "Retrieve users",
"description": "Retrieves Users",
"expects": null,
"returns": "hydra:Collection",
"IriTemplate" : {
"#type" : "IriTemplate",
"template" : "{?userIds,firstName,lastName}",
"variableRepresentation": "BasicRepresentation",
"mapping" : [
{
"#type" : "IriTemplateMapping",
"variable" : "userIds",
"property" : "hydra:property",
"required" : false
},
{
"#type" : "IriTemplateMapping",
"variable" : "firstName",
"property" : "hydra:property",
"required" : false
},
{
"#type" : "IriTemplateMapping",
"variable" : "lastName",
"property" : "hydra:property",
"required" : false
}
]
}
}
As you can see in IRItemplate
"template" : "{?userIds,firstName,lastName}"
so I want to get control over retrieve either a third person will be able to retrieve through (userIds) or (firstName,lastName).
Should I make two separate hydra Operations having IRItemplate :
In First Operation:
"template" : "{?userIds}"
In Second Operation:
"template" : "{?firstName,lastName}"
Or Is there any existing way to do this in Hydra Specification using single operation ?
Currently there's no way to specify that for a single operation. You'll need to have two operations. Also, you need to associate the operation to the IriTemplate and not the other way round:
{
"#type" : "IriTemplate",
"template" : "{?userIds,firstName,lastName}",
...
"operation": {
"#id": "payu:retrieve_users",
"#type": "hydra:Operation",
"method": "GET",
...
}
}

Get a collection of sub-resources at once with JSON-LD and Hydra

In the RESTful Web API book, the authors advise to expose a profile and use a content type which acknowledges link relations. JSON-LD extended by Hydra seem to match these requirements, and I want to use them in the design of my new API.
I am currently stuck with a performance issue. Let say that I have an online bike store, and I want to retrieve information about the wheels of a given bike.
With the Hydra specification, it seems to me that I need to send 2 requests to get the details about the wheels.
The first request is toward the bike itself:
GET /mybike HTTP/1.1
Host: wowbike.com
The response contains a Hydra::Link to the collection of wheels:
HTTP/1.1 200 OK
Content-Type: application/ld+json
{
"#context" :
{
"Bike": "/contexts/vocab#Bike"
},
"#id" : "/mybike",
"#type" : "Bike",
"size" : "L",
"wheels" : "/mybike/wheels" // "wheels" is a "hydra:Link"
}
Now I can send a second request to the wheels resource to get the details:
GET /mybike/wheels HTTP/1.1
Host: wowbike.com
HTTP/1.1 200 OK
Content-Type: application/ld+json
{
"#context":
{
"Collection": "http://www.w3.org/ns/hydra/core#Collection",
"Wheel" : "/contexts/vocab#Wheel"
},
"#type" : "Collection",
"#id" : "/mybike/wheels",
"member" :
[
{
"#id" : "/mybike/wheels/firstwheel",
"#type" : "Wheel",
"color" : "blue"
},
{
"#id" : "/mybike/wheels/secondwheel",
"#type" : "Wheel",
"color" : "white"
}
]
}
Is it valid to send a single request and get a response such as the one below?
GET /mybike HTTP/1.1
Host: wowbike.com
HTTP/1.1 200 OK
Content-Type: application/ld+json
{
"#context" :
{
"Collection": "http://www.w3.org/ns/hydra/core#Collection",
"Bike" : "/contexts/vocab#Bike",
"Wheel" : "/contexts/vocab#Wheel"
},
"#id" : "/mybike",
"#type" : "Bike",
"size" : "L",
"wheels" :
{
"#id" : "/mybike/wheels",
"#type" : "Link",
"member":
[
{
"#id" : "/mybike/wheels/firstwheel",
"#type" : "Wheel",
"color" : "blue"
},
{
"#id" : "/mybike/wheels/secondwheel",
"#type" : "Wheel",
"color" : "white"
}
]
}
}
Great to see that you consider using JSON-LD and Hydra. Of course it is possible to get all the data in a single response. You don't have to change the type of the collection from Collection to Link though. Also, you might want to tweak your context a bit. Summed up, your response would look somewhat like this:
{
"#context": [
"http://www.w3.org/ns/hydra/context.jsonld",
{ "#vocab": "/contexts/vocab#" }
],
"#id": "/mybike",
"#type": "Bike",
"size": "L",
"wheels": {
"#id" : "/mybike/wheels",
"#type" : "Collection",
"member": [
{
"#id" : "/mybike/wheels/firstwheel",
"#type" : "Wheel",
"color" : "blue"
},
{
"#id" : "/mybike/wheels/secondwheel",
"#type" : "Wheel",
"color" : "white"
}
]
}
}
I'm importing Hydra's context here and then overlaying a default vocabulary which means that everything that isn't already defined in Hydra's context is expanded by appending it to /contexts/vocab#. So, Bike for instance will be expanded to /contexts/vocab#Bike.
Btw. there's a W3C Community Groupw working on Hydra which you should join if you are using it. We also have a mailing list on which all your questions will be answered.
The instructions to join the group can be found at http://www.hydra-cg.com/#community