wordlift-sdk 2.11.0__py3-none-any.whl → 2.12.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wordlift_sdk/validation/generator.py +150 -54
- wordlift_sdk/validation/shacls/google-breadcrumb.ttl +17 -18
- wordlift_sdk/validation/shacls/google-carousel.ttl +1 -1
- wordlift_sdk/validation/shacls/google-course.ttl +4 -4
- wordlift_sdk/validation/shacls/google-education-qa.ttl +23 -24
- wordlift_sdk/validation/shacls/google-faqpage.ttl +21 -23
- wordlift_sdk/validation/shacls/google-merchant-listing.ttl +56 -57
- wordlift_sdk/validation/shacls/google-product-snippet.ttl +37 -34
- wordlift_sdk/validation/shacls/google-profile-page.ttl +103 -103
- wordlift_sdk/validation/shacls/google-qapage.ttl +345 -180
- wordlift_sdk/validation/shacls/google-recipe.ttl +42 -49
- {wordlift_sdk-2.11.0.dist-info → wordlift_sdk-2.12.0.dist-info}/METADATA +2 -2
- {wordlift_sdk-2.11.0.dist-info → wordlift_sdk-2.12.0.dist-info}/RECORD +14 -14
- {wordlift_sdk-2.11.0.dist-info → wordlift_sdk-2.12.0.dist-info}/WHEEL +0 -0
|
@@ -169,13 +169,135 @@ def _prop_path(prop: str) -> str:
|
|
|
169
169
|
return f"( {seq} )"
|
|
170
170
|
|
|
171
171
|
|
|
172
|
+
_SCOPED_CHILD_RULES: dict[str, dict[str, list[str]]] = {
|
|
173
|
+
"ItemList": {"itemListElement": ["ListItem"]},
|
|
174
|
+
"BreadcrumbList": {"itemListElement": ["ListItem"]},
|
|
175
|
+
"QAPage": {"mainEntity": ["Question"]},
|
|
176
|
+
"FAQPage": {"mainEntity": ["Question"]},
|
|
177
|
+
"Quiz": {"hasPart": ["Question"]},
|
|
178
|
+
"ProfilePage": {"mainEntity": ["Person", "Organization"]},
|
|
179
|
+
"Question": {
|
|
180
|
+
"acceptedAnswer": ["Answer"],
|
|
181
|
+
"suggestedAnswer": ["Answer"],
|
|
182
|
+
"comment": ["Comment"],
|
|
183
|
+
},
|
|
184
|
+
"Answer": {"comment": ["Comment"]},
|
|
185
|
+
"Product": {"offers": ["Offer"]},
|
|
186
|
+
"Recipe": {"recipeInstructions": ["HowToStep"], "step": ["HowToStep"]},
|
|
187
|
+
"Course": {"provider": ["Organization"], "hasPart": ["Course", "CreativeWork"]},
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _emit_property(
|
|
192
|
+
lines: list[str],
|
|
193
|
+
prop: str,
|
|
194
|
+
required: bool,
|
|
195
|
+
child_types: list[str] | None,
|
|
196
|
+
indent: int,
|
|
197
|
+
buckets: dict[str, dict[str, set[str]]],
|
|
198
|
+
visited: set[str],
|
|
199
|
+
) -> None:
|
|
200
|
+
sp = " " * indent
|
|
201
|
+
path = _prop_path(prop)
|
|
202
|
+
lines.append(f"{sp}sh:property [")
|
|
203
|
+
lines.append(f"{sp} sh:path {path} ;")
|
|
204
|
+
lines.append(f"{sp} sh:minCount 1 ;")
|
|
205
|
+
if not required:
|
|
206
|
+
lines.append(f"{sp} sh:severity sh:Warning ;")
|
|
207
|
+
lines.append(f'{sp} sh:message "Recommended by Google: {prop}." ;')
|
|
208
|
+
if child_types:
|
|
209
|
+
valid_children = [
|
|
210
|
+
child_type
|
|
211
|
+
for child_type in child_types
|
|
212
|
+
if child_type not in visited and child_type in buckets
|
|
213
|
+
]
|
|
214
|
+
if len(valid_children) == 1:
|
|
215
|
+
child_type = valid_children[0]
|
|
216
|
+
child_bucket = buckets.get(child_type)
|
|
217
|
+
node_indent = indent + 2
|
|
218
|
+
node_sp = " " * node_indent
|
|
219
|
+
lines.append(f"{node_sp}sh:node [")
|
|
220
|
+
_emit_node(
|
|
221
|
+
lines,
|
|
222
|
+
child_type,
|
|
223
|
+
child_bucket,
|
|
224
|
+
node_indent + 2,
|
|
225
|
+
buckets,
|
|
226
|
+
visited | {child_type},
|
|
227
|
+
)
|
|
228
|
+
lines.append(f"{node_sp}] ;")
|
|
229
|
+
elif len(valid_children) > 1:
|
|
230
|
+
or_indent = indent + 2
|
|
231
|
+
or_sp = " " * or_indent
|
|
232
|
+
lines.append(f"{or_sp}sh:or (")
|
|
233
|
+
for child_type in valid_children:
|
|
234
|
+
child_bucket = buckets.get(child_type)
|
|
235
|
+
lines.append(f"{or_sp} [")
|
|
236
|
+
_emit_node(
|
|
237
|
+
lines,
|
|
238
|
+
child_type,
|
|
239
|
+
child_bucket,
|
|
240
|
+
or_indent + 4,
|
|
241
|
+
buckets,
|
|
242
|
+
visited | {child_type},
|
|
243
|
+
)
|
|
244
|
+
lines.append(f"{or_sp} ]")
|
|
245
|
+
lines.append(f"{or_sp}) ;")
|
|
246
|
+
lines.append(f"{sp}] ;")
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _emit_node(
|
|
250
|
+
lines: list[str],
|
|
251
|
+
type_name: str,
|
|
252
|
+
bucket: dict[str, set[str]],
|
|
253
|
+
indent: int,
|
|
254
|
+
buckets: dict[str, dict[str, set[str]]],
|
|
255
|
+
visited: set[str],
|
|
256
|
+
) -> None:
|
|
257
|
+
sp = " " * indent
|
|
258
|
+
lines.append(f"{sp}a sh:NodeShape ;")
|
|
259
|
+
lines.append(f"{sp}sh:class schema:{type_name} ;")
|
|
260
|
+
|
|
261
|
+
child_rules = _SCOPED_CHILD_RULES.get(type_name, {})
|
|
262
|
+
for prop in sorted(bucket["required"]):
|
|
263
|
+
child_types = child_rules.get(prop)
|
|
264
|
+
_emit_property(
|
|
265
|
+
lines,
|
|
266
|
+
prop,
|
|
267
|
+
required=True,
|
|
268
|
+
child_types=child_types,
|
|
269
|
+
indent=indent,
|
|
270
|
+
buckets=buckets,
|
|
271
|
+
visited=visited,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
for prop in sorted(bucket["recommended"]):
|
|
275
|
+
child_types = child_rules.get(prop)
|
|
276
|
+
_emit_property(
|
|
277
|
+
lines,
|
|
278
|
+
prop,
|
|
279
|
+
required=False,
|
|
280
|
+
child_types=child_types,
|
|
281
|
+
indent=indent,
|
|
282
|
+
buckets=buckets,
|
|
283
|
+
visited=visited,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
|
|
172
287
|
def _write_feature(feature: FeatureData, output_path: Path, overwrite: bool) -> bool:
|
|
173
288
|
if output_path.exists() and not overwrite:
|
|
174
289
|
return False
|
|
175
290
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
291
|
+
scoped_types: set[str] = set()
|
|
292
|
+
for parent_type, rules in _SCOPED_CHILD_RULES.items():
|
|
293
|
+
if parent_type not in feature.types:
|
|
294
|
+
continue
|
|
295
|
+
for child_types in rules.values():
|
|
296
|
+
for child_type in child_types:
|
|
297
|
+
if child_type == parent_type:
|
|
298
|
+
continue
|
|
299
|
+
if child_type in feature.types:
|
|
300
|
+
scoped_types.add(child_type)
|
|
179
301
|
|
|
180
302
|
lines: list[str] = []
|
|
181
303
|
slug = output_path.stem
|
|
@@ -186,7 +308,8 @@ def _write_feature(feature: FeatureData, output_path: Path, overwrite: bool) ->
|
|
|
186
308
|
lines.append("")
|
|
187
309
|
lines.append(f"# Source: {feature.url}")
|
|
188
310
|
lines.append(
|
|
189
|
-
|
|
311
|
+
"# Generated: "
|
|
312
|
+
f"{datetime.now(timezone.utc).isoformat(timespec='seconds').replace('+00:00', 'Z')}"
|
|
190
313
|
)
|
|
191
314
|
lines.append(
|
|
192
315
|
"# Notes: required properties => errors; recommended properties => warnings."
|
|
@@ -194,7 +317,7 @@ def _write_feature(feature: FeatureData, output_path: Path, overwrite: bool) ->
|
|
|
194
317
|
lines.append("")
|
|
195
318
|
|
|
196
319
|
for type_name in sorted(feature.types.keys()):
|
|
197
|
-
if
|
|
320
|
+
if type_name in scoped_types:
|
|
198
321
|
continue
|
|
199
322
|
bucket = feature.types[type_name]
|
|
200
323
|
shape_name = f":google_{type_name}Shape"
|
|
@@ -203,56 +326,28 @@ def _write_feature(feature: FeatureData, output_path: Path, overwrite: bool) ->
|
|
|
203
326
|
lines.append(f" sh:targetClass schema:{type_name} ;")
|
|
204
327
|
|
|
205
328
|
for prop in sorted(bucket["required"]):
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
lines.append(" sh:class schema:ListItem ;")
|
|
217
|
-
for item_prop in sorted(scoped_list_item["required"]):
|
|
218
|
-
item_path = _prop_path(item_prop)
|
|
219
|
-
lines.append(" sh:property [")
|
|
220
|
-
lines.append(f" sh:path {item_path} ;")
|
|
221
|
-
lines.append(" sh:minCount 1 ;")
|
|
222
|
-
lines.append(" ] ;")
|
|
223
|
-
for item_prop in sorted(scoped_list_item["recommended"]):
|
|
224
|
-
item_path = _prop_path(item_prop)
|
|
225
|
-
lines.append(" sh:property [")
|
|
226
|
-
lines.append(f" sh:path {item_path} ;")
|
|
227
|
-
lines.append(" sh:minCount 1 ;")
|
|
228
|
-
lines.append(" sh:severity sh:Warning ;")
|
|
229
|
-
lines.append(
|
|
230
|
-
f' sh:message "Recommended by Google: {item_prop}." ;'
|
|
231
|
-
)
|
|
232
|
-
lines.append(" ] ;")
|
|
233
|
-
lines.append(" ] ;")
|
|
234
|
-
lines.append(" ] ;")
|
|
235
|
-
continue
|
|
236
|
-
path = _prop_path(prop)
|
|
237
|
-
lines.append(" sh:property [")
|
|
238
|
-
lines.append(f" sh:path {path} ;")
|
|
239
|
-
lines.append(" sh:minCount 1 ;")
|
|
240
|
-
lines.append(" ] ;")
|
|
329
|
+
child_types = _SCOPED_CHILD_RULES.get(type_name, {}).get(prop)
|
|
330
|
+
_emit_property(
|
|
331
|
+
lines,
|
|
332
|
+
prop,
|
|
333
|
+
required=True,
|
|
334
|
+
child_types=child_types,
|
|
335
|
+
indent=2,
|
|
336
|
+
buckets=feature.types,
|
|
337
|
+
visited={type_name},
|
|
338
|
+
)
|
|
241
339
|
|
|
242
340
|
for prop in sorted(bucket["recommended"]):
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
lines.append(" sh:severity sh:Warning ;")
|
|
254
|
-
lines.append(f' sh:message "Recommended by Google: {prop}." ;')
|
|
255
|
-
lines.append(" ] ;")
|
|
341
|
+
child_types = _SCOPED_CHILD_RULES.get(type_name, {}).get(prop)
|
|
342
|
+
_emit_property(
|
|
343
|
+
lines,
|
|
344
|
+
prop,
|
|
345
|
+
required=False,
|
|
346
|
+
child_types=child_types,
|
|
347
|
+
indent=2,
|
|
348
|
+
buckets=feature.types,
|
|
349
|
+
visited={type_name},
|
|
350
|
+
)
|
|
256
351
|
|
|
257
352
|
lines.append(".")
|
|
258
353
|
lines.append("")
|
|
@@ -426,7 +521,8 @@ def generate_schema_shacls(output_file: Path, overwrite: bool) -> int:
|
|
|
426
521
|
lines.append("")
|
|
427
522
|
lines.append(f"# Source: {SCHEMA_JSONLD_URL}")
|
|
428
523
|
lines.append(
|
|
429
|
-
|
|
524
|
+
"# Generated: "
|
|
525
|
+
f"{datetime.now(timezone.utc).isoformat(timespec='seconds').replace('+00:00', 'Z')}"
|
|
430
526
|
)
|
|
431
527
|
lines.append(
|
|
432
528
|
"# Notes: schema.org grammar checks only; all constraints are warnings."
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
@prefix schema: <http://schema.org/> .
|
|
4
4
|
|
|
5
5
|
# Source: https://developers.google.com/search/docs/appearance/structured-data/breadcrumb
|
|
6
|
-
# Generated: 2026-
|
|
6
|
+
# Generated: 2026-02-04T20:00:50Z
|
|
7
7
|
# Notes: required properties => errors; recommended properties => warnings.
|
|
8
8
|
|
|
9
9
|
:google_BreadcrumbListShape
|
|
@@ -12,22 +12,21 @@
|
|
|
12
12
|
sh:property [
|
|
13
13
|
sh:path schema:itemListElement ;
|
|
14
14
|
sh:minCount 1 ;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
sh:minCount 1 ;
|
|
15
|
+
sh:node [
|
|
16
|
+
a sh:NodeShape ;
|
|
17
|
+
sh:class schema:ListItem ;
|
|
18
|
+
sh:property [
|
|
19
|
+
sh:path schema:item ;
|
|
20
|
+
sh:minCount 1 ;
|
|
21
|
+
] ;
|
|
22
|
+
sh:property [
|
|
23
|
+
sh:path schema:name ;
|
|
24
|
+
sh:minCount 1 ;
|
|
25
|
+
] ;
|
|
26
|
+
sh:property [
|
|
27
|
+
sh:path schema:position ;
|
|
28
|
+
sh:minCount 1 ;
|
|
29
|
+
] ;
|
|
30
|
+
] ;
|
|
32
31
|
] ;
|
|
33
32
|
.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
@prefix schema: <http://schema.org/> .
|
|
4
4
|
|
|
5
5
|
# Source: https://developers.google.com/search/docs/appearance/structured-data/carousel
|
|
6
|
-
# Generated: 2026-02-
|
|
6
|
+
# Generated: 2026-02-04T20:00:51Z
|
|
7
7
|
# Notes: required properties => errors; recommended properties => warnings.
|
|
8
8
|
|
|
9
9
|
:google_ItemListShape
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
@prefix schema: <http://schema.org/> .
|
|
4
4
|
|
|
5
5
|
# Source: https://developers.google.com/search/docs/appearance/structured-data/course
|
|
6
|
-
# Generated: 2026-
|
|
6
|
+
# Generated: 2026-02-04T20:09:17Z
|
|
7
7
|
# Notes: required properties => errors; recommended properties => warnings.
|
|
8
8
|
|
|
9
9
|
:google_CourseShape
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
a sh:NodeShape ;
|
|
30
30
|
sh:targetClass schema:ItemList ;
|
|
31
31
|
sh:property [
|
|
32
|
-
sh:path schema:
|
|
32
|
+
sh:path ( schema:ListItem schema:position ) ;
|
|
33
33
|
sh:minCount 1 ;
|
|
34
34
|
] ;
|
|
35
35
|
sh:property [
|
|
36
|
-
sh:path schema:
|
|
36
|
+
sh:path ( schema:ListItem schema:url ) ;
|
|
37
37
|
sh:minCount 1 ;
|
|
38
38
|
] ;
|
|
39
39
|
sh:property [
|
|
40
|
-
sh:path schema:
|
|
40
|
+
sh:path schema:itemListElement ;
|
|
41
41
|
sh:minCount 1 ;
|
|
42
42
|
] ;
|
|
43
43
|
.
|
|
@@ -3,26 +3,9 @@
|
|
|
3
3
|
@prefix schema: <http://schema.org/> .
|
|
4
4
|
|
|
5
5
|
# Source: https://developers.google.com/search/docs/appearance/structured-data/education-qa
|
|
6
|
-
# Generated: 2026-
|
|
6
|
+
# Generated: 2026-02-04T20:00:52Z
|
|
7
7
|
# Notes: required properties => errors; recommended properties => warnings.
|
|
8
8
|
|
|
9
|
-
:google_QuestionShape
|
|
10
|
-
a sh:NodeShape ;
|
|
11
|
-
sh:targetClass schema:Question ;
|
|
12
|
-
sh:property [
|
|
13
|
-
sh:path schema:acceptedAnswer ;
|
|
14
|
-
sh:minCount 1 ;
|
|
15
|
-
] ;
|
|
16
|
-
sh:property [
|
|
17
|
-
sh:path schema:eduQuestionType ;
|
|
18
|
-
sh:minCount 1 ;
|
|
19
|
-
] ;
|
|
20
|
-
sh:property [
|
|
21
|
-
sh:path schema:text ;
|
|
22
|
-
sh:minCount 1 ;
|
|
23
|
-
] ;
|
|
24
|
-
.
|
|
25
|
-
|
|
26
9
|
:google_QuizShape
|
|
27
10
|
a sh:NodeShape ;
|
|
28
11
|
sh:targetClass schema:Quiz ;
|
|
@@ -37,6 +20,22 @@
|
|
|
37
20
|
sh:property [
|
|
38
21
|
sh:path schema:hasPart ;
|
|
39
22
|
sh:minCount 1 ;
|
|
23
|
+
sh:node [
|
|
24
|
+
a sh:NodeShape ;
|
|
25
|
+
sh:class schema:Question ;
|
|
26
|
+
sh:property [
|
|
27
|
+
sh:path schema:acceptedAnswer ;
|
|
28
|
+
sh:minCount 1 ;
|
|
29
|
+
] ;
|
|
30
|
+
sh:property [
|
|
31
|
+
sh:path schema:eduQuestionType ;
|
|
32
|
+
sh:minCount 1 ;
|
|
33
|
+
] ;
|
|
34
|
+
sh:property [
|
|
35
|
+
sh:path schema:text ;
|
|
36
|
+
sh:minCount 1 ;
|
|
37
|
+
] ;
|
|
38
|
+
] ;
|
|
40
39
|
] ;
|
|
41
40
|
sh:property [
|
|
42
41
|
sh:path schema:text ;
|
|
@@ -49,10 +48,10 @@
|
|
|
49
48
|
sh:message "Recommended by Google: about." ;
|
|
50
49
|
] ;
|
|
51
50
|
sh:property [
|
|
52
|
-
sh:path schema:
|
|
51
|
+
sh:path ( schema:about schema:name ) ;
|
|
53
52
|
sh:minCount 1 ;
|
|
54
53
|
sh:severity sh:Warning ;
|
|
55
|
-
sh:message "Recommended by Google:
|
|
54
|
+
sh:message "Recommended by Google: about.name." ;
|
|
56
55
|
] ;
|
|
57
56
|
sh:property [
|
|
58
57
|
sh:path schema:educationalAlignment ;
|
|
@@ -61,15 +60,15 @@
|
|
|
61
60
|
sh:message "Recommended by Google: educationalAlignment." ;
|
|
62
61
|
] ;
|
|
63
62
|
sh:property [
|
|
64
|
-
sh:path schema:
|
|
63
|
+
sh:path ( schema:educationalAlignment schema:alignmentType ) ;
|
|
65
64
|
sh:minCount 1 ;
|
|
66
65
|
sh:severity sh:Warning ;
|
|
67
|
-
sh:message "Recommended by Google:
|
|
66
|
+
sh:message "Recommended by Google: educationalAlignment.alignmentType." ;
|
|
68
67
|
] ;
|
|
69
68
|
sh:property [
|
|
70
|
-
sh:path schema:targetName ;
|
|
69
|
+
sh:path ( schema:educationalAlignment schema:targetName ) ;
|
|
71
70
|
sh:minCount 1 ;
|
|
72
71
|
sh:severity sh:Warning ;
|
|
73
|
-
sh:message "Recommended by Google: targetName." ;
|
|
72
|
+
sh:message "Recommended by Google: educationalAlignment.targetName." ;
|
|
74
73
|
] ;
|
|
75
74
|
.
|
|
@@ -3,36 +3,34 @@
|
|
|
3
3
|
@prefix schema: <http://schema.org/> .
|
|
4
4
|
|
|
5
5
|
# Source: https://developers.google.com/search/docs/appearance/structured-data/faqpage
|
|
6
|
-
# Generated: 2026-
|
|
6
|
+
# Generated: 2026-02-04T20:00:53Z
|
|
7
7
|
# Notes: required properties => errors; recommended properties => warnings.
|
|
8
8
|
|
|
9
|
-
:google_AnswerShape
|
|
10
|
-
a sh:NodeShape ;
|
|
11
|
-
sh:targetClass schema:Answer ;
|
|
12
|
-
sh:property [
|
|
13
|
-
sh:path schema:text ;
|
|
14
|
-
sh:minCount 1 ;
|
|
15
|
-
] ;
|
|
16
|
-
.
|
|
17
|
-
|
|
18
9
|
:google_FAQPageShape
|
|
19
10
|
a sh:NodeShape ;
|
|
20
11
|
sh:targetClass schema:FAQPage ;
|
|
21
12
|
sh:property [
|
|
22
13
|
sh:path schema:mainEntity ;
|
|
23
14
|
sh:minCount 1 ;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
15
|
+
sh:node [
|
|
16
|
+
a sh:NodeShape ;
|
|
17
|
+
sh:class schema:Question ;
|
|
18
|
+
sh:property [
|
|
19
|
+
sh:path schema:acceptedAnswer ;
|
|
20
|
+
sh:minCount 1 ;
|
|
21
|
+
sh:node [
|
|
22
|
+
a sh:NodeShape ;
|
|
23
|
+
sh:class schema:Answer ;
|
|
24
|
+
sh:property [
|
|
25
|
+
sh:path schema:text ;
|
|
26
|
+
sh:minCount 1 ;
|
|
27
|
+
] ;
|
|
28
|
+
] ;
|
|
29
|
+
] ;
|
|
30
|
+
sh:property [
|
|
31
|
+
sh:path schema:name ;
|
|
32
|
+
sh:minCount 1 ;
|
|
33
|
+
] ;
|
|
34
|
+
] ;
|
|
37
35
|
] ;
|
|
38
36
|
.
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
@prefix schema: <http://schema.org/> .
|
|
4
4
|
|
|
5
5
|
# Source: https://developers.google.com/search/docs/appearance/structured-data/merchant-listing
|
|
6
|
-
# Generated: 2026-
|
|
6
|
+
# Generated: 2026-02-04T20:09:18Z
|
|
7
7
|
# Notes: required properties => errors; recommended properties => warnings.
|
|
8
8
|
|
|
9
9
|
:google_3DModelShape
|
|
10
10
|
a sh:NodeShape ;
|
|
11
11
|
sh:targetClass schema:3DModel ;
|
|
12
12
|
sh:property [
|
|
13
|
-
sh:path schema:
|
|
13
|
+
sh:path schema:encoding ;
|
|
14
14
|
sh:minCount 1 ;
|
|
15
15
|
] ;
|
|
16
16
|
sh:property [
|
|
17
|
-
sh:path schema:encoding ;
|
|
17
|
+
sh:path ( schema:encoding schema:contentUrl ) ;
|
|
18
18
|
sh:minCount 1 ;
|
|
19
19
|
] ;
|
|
20
20
|
.
|
|
@@ -40,53 +40,6 @@
|
|
|
40
40
|
] ;
|
|
41
41
|
.
|
|
42
42
|
|
|
43
|
-
:google_OfferShape
|
|
44
|
-
a sh:NodeShape ;
|
|
45
|
-
sh:targetClass schema:Offer ;
|
|
46
|
-
sh:property [
|
|
47
|
-
sh:path schema:price ;
|
|
48
|
-
sh:minCount 1 ;
|
|
49
|
-
] ;
|
|
50
|
-
sh:property [
|
|
51
|
-
sh:path schema:priceCurrency ;
|
|
52
|
-
sh:minCount 1 ;
|
|
53
|
-
] ;
|
|
54
|
-
sh:property [
|
|
55
|
-
sh:path schema:priceSpecification ;
|
|
56
|
-
sh:minCount 1 ;
|
|
57
|
-
] ;
|
|
58
|
-
sh:property [
|
|
59
|
-
sh:path schema:availability ;
|
|
60
|
-
sh:minCount 1 ;
|
|
61
|
-
sh:severity sh:Warning ;
|
|
62
|
-
sh:message "Recommended by Google: availability." ;
|
|
63
|
-
] ;
|
|
64
|
-
sh:property [
|
|
65
|
-
sh:path schema:hasMerchantReturnPolicy ;
|
|
66
|
-
sh:minCount 1 ;
|
|
67
|
-
sh:severity sh:Warning ;
|
|
68
|
-
sh:message "Recommended by Google: hasMerchantReturnPolicy." ;
|
|
69
|
-
] ;
|
|
70
|
-
sh:property [
|
|
71
|
-
sh:path schema:itemCondition ;
|
|
72
|
-
sh:minCount 1 ;
|
|
73
|
-
sh:severity sh:Warning ;
|
|
74
|
-
sh:message "Recommended by Google: itemCondition." ;
|
|
75
|
-
] ;
|
|
76
|
-
sh:property [
|
|
77
|
-
sh:path schema:shippingDetails ;
|
|
78
|
-
sh:minCount 1 ;
|
|
79
|
-
sh:severity sh:Warning ;
|
|
80
|
-
sh:message "Recommended by Google: shippingDetails." ;
|
|
81
|
-
] ;
|
|
82
|
-
sh:property [
|
|
83
|
-
sh:path schema:url ;
|
|
84
|
-
sh:minCount 1 ;
|
|
85
|
-
sh:severity sh:Warning ;
|
|
86
|
-
sh:message "Recommended by Google: url." ;
|
|
87
|
-
] ;
|
|
88
|
-
.
|
|
89
|
-
|
|
90
43
|
:google_OfferShippingDetailsShape
|
|
91
44
|
a sh:NodeShape ;
|
|
92
45
|
sh:targetClass schema:OfferShippingDetails ;
|
|
@@ -94,10 +47,6 @@
|
|
|
94
47
|
sh:path schema:addressCountry ;
|
|
95
48
|
sh:minCount 1 ;
|
|
96
49
|
] ;
|
|
97
|
-
sh:property [
|
|
98
|
-
sh:path schema:currency ;
|
|
99
|
-
sh:minCount 1 ;
|
|
100
|
-
] ;
|
|
101
50
|
sh:property [
|
|
102
51
|
sh:path schema:deliveryTime ;
|
|
103
52
|
sh:minCount 1 ;
|
|
@@ -111,7 +60,11 @@
|
|
|
111
60
|
sh:minCount 1 ;
|
|
112
61
|
] ;
|
|
113
62
|
sh:property [
|
|
114
|
-
sh:path schema:
|
|
63
|
+
sh:path ( schema:shippingRate schema:currency ) ;
|
|
64
|
+
sh:minCount 1 ;
|
|
65
|
+
] ;
|
|
66
|
+
sh:property [
|
|
67
|
+
sh:path ( schema:shippingRate schema:value ) ;
|
|
115
68
|
sh:minCount 1 ;
|
|
116
69
|
] ;
|
|
117
70
|
sh:property [
|
|
@@ -165,6 +118,52 @@
|
|
|
165
118
|
sh:property [
|
|
166
119
|
sh:path schema:offers ;
|
|
167
120
|
sh:minCount 1 ;
|
|
121
|
+
sh:node [
|
|
122
|
+
a sh:NodeShape ;
|
|
123
|
+
sh:class schema:Offer ;
|
|
124
|
+
sh:property [
|
|
125
|
+
sh:path schema:price ;
|
|
126
|
+
sh:minCount 1 ;
|
|
127
|
+
] ;
|
|
128
|
+
sh:property [
|
|
129
|
+
sh:path schema:priceCurrency ;
|
|
130
|
+
sh:minCount 1 ;
|
|
131
|
+
] ;
|
|
132
|
+
sh:property [
|
|
133
|
+
sh:path schema:priceSpecification ;
|
|
134
|
+
sh:minCount 1 ;
|
|
135
|
+
] ;
|
|
136
|
+
sh:property [
|
|
137
|
+
sh:path schema:availability ;
|
|
138
|
+
sh:minCount 1 ;
|
|
139
|
+
sh:severity sh:Warning ;
|
|
140
|
+
sh:message "Recommended by Google: availability." ;
|
|
141
|
+
] ;
|
|
142
|
+
sh:property [
|
|
143
|
+
sh:path schema:hasMerchantReturnPolicy ;
|
|
144
|
+
sh:minCount 1 ;
|
|
145
|
+
sh:severity sh:Warning ;
|
|
146
|
+
sh:message "Recommended by Google: hasMerchantReturnPolicy." ;
|
|
147
|
+
] ;
|
|
148
|
+
sh:property [
|
|
149
|
+
sh:path schema:itemCondition ;
|
|
150
|
+
sh:minCount 1 ;
|
|
151
|
+
sh:severity sh:Warning ;
|
|
152
|
+
sh:message "Recommended by Google: itemCondition." ;
|
|
153
|
+
] ;
|
|
154
|
+
sh:property [
|
|
155
|
+
sh:path schema:shippingDetails ;
|
|
156
|
+
sh:minCount 1 ;
|
|
157
|
+
sh:severity sh:Warning ;
|
|
158
|
+
sh:message "Recommended by Google: shippingDetails." ;
|
|
159
|
+
] ;
|
|
160
|
+
sh:property [
|
|
161
|
+
sh:path schema:url ;
|
|
162
|
+
sh:minCount 1 ;
|
|
163
|
+
sh:severity sh:Warning ;
|
|
164
|
+
sh:message "Recommended by Google: url." ;
|
|
165
|
+
] ;
|
|
166
|
+
] ;
|
|
168
167
|
] ;
|
|
169
168
|
sh:property [
|
|
170
169
|
sh:path schema:aggregateRating ;
|
|
@@ -179,10 +178,10 @@
|
|
|
179
178
|
sh:message "Recommended by Google: audience." ;
|
|
180
179
|
] ;
|
|
181
180
|
sh:property [
|
|
182
|
-
sh:path schema:brand ;
|
|
181
|
+
sh:path ( schema:brand schema:name ) ;
|
|
183
182
|
sh:minCount 1 ;
|
|
184
183
|
sh:severity sh:Warning ;
|
|
185
|
-
sh:message "Recommended by Google: brand." ;
|
|
184
|
+
sh:message "Recommended by Google: brand.name." ;
|
|
186
185
|
] ;
|
|
187
186
|
sh:property [
|
|
188
187
|
sh:path schema:color ;
|