Projections
Questi contenuti non sono ancora disponibili nella tua lingua.
A projection is a one-way, lossy mapping from an ORDER document to another format. ORDER does not attempt to be losslessly round-trippable through either target — that is not what either target is for. The reference implementation ships both as plain functions (toSchemaOrg and toGoogleAvailability, in the order package); this page states what each one maps, and — as importantly — what it deliberately drops.
schema.org JSON-LD
Section titled “schema.org JSON-LD”toSchemaOrg(document) produces a single Restaurant JSON-LD node — the structured data search engines read for rich results. It reads restaurant, service_periods (only whether any exist), and menus. It never reads rooms, tables, table_groups, closures, or reservations.
What is mapped
Section titled “What is mapped”| ORDER | schema.org | Notes |
|---|---|---|
restaurant.name |
name |
|
restaurant.description |
description |
Omitted if absent. |
restaurant.contact.phone |
telephone |
|
restaurant.contact.email |
email |
|
restaurant.contact.website |
url |
|
restaurant.address |
address (PostalAddress) |
Omitted entirely if every sub-field is absent — a bare PostalAddress node with nothing but its type is not useful JSON-LD. |
restaurant.address.coordinates |
geo (GeoCoordinates) |
Projected independently of address — a coordinates-only address still produces geo with no address. |
restaurant.branding.logo.url |
logo |
|
restaurant.branding.social_links (values) |
sameAs |
Keys (instagram, facebook, …) are dropped; only the URLs survive. |
restaurant.currency |
currenciesAccepted |
Always set. |
restaurant.public_hours |
openingHoursSpecification |
days map to https://schema.org/Monday etc.; opens/closes pass through as the same wall-clock HH:MM strings. |
service_periods (presence only) |
acceptsReservations |
A boolean — true when the document has at least one service period. This says the restaurant is bookable at all; it is not derived from the reservations array of actual bookings. |
menus[].sections[].items[] |
hasMenu → Menu → MenuSection → MenuItem |
Sections nest recursively via hasMenuSection. |
menu_item.name, .description |
MenuItem.name, .description |
|
menu_item.prices[] |
MenuItem.offers[] (Offer) |
Each price’s amount becomes price; priceCurrency is always the document’s restaurant.currency — ORDER has no per-price currency to project instead. |
What is dropped
Section titled “What is dropped”- Rooms, tables, table groups, and all geometry —
floor_plan,coordinate_system,position,shape— have no schema.org vocabulary at all. This is the gap Why ORDER exists describes; there is nothing to map them onto. - Service period and turn detail. Days, hours, turns,
max_covers, and party-size ranges all collapse to the singleacceptsReservationsboolean. schema.org has no concept of a turn or a covers limit. - Closures are not projected — schema.org has no vocabulary for a one-off blocked date.
allergensandlabel_refsare not projected ontoMenuItemin this version — nothing populates schema.org’ssuitableForDiet.menu_item.available,.frozen,.pairs_with,.image, andmenu.image/menu_section.imageare not projected.x_vendor extensions are never projected — a projection has no way to know what a proprietary key means.reservations— the module, and every field on it, includingstatus— is never read by this projection. That is deliberate, not an oversight:toSchemaOrgproduces public-facing SEO markup, andreservationsis the one ORDER module that carries personal data. A field the code never touches cannot leak through it.
Reserve with Google availability feed
Section titled “Reserve with Google availability feed”toGoogleAvailability(document, window) materialises ORDER’s rules (service_periods recurring on given days, subdivided into turns) into slots — one entry per date × turn, inside an explicit { from, to } window. This is the rules-versus-slots distinction Why ORDER exists discusses: the feed is the lossy, bounded output; the ORDER document is the portable rule.
Unlike validate(), this function throws rather than returning a result — its second argument is caller-supplied input, not untrusted document data. It throws if from/to are not valid dates, if from is after to, or if the window exceeds 90 days.
What is mapped
Section titled “What is mapped”For each date in the window, for each service_period whose days includes that date’s weekday, for each turn in that period, one slot is emitted:
| ORDER | Notes | |
|---|---|---|
restaurant.ref |
merchant_id |
|
service_period.ref |
service_id |
|
turn.opens, resolved against that date in restaurant.timezone |
start_sec |
An absolute epoch-second instant — the point where a wall-clock rule becomes a DST-aware absolute instant. |
turn.duration_minutes × 60 |
duration_sec |
|
turn.party_size.min / .max |
party_size_min / party_size_max |
Omitted if the turn has no party_size. |
the document’s one room, if there is exactly one |
room_id, room_name |
See below. |
What is dropped
Section titled “What is dropped”- A service period with no
turnsproduces no slots at all, even if the period itself is otherwise fully configured. The feed is turn-granular; a period intended to be bookable needs at least one turn to appear in it. service_period.max_covers(the period-wide covers cap) is not projected — only a turn’s ownparty_sizerange is.closuresare not consulted. The feed does not subtract closed dates or closed tables; a date closed in the ORDER document can still produce a slot.reservationsare not consulted either. This projection materialises configured capacity, not remaining availability — it has no notion of a slot already being booked out.- Rooms, when there are zero or two-or-more of them.
room_id/room_nameare attached only when the document has exactly one room. With zero rooms there is nothing to attach; with two or more there is no non-arbitrary way to attribute a slot to one of them, because ORDER’sservice_period/turnschema carries no room association at all. The projection makes that schema limitation visible rather than guessing around it — attaching the wrong room to a slot would be a silently wrong feed, and omitting is the honest choice. - Tables —
table_refs,seats— are not represented; the feed is period/turn-granular, not table-granular.
