Where to place multiple JSON-LD objects in a webpage? - schema.org

My webapge
I am building a webpage for a conference. The page contains multiple objects like speaker (Person), or session (Event).
My problem
I would like to add semantic data to the page, so that search engines and social networks can easily understand its content. I would like to both describe the page as a whole, and parts of it - like a single session
My question
How do I mark up both the entire page and inner objects in a standard way?
Can I use multiple JSON-LD in the same page, or should I use JSON-LD for the page as a whole and other markups for inner objects?
Clarification, following the comments
Thanks for pointing out the answer to JSON-LD Schema.org: Multiple video/image page. However, it I am not sure where should I put the different JSON-LD objects so that each of them refers to a specific part of the document. Should they be linked using div ids? Should the <script> be placed inside the relevant div?

You can include multiple structured-data elements on a page if you wish as per Google's guideline:
https://developers.google.com/search/docs/guides/sd-policies#multiple-elements-on-a-page
The best way to tell whether it can parse your expected JSON-LD objects and attributes is to use their Structured Data Testing Tool
https://search.google.com/structured-data/testing-tool

I am not sure where should I put the different JSON-LD objects so that each of them refers to a specific part of the document.
With JSON-LD, the structured data is not "coupled" to the HTML. (That would be possible with the syntaxes Microdata and RDFa, but even there, after extracting the structured data, it’s of no relevance anymore on which HTML elements it was specified.)
If you have a page about two persons, you would just provide one WebPage and two Person objects. To be able to make statements about these objects from other places, it’s a good practice to give them URIs, which can be specified with #id. For the WebPage, the URI would typically be the canonical URL of the page.
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebPage",
"#id": "",
"about": [
{
"#type": "Person",
"#id": "#person-1"
},
{
"#type": "Person",
"#id": "#person-2"
}
]
}
</script>
Theoretically, there could be a property which allows you to reference the HTML elements which describe the entity. Schema.org currently has properties like that in Pending, which are used for SpeakableSpecification (Pending): cssSelector (Pending) (using CSS selectors to reference the elements), xpath (Pending) (using XPath to reference the elements). But these can’t be used for other cases (as currently defined). So you would have to define your own property for this purpose.
Should they be linked using div ids?
You could provide the id value in the object’s url property. It doesn’t "link" the HTML to the structured data, though. It just conveys: You can find information about the entity described by this node object by following this URL.
Often each entity has its own page, but it’s perfectly fine to describe multiple entities on the same page, of course.
Expanding the example from above:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "WebPage",
"#id": "",
"about": [
{
"#type": "Person",
"#id": "#person-1",
"url": "#about-person-1"
},
{
"#type": "Person",
"#id": "#person-2",
"url": "#about-person-2"
}
]
}
</script>
Should the <script> be placed inside the relevant div?
For the structured data, it makes no difference where in the HTML document the script elements are placed.
You could place all objects in one script element (like in the examples above), or you could use multiple script elements, but then you should reference their #id values so that you can still make use of properties like about (example in my answer linked above). It makes no difference semantically.

Related

Instructor for a Course provided by Organization in Schema.org

I'm adding structured data to a course web page using Course json-ld markup.
The "provider" field I think is our Organization, because is an online course on our platform and we prepare the material to show during the lessons or, if this material is prepared from the Instructor/Speaker, is subject to approval/editing.
Here is the code:
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "Course",
"name": "Introduction to Trading Online",
"description": "Introductory Trading Online course laying out the basics.",
"image":"https://investire.biz/img/course/1500202_d7cc.jpg",
"provider": {
"#type": "Organization",
"name": "Investire.biz",
"sameAs": "https://investire.biz"
},
"inLanguage": "English",
"audience":{"audienceType":["Beginner trader","No specific knowledge"],"#type":"Audience"}
}
</script>
Which is the correct field for the instructor or speaker?
A Course can’t have a speaker, because it represents the creative work, not a specific instance of this course.
You can provide the instances with the hasCourseInstance property, which takes CourseInstance as value.
And a CourseInstance can have the instructor property:
A person assigned to instruct or provide instructional assistance for the CourseInstance.

How to correctly define schema for non-carousel category page and also satisfy consumer Google

Google mentions here that Carousel markups using ListItem with type, position and item is currently supported only for Recipe, Course and Article. So, doing this for other products is not much effective (looking at google search as the consumer).
Google in another page mentions this:
A category page listing several different products (or recipes, videos, or any other type). Each entity should be marked up using the relevant schema.org type, such as schema.org/Product for product category pages. However, if one item is marked, all items should be marked. Also, unless this is a carousel page, the marked items should not link out to separate details pages.
Note the statement about usage of proper Schema.org type, like Product and should not link to separate details pages.
So, for an online seller of shoes, then the category page will probably be like:
{
"#context": "http://schema.org",
"#type": "CollectionPage",
"#id": "https://www.example.com/cat1/cat2",
"url": "https://www.example.com/cat1/cat2",
"provider": {
"#type": "Organization",
"#id": "https://www.example.com#org"
},
"isPartOf": {
"#type": "WebSite",
"#id": "https://www.example.com#ws"
},
"name": "Running Shoes",
"hasPart": [
{
"#type": "Product",
"name": "shoe 1"
},{
"#type": "Product",
"name": "shoe 2"
},
...
]
}
I didn't use #id and url here, to conform with Google's statement about no link to separate details page. Don't feel comfortable about it.
Q1: Without these, how does this page semantically connect with the schemas of the respective products in other pages?
I didn't define the schema with ItemList as the items are not ordered and without position, SDTT raises error. (Infact, the above schema too raises error on SDTT with hasPart, stating: "Product is not a known valid target type for the hasPart property").
Q2: What is a better way to define this schema, to stay correct as per Schema.org and also not have Google raise errors?
Q3: If we use hasPart here for the products, can we on each of the product's ItemPage define isPartOf to include id-s to this CollectionPage (and other categories', if necessary) where the product is listed? Basically, that closes the loop, but as per schema, is that necessary or just one-way declaration (with 'hasPart' in category page) enough?

