How to represent internationalized strings in Google-friendly Schema.org - multilingual

Google's Structured Data Testing Tool doesn't seem to like JSON-LD's #language in value object approach to string internationalization. For example:
{
"#context": "https://schema.org/",
"#type": "Person",
"name": [{"#language": "ar", "#value": "أياس"},
{"#language": "en", "#value": "Eyas"}]
}
or
{
"#context": "https://schema.org/",
"#type": "Person",
"name": {"#language": "ar", "#value": "أياس"}
}
don't seem to work. I also tried adding "#type": "Text" but that doesn't seem to make it happy either.
Is there an accepted way of specifying multiple language representations of the same thing in Schema.org JSON-LD that is respected by search engines?
I know there's "inLanguage" for certain types, but that is not general enough to, e.g., work with a Person.

Related

Gatling: extraction crashed: end of input expected error while paring json response

Here is the JSON Response:
[{
"startTime": "2020-07-21T15:20:00.000+00:00",
"endTime": "2020-07-21T15:40:00.000+00:00",
"availabilities": [{
"availabilityId": "eyJJZCI6MTA4N",
"startTime": "2020-07-21T15:20:00.000+00:00",
"endTime": "2020-07-21T15:40:00.000+00:00",
"channel": "PHONE",
"programId": "Msff",
"providerDetails": {
"firstName": "abc",
"lastName": "abc",
"providerTitle": "NURSE"
}
}]
}, {
"startTime": "2020-07-21T15:40:00.000+00:00",
"endTime": "2020-07-21T16:00:00.000+00:00",
"availabilities": [{
"availabilityId": "eyJJZCI6MTA4NDM2MiwiU3RhcnRUa",
"startTime": "2020-07-21T15:40:00.000+00:00",
"endTime": "2020-07-21T16:00:00.000+00:00",
"channel": "PHONE",
"programId": "Msff",
"providerDetails": {
"firstName": "def",
"lastName": "def",
"providerTitle": "NURSE"
}
}]
}]
And here is the check i am using to extract the first "availabilityId" from json response
check(
jsonPath("$[0][availabilities].[0].availabilityId") saveAs "availabilityId"
)
but i am getting error:
jsonPath($[0][availabilities].[0].availabilityId).find.exists extraction crashed: end of input expected
I validated the path on https://jsonpath.com/, i am able to see the result. What am i doing wrong?
That's an example of how bad JsonPath is in its current state:
JsonPath currently doesn't have a real specification
because of holes in the original "paper" (a simple blog post actually) and implementors going with their own interpretation and likings, there are A LOT of differences between implementations
jsonpath.com isn't currently a reference, just someone who bought the domain name
Here, if you check the original source, you'll see that the square notation is supposed to use single quotes to wrap field name:
JSONPath expressions can use the dot–notation
$.store.book[0].title
or the bracket–notation
$['store']['book'][0]['title']
What happens here is that the Gatling implementation sticks to this definition while the JavaScript one used on jsonpath.com allows for ditching the single quotes.
Also, you shouldn't have dots between your brackets, so your path should be:
$[0]['availabilities'][0].availabilityId
You could also stick to the more common dot notation:
$[0].availabilities[0].availabilityId
There's an ongoing effort on creating a proper JsonPath implementation. Until this effort lands, we from Gatling recommend going with JMESPath instead, as explained here. On contrary to JsonPath atm, JMESPath has a real complete grammar and a compliance test suite.
You have added unnecessary square brackets. Change jsonPath on:
$.[0].availabilities.[0].availabilityId

Merge two properties using JSON-LD framing

I'm trying to standartize a property in a json-ld document. A simple example:
json-ld
{
"#context": {
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"dcterms": "http://purl.org/dc/terms/"
},
"#graph": [
{
"#id": "1",
"rdfs:label": "A title"
},
{
"#id": "2",
"dcterms:title": "Another title"
}
]
}
frame (failing attempt)
{
"type": "array",
"items": {
"title": ["rdfs:label", "dcterms:title"]
}
}
This produces an empty graph, instead of this:
desired output
[{
"title": "A title"
},
{
"title": "Another title"
}]
The documentation at https://json-ld.org/primer/latest/#framing seems to be work in progress and there is really not a lot of examples or tutorials covering json-ld framing.
Playground example
Framing is used to shape the data in a JSON-LD document, using an example frame document which is used to both match the flattened data and show an example of how the resulting data should be shaped
https://json-ld.org/spec/latest/json-ld-framing/#framing
This beeing said, re-shaping data does not mean you can change the semantics. rdfs:label and dcterms:title are different things in the source data and will be different things in the result, you can not merge them to a "title" property that expands to only one URI (which one?). If that were the case, the result would have different semantics than the source, but framing is only meant to change the structure.

json-ld: Good way to model custom values

I'm trying to get a good json-ld that combines the schema.org/Product definition with some custom elements.
I'm coming from an xsd background and the extensibility in json-ld seems very difficult to achieve.
I started from the template markup for Products found at Google (https://developers.google.com/search/docs/guides/search-gallery) and tried to extend it (I would like to add something like mydomain:tags to it) but I'm not sure how to do this.
<script type="application/ld+json">
{
"#context": ["http://schema.org/",
{"mydomain": "http://mystuff.com/"}],
"#type": "Product",
"name": "Executive Anvil",
"image": "http://www.example.com/anvil_executive.jpg",
"description": "Sleeker than ACME's Classic Anvil, the Executive Anvil is perfect for the business traveler looking for something to drop from a height.",
"mpn": "925872",
"brand": {
"#type": "Thing",
"name": "ACME"
},
"aggregateRating": {
"#type": "AggregateRating",
"ratingValue": "4.4",
"reviewCount": "89"
},
"offers": {
"#type": "Offer",
"priceCurrency": "USD",
"price": "119.99",
"priceValidUntil": "2020-11-05",
"itemCondition": "http://schema.org/UsedCondition",
"availability": "http://schema.org/InStock",
"seller": {
"#type": "Organization",
"name": "Executive Objects"
}
},
"mydomain:tags" : {}
}
</script>
Any clue on what I'm doing wrong here would be much appreciated.
It's probably something silly...
Your JSON-LD seems to be correct. You are using a combination of example 19 (Compact IRIs) and example 29 (Advanced Context Usage).
Google’s Structured Data Testing Tool is not a general JSON-LD validator. The errors it reports are primarily for their search result features. Their error ("The property http://mystuff.com/tags is not recognized by Google for an object of type Product.") just says that it’s not one of the properties Google knows, which is, of course, correct.
If you want to validate your JSON-LD, without getting errors for Google-specific features, you could use http://json-ld.org/playground/, for example.
If you want to use JsonLd for your ListView and DetailView in Django then you don't need to write it for all the list items added from the admin side you only need to pass JsonLdListView in the List View class and JsonLdDetailView in DetailView class and one function in model
Step-1
In models.py write this function in the model for which you have created ListView and DetailView
#property
def sd(self):
return {
"#type": 'Organization',
"description": self.description,
"name": self.name,
}
*name and description is the field name from the same model
from django_json_ld.views import JsonLdDetailView, JsonLdListView
Step-2
class PortfolioListView(JsonLdListView, ListView):
pass
Step-3
class PortfolioDetailView(JsonLdDetailView, DetailView):
def get_structured_data(self):
sd = super(DesignzPortfolioDetailView,
self).get_structured_data()
return sd

Localisation of values in JSON-LD

I'm trying to work out the best way to handle localisation in JSON-LD. The spec has information on String Internationalization that allows you to specify different translations for string values:
{
"#context":
{
...
"occupation": { "#id": "ex:occupation", "#container": "#language" }
},
"name": "Yagyū Muneyoshi",
"occupation":
{
"ja": "忍者",
"en": "Ninja",
"cs": "Nindža"
}
...
}
This covers translation but not internationalization where the content changes depending on locale.
E.g.
{
"#context":
{
"#id": "http://example.org/carousel#mycarousel",
"#language": "ja"
...
},
"slides": ["http://example.org/japan.jpg"]
}
{
"#context":
{
"#id": "http://example.org/carousel#mycarousel",
"#language": "es"
...
},
"slides": ["http://example.org/spain.jpg"]
}
Does anyone know if the above is invalid in the JSON-LD spec, i.e. having different field values depending on the #language while there #ids are the same? If not is there an alternate approach that could work?
Yes, the above is invalid. #language is only used to annotate strings with their language. What you are looking for is higher-level information. As such, you need to use some vocabulary. Schema.org for instance has http://schema.org/inLanguage for this. There exist various others as well. Which one you want to use, depends on the specific use case.

Creating context for JSON-LD

As a simple exercise I wanted to take some test-data from a little app I had which produced a user record in JSON and turn it into JSON-LD, testing on JSON-LD.org's playground gives some help, but I don't know if I'm doing it right.
The original is:
[
{
"Id": 1
"Username": "Dave",
"Colour":"green“
}
]
So I have a person, who has a username, an ID and an associated colour.
What I've got so far is:
{
"#context": {
"name": "http://schema.org/name",
"Colour": {
"#id": "http://dbpedia.org/ontology/Colour",
"#type": "http://schema.org/Text",
"#language": "en"
}
},
"#type": "http://schema.org/Person",
"#Id": "http://example.com/player/1",
"sameAs" : "https://www.facebook.com/DaveAlger",
"Id": 1,
"name": "David Alger",
"Username": "Dave",
"Colour": "green"
}
So I'm declaring it's a #type of person, and given a URI #id.
I'm also using the "sameAs" idea, which I saw on a blog-post once, but am unclear if it is just supported right off.
Then I've tried to create a #context. Here that I've added a name and given that a reference. I've tried to create something for "colour" too. I'm not sure if pointing to a DBpedia reference about "colour" and specifying a #type and #language is good, or not.
I suppose the final thing is "username", but that feels so deeply internal to a site that it doesn't make sense to "Link" it at all.
I'm aware this data is perhaps not even worth linking, this is very much a learning exercise for me.
I don’t think that http://dbpedia.org/ontology/Colour should be used like that. It’s a class, not a property. The property that has http://dbpedia.org/ontology/Colour as range is http://dbpedia.org/ontology/colour. (That said, I’m not sure if your really intend that the person should have a colour, instead of something related to this person.)
If you want to provide the language of the colour strings, you should not specify the datatype, #language is sufficient (if a value is typed, it can’t have a language anymore; by using #language, it’s implied that the value is a string).
You are using #Id for specifying the node’s URI, but it must be #id.
The properties sameAs, Id and Username are not defined in your #context.
If you intend to use Schema.org’s sameAs property, you could define it similar to what you did with name, but you should specify that the value is a URI:
"sameAs": {
"#id": "http://schema.org/sameAs",
"#type": "#id"
},
For Username, you could use FOAF’s nick property, or maybe Schema.org’s alternateName property.
No idea which property you could use for Id (depends on your case if this is useful for others at all, or if this is only relevant for your internal system).

Resources