How can I add custom attributes to a "Product" type in with JSON-LD?

I have a real estate website which displays real estate properties for sale. For each page where a property is listed, I want to create JSON-LD code to display information about the property, using Schema.org.
I am not sure if there is a better type to use than Product for real estate listings here.
How can I add a custom attribute to describe the property?
Here is a JSON-LD structure for Product:
{
"#context": "https://schema.org/",
"#type": "Product",
"name": "address of the property ",
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"description": "description about the houese"
}
}
I want to be able to add other info like
Primary Features
How many bedrooms it has
How many bathrooms it has
If it is a smart home or not
etc...
Interior Features
Fireplace
Fireplace location
etc...
Exterior Features
The Lots Size
Fets
etc...
How can I add these custom attribute that describes the property using Schema.org?
If you want to provide data about real estate, you need to use a type that represents real estate. Probably Accommodation (Apartment, House, …) for your case.
If you want to convey that this real estate is a product, you need to provide the Product type in addition to the Accommodation type.
Then you can use properties from Accommodation as well as Product.
{
"#context": "https://schema.org/",
"#type": ["House", "Product"],
"offers": {
"#type": "Offer"
},
"numberOfRooms": 4
}
Custom properties about the real estate can be added with the additionalProperty property, and, if applicable, with the amenityFeature property.

How can I add SiteNavigationElement and footer into JSON-LD?

I want to build JSON-LD for my homepage. In my page I have:
header
navigation (2 series)
sidebar (with 2 list of items)
one list of main items
footer
I try build the JSON-LD like this:
<script type="application/ld+json">
[
{
"#context": "http://schema.org",
"#type": "WebSite",
.
.
.
},
{
"#context": "http://schema.org",
"#type": "WebPage",
"mainEntity":{
"#type": "ItemList",
"itemListElement":[
{
"#type": "BlogPosting",
.
.// 4- one list of main items
.
}
...
]
}
.
.
.
}]
</script>
If my structure is true,
how can I add SiteNavigationElement and sidebar content to this JSON object? Do I have to add another object or I can insert it in WebPage?
I use JSON-LD. Do I need to use Microdata too? or is JSON-LD enough?
I create a full sitemap-index.xml for all menu and items. Do I really need to add SiteNavigationElement (and another thing except mainEntity) in JSON-LD?
(Everything you can do with Microdata can also be done with JSON-LD, and vice versa. So there is no need to mix. There might be consumers that support only one syntax for certain features, though.)
You can add SiteNavigationElement with the hasPart property to the WebPage:
{
"#context": "http://schema.org",
"#type": "WebPage",
"hasPart":
{
"#type": "SiteNavigationElement"
}
}
But using SiteNavigationElement (and the other WebPageElement types) is typically not useful, so you might want to consider omitting it.

fancytree folders never collapse

fancytree folders are never collapsed. All children and parents are displayed without correct nesting structure.
When I copy the exact same data that works in text data source, instead from a web2py (python) controller the folders will not collapse but just display permanently expanded. No js console errors in browser.
original data that works perfectly in text file
FancyTree copies data from python contoller like this
json_list = [{
"alexLink": "http://example.com/",
"kind": "tasks#task",
"id": "MTYwNzEzNjc2OTEyMDI1MzcwNzM6ODUwNjk4NTgzOjExMTkyODk2MjA",
"etag": "\"4qyCALf1j510T_-I20NAMbUHF2k/LTEzNTgzMTMzODg\"",
"title": "Task 01",
"updated": "2015-04-23T19:25:44.000Z",
"selfLink": "",
"position": "00000000002147483647",
"status": "needsAction"
}]
I convert to json: json_list = json.dumps(json_list)
Then use as source:
// Initialize Fancytree
$("#alexTree").fancytree({
checkbox: true,
selectMode: 3,
source: {{=XML(json_list)}},
postProcess: function(event, data){
data.result = convertData(data.response);
},
select: function(event, data) {
window.open(data.node.data.alexLink, "_blank");
Data looks same as in text file source. What could be causing the folders to not contract with children under them?
I can't see an obvious reason, why your sample is not working (I assume persistence extension is off?).
Except maybe for {{=XML(json_list)}}, that may do something unexpected.
I guess a debuggable demo is needed, to find out.
Anyway, your sample does this:
Generate tree data in a native (none-Fancytree) format
Generate a html page with an embedded <script> tag that in turn has this data embedded as string
On page-load the tree is created with native data and post processing is done client-side
Fancytree was designed with this pattern in mind (among others):
Have a static page with an empty <div id="tree"> element and include some JavaScript
On page-load initialize the tree and pass an ajax url for source.
This will immediately display the page for your users, while loading is deferred (showing a spinning icon)
A soon as the data arrives, the tree will update.
(You could also consider to do the conversion server-side and send valid Fancytree-compatible data.)
This would probably deliver a smoother user experience. It would also allow to refresh tree data without reloading the page, by calling tree.reload().