@cogenta/starters 0.3.0 → 0.4.0
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.
- package/dist/blueprints/assets/photos/association/coat-bank.jpg +0 -0
- package/dist/blueprints/assets/photos/association/food-bank.jpg +0 -0
- package/dist/blueprints/assets/photos/association/garden-corner.jpg +0 -0
- package/dist/blueprints/assets/photos/association/garden-planting.jpg +0 -0
- package/dist/blueprints/assets/photos/association/hall.jpg +0 -0
- package/dist/blueprints/assets/photos/association/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/association/homework-club.jpg +0 -0
- package/dist/blueprints/assets/photos/association/orientation.jpg +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-college.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-delcourt.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-fondation.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-habitat.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-mairie.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-pharmacie.png +0 -0
- package/dist/blueprints/assets/photos/association/supper.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/desk-setup.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/library.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/notebook-and-coffee.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/notebooks.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/platform.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/pour-over.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/typing.jpg +0 -0
- package/dist/blueprints/assets/photos/documentation/delivery-flow-en.png +0 -0
- package/dist/blueprints/assets/photos/documentation/delivery-flow-fr.png +0 -0
- package/dist/blueprints/assets/photos/magazine/allotments.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/archive-stacks.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/baguettes.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/dining-room.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/empty-tram-stop.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/gallery.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/office-block-dusk.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/reading-room.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/reception-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/theatre.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/town-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/tram-stop.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-boats.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-ridge.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-water.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-beech.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-birch.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-branches.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-cave.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-melt.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-tongue.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-egret.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-shore.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-storm.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-dusk.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-marina.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-quay.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-green.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-single.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-valley.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-grapes.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-shed.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-tree.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/beetroot-carpaccio.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/chocolate-tart.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/cod-vin-jaune.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/duck-confit.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/grilled-octopus.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/market-stall.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/mushroom-risotto.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/pike-quenelle.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/poached-pear.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/praline-cake.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/pumpkin-soup.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/street-burdeau.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/api-webhooks-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/api-webhooks-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/approvals-queue-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/approvals-queue-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/audit-log-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/audit-log-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/erp-sync-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/erp-sync-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-castellan-alimentaire.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-cliniques-du-vivier.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-marenne-logistique.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-nordgate-habitat.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-tessaly-energies.png +0 -0
- package/dist/blueprints/assets/photos/saas/office-london.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/office-montreal.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/office-paris.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/office-toronto.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/policy-editor-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/policy-editor-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/security-racks.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/spend-reporting-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/spend-reporting-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/sso-scim-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/sso-scim-fr.png +0 -0
- package/dist/blueprints/assets/photos/store/aleppo-soap.jpg +0 -0
- package/dist/blueprints/assets/photos/store/copper-pan.jpg +0 -0
- package/dist/blueprints/assets/photos/store/crochet-throw.jpg +0 -0
- package/dist/blueprints/assets/photos/store/enamel-mug.jpg +0 -0
- package/dist/blueprints/assets/photos/store/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/store/knit-sweater.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-boots.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-duffel.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-wallet.jpg +0 -0
- package/dist/blueprints/assets/photos/store/moka-pot.jpg +0 -0
- package/dist/blueprints/assets/photos/store/skillet.jpg +0 -0
- package/dist/blueprints/assets/photos/store/stoneware-bottles.jpg +0 -0
- package/dist/blueprints/assets/photos/store/story.jpg +0 -0
- package/dist/blueprints/assets/photos/store/turned-bowl.jpg +0 -0
- package/dist/blueprints/association-copy-en.d.ts +3 -0
- package/dist/blueprints/association-copy-en.d.ts.map +1 -0
- package/dist/blueprints/association-copy-en.js +834 -0
- package/dist/blueprints/association-copy-en.js.map +1 -0
- package/dist/blueprints/association-copy-fr.d.ts +3 -0
- package/dist/blueprints/association-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/association-copy-fr.js +841 -0
- package/dist/blueprints/association-copy-fr.js.map +1 -0
- package/dist/blueprints/association-copy.d.ts +301 -0
- package/dist/blueprints/association-copy.d.ts.map +1 -0
- package/dist/blueprints/association-copy.js +17 -0
- package/dist/blueprints/association-copy.js.map +1 -0
- package/dist/blueprints/association-credits.d.ts +16 -0
- package/dist/blueprints/association-credits.d.ts.map +1 -0
- package/dist/blueprints/association-credits.js +80 -0
- package/dist/blueprints/association-credits.js.map +1 -0
- package/dist/blueprints/association-typography.d.ts +23 -0
- package/dist/blueprints/association-typography.d.ts.map +1 -0
- package/dist/blueprints/association-typography.js +55 -0
- package/dist/blueprints/association-typography.js.map +1 -0
- package/dist/blueprints/association.d.ts +86 -287
- package/dist/blueprints/association.d.ts.map +1 -1
- package/dist/blueprints/association.js +503 -1078
- package/dist/blueprints/association.js.map +1 -1
- package/dist/blueprints/blog-copy-en.d.ts +4 -0
- package/dist/blueprints/blog-copy-en.d.ts.map +1 -0
- package/dist/blueprints/blog-copy-en.js +701 -0
- package/dist/blueprints/blog-copy-en.js.map +1 -0
- package/dist/blueprints/blog-copy-fr.d.ts +12 -0
- package/dist/blueprints/blog-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/blog-copy-fr.js +722 -0
- package/dist/blueprints/blog-copy-fr.js.map +1 -0
- package/dist/blueprints/blog-copy.d.ts +157 -0
- package/dist/blueprints/blog-copy.d.ts.map +1 -0
- package/dist/blueprints/blog-copy.js +2 -0
- package/dist/blueprints/blog-copy.js.map +1 -0
- package/dist/blueprints/blog-credits.d.ts +28 -0
- package/dist/blueprints/blog-credits.d.ts.map +1 -0
- package/dist/blueprints/blog-credits.js +73 -0
- package/dist/blueprints/blog-credits.js.map +1 -0
- package/dist/blueprints/blog-rich.d.ts +19 -0
- package/dist/blueprints/blog-rich.d.ts.map +1 -0
- package/dist/blueprints/blog-rich.js +51 -0
- package/dist/blueprints/blog-rich.js.map +1 -0
- package/dist/blueprints/blog.d.ts +51 -176
- package/dist/blueprints/blog.d.ts.map +1 -1
- package/dist/blueprints/blog.js +358 -947
- package/dist/blueprints/blog.js.map +1 -1
- package/dist/blueprints/content-pack.d.ts.map +1 -1
- package/dist/blueprints/content-pack.js +11 -16
- package/dist/blueprints/content-pack.js.map +1 -1
- package/dist/blueprints/content-packs.d.ts +2 -4
- package/dist/blueprints/content-packs.d.ts.map +1 -1
- package/dist/blueprints/content-packs.js +27 -15
- package/dist/blueprints/content-packs.js.map +1 -1
- package/dist/blueprints/documentation-copy-en.d.ts +3 -0
- package/dist/blueprints/documentation-copy-en.d.ts.map +1 -0
- package/dist/blueprints/documentation-copy-en.js +883 -0
- package/dist/blueprints/documentation-copy-en.js.map +1 -0
- package/dist/blueprints/documentation-copy-fr.d.ts +3 -0
- package/dist/blueprints/documentation-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/documentation-copy-fr.js +939 -0
- package/dist/blueprints/documentation-copy-fr.js.map +1 -0
- package/dist/blueprints/documentation-copy.d.ts +52 -0
- package/dist/blueprints/documentation-copy.d.ts.map +1 -0
- package/dist/blueprints/documentation-copy.js +2 -0
- package/dist/blueprints/documentation-copy.js.map +1 -0
- package/dist/blueprints/documentation-writer.d.ts +67 -0
- package/dist/blueprints/documentation-writer.d.ts.map +1 -0
- package/dist/blueprints/documentation-writer.js +190 -0
- package/dist/blueprints/documentation-writer.js.map +1 -0
- package/dist/blueprints/documentation.d.ts +26 -29
- package/dist/blueprints/documentation.d.ts.map +1 -1
- package/dist/blueprints/documentation.js +106 -1064
- package/dist/blueprints/documentation.js.map +1 -1
- package/dist/blueprints/magazine-copy-en.d.ts +13 -0
- package/dist/blueprints/magazine-copy-en.d.ts.map +1 -0
- package/dist/blueprints/magazine-copy-en.js +553 -0
- package/dist/blueprints/magazine-copy-en.js.map +1 -0
- package/dist/blueprints/magazine-copy-fr.d.ts +14 -0
- package/dist/blueprints/magazine-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/magazine-copy-fr.js +568 -0
- package/dist/blueprints/magazine-copy-fr.js.map +1 -0
- package/dist/blueprints/magazine-copy.d.ts +166 -0
- package/dist/blueprints/magazine-copy.d.ts.map +1 -0
- package/dist/blueprints/magazine-copy.js +58 -0
- package/dist/blueprints/magazine-copy.js.map +1 -0
- package/dist/blueprints/magazine-credits.d.ts +19 -0
- package/dist/blueprints/magazine-credits.d.ts.map +1 -0
- package/dist/blueprints/magazine-credits.js +109 -0
- package/dist/blueprints/magazine-credits.js.map +1 -0
- package/dist/blueprints/magazine.d.ts +30 -78
- package/dist/blueprints/magazine.d.ts.map +1 -1
- package/dist/blueprints/magazine.js +269 -690
- package/dist/blueprints/magazine.js.map +1 -1
- package/dist/blueprints/portfolio-copy-en.d.ts +4 -0
- package/dist/blueprints/portfolio-copy-en.d.ts.map +1 -0
- package/dist/blueprints/portfolio-copy-en.js +745 -0
- package/dist/blueprints/portfolio-copy-en.js.map +1 -0
- package/dist/blueprints/portfolio-copy-fr.d.ts +9 -0
- package/dist/blueprints/portfolio-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/portfolio-copy-fr.js +737 -0
- package/dist/blueprints/portfolio-copy-fr.js.map +1 -0
- package/dist/blueprints/portfolio-copy.d.ts +204 -0
- package/dist/blueprints/portfolio-copy.d.ts.map +1 -0
- package/dist/blueprints/portfolio-copy.js +15 -0
- package/dist/blueprints/portfolio-copy.js.map +1 -0
- package/dist/blueprints/portfolio-credits.d.ts +18 -0
- package/dist/blueprints/portfolio-credits.d.ts.map +1 -0
- package/dist/blueprints/portfolio-credits.js +239 -0
- package/dist/blueprints/portfolio-credits.js.map +1 -0
- package/dist/blueprints/portfolio-typography.d.ts +19 -0
- package/dist/blueprints/portfolio-typography.d.ts.map +1 -0
- package/dist/blueprints/portfolio-typography.js +41 -0
- package/dist/blueprints/portfolio-typography.js.map +1 -0
- package/dist/blueprints/portfolio.d.ts +68 -157
- package/dist/blueprints/portfolio.d.ts.map +1 -1
- package/dist/blueprints/portfolio.js +475 -727
- package/dist/blueprints/portfolio.js.map +1 -1
- package/dist/blueprints/restaurant-copy-en.d.ts +3 -0
- package/dist/blueprints/restaurant-copy-en.d.ts.map +1 -0
- package/dist/blueprints/restaurant-copy-en.js +641 -0
- package/dist/blueprints/restaurant-copy-en.js.map +1 -0
- package/dist/blueprints/restaurant-copy-fr.d.ts +3 -0
- package/dist/blueprints/restaurant-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/restaurant-copy-fr.js +665 -0
- package/dist/blueprints/restaurant-copy-fr.js.map +1 -0
- package/dist/blueprints/restaurant-copy.d.ts +234 -0
- package/dist/blueprints/restaurant-copy.d.ts.map +1 -0
- package/dist/blueprints/restaurant-copy.js +15 -0
- package/dist/blueprints/restaurant-copy.js.map +1 -0
- package/dist/blueprints/restaurant-credits.d.ts +18 -0
- package/dist/blueprints/restaurant-credits.d.ts.map +1 -0
- package/dist/blueprints/restaurant-credits.js +121 -0
- package/dist/blueprints/restaurant-credits.js.map +1 -0
- package/dist/blueprints/restaurant.d.ts +55 -128
- package/dist/blueprints/restaurant.d.ts.map +1 -1
- package/dist/blueprints/restaurant.js +425 -770
- package/dist/blueprints/restaurant.js.map +1 -1
- package/dist/blueprints/saas-copy-en.d.ts +3 -0
- package/dist/blueprints/saas-copy-en.d.ts.map +1 -0
- package/dist/blueprints/saas-copy-en.js +901 -0
- package/dist/blueprints/saas-copy-en.js.map +1 -0
- package/dist/blueprints/saas-copy-fr.d.ts +3 -0
- package/dist/blueprints/saas-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/saas-copy-fr.js +912 -0
- package/dist/blueprints/saas-copy-fr.js.map +1 -0
- package/dist/blueprints/saas-copy.d.ts +266 -0
- package/dist/blueprints/saas-copy.d.ts.map +1 -0
- package/dist/blueprints/saas-copy.js +18 -0
- package/dist/blueprints/saas-copy.js.map +1 -0
- package/dist/blueprints/saas-credits.d.ts +22 -0
- package/dist/blueprints/saas-credits.d.ts.map +1 -0
- package/dist/blueprints/saas-credits.js +44 -0
- package/dist/blueprints/saas-credits.js.map +1 -0
- package/dist/blueprints/saas.d.ts +59 -203
- package/dist/blueprints/saas.d.ts.map +1 -1
- package/dist/blueprints/saas.js +505 -1108
- package/dist/blueprints/saas.js.map +1 -1
- package/dist/blueprints/store-copy-en.d.ts +4 -0
- package/dist/blueprints/store-copy-en.d.ts.map +1 -0
- package/dist/blueprints/store-copy-en.js +521 -0
- package/dist/blueprints/store-copy-en.js.map +1 -0
- package/dist/blueprints/store-copy-fr.d.ts +4 -0
- package/dist/blueprints/store-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/store-copy-fr.js +521 -0
- package/dist/blueprints/store-copy-fr.js.map +1 -0
- package/dist/blueprints/store-copy.d.ts +219 -0
- package/dist/blueprints/store-copy.d.ts.map +1 -0
- package/dist/blueprints/store-copy.js +16 -0
- package/dist/blueprints/store-copy.js.map +1 -0
- package/dist/blueprints/store-credits.d.ts +3 -0
- package/dist/blueprints/store-credits.d.ts.map +1 -0
- package/dist/blueprints/store-credits.js +117 -0
- package/dist/blueprints/store-credits.js.map +1 -0
- package/dist/blueprints/store.d.ts +43 -231
- package/dist/blueprints/store.d.ts.map +1 -1
- package/dist/blueprints/store.js +466 -789
- package/dist/blueprints/store.js.map +1 -1
- package/dist/blueprints/vitrine-copy-en.d.ts.map +1 -1
- package/dist/blueprints/vitrine-copy-en.js +1 -0
- package/dist/blueprints/vitrine-copy-en.js.map +1 -1
- package/dist/blueprints/vitrine-copy-fr.d.ts.map +1 -1
- package/dist/blueprints/vitrine-copy-fr.js +1 -0
- package/dist/blueprints/vitrine-copy-fr.js.map +1 -1
- package/dist/blueprints/vitrine-copy.d.ts +1 -0
- package/dist/blueprints/vitrine-copy.d.ts.map +1 -1
- package/dist/blueprints/vitrine.d.ts +1 -0
- package/dist/blueprints/vitrine.d.ts.map +1 -1
- package/dist/blueprints/vitrine.js +24 -3
- package/dist/blueprints/vitrine.js.map +1 -1
- package/package.json +10 -10
- package/dist/blueprints/assets/photos/association/fundraising-dinner.jpg +0 -0
- package/dist/blueprints/assets/photos/association/volunteer-orientation.jpg +0 -0
- package/dist/blueprints/assets/photos/association/volunteer-portrait.jpg +0 -0
- package/dist/blueprints/assets/photos/association/winter-coat-collection.jpg +0 -0
- package/dist/blueprints/assets/photos/documentation/delivery-flow.png +0 -0
- package/dist/blueprints/assets/photos/magazine/archive-room.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/banquet-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/city-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/downtown-towers.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/gallery-opening.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/garden-volunteers.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/station-platform.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/theater-stage.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/fenmore-branch.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/fenmore-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/fenmore-stationery.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/gannet-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/gannet-sardines.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/gannet-shelf.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-grid.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-salt-year.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-spines.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-brochure.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-poster-carnival.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-poster-sibelius.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-series.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-gate.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-pictograms.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-totem.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/tidewater-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/tidewater-data.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/tidewater-report-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/warp-and-weft-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/warp-and-weft-room.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/westmoor-rail-components.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/westmoor-rail-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/westmoor-rail-departures.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/beetroot-goats-curd.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/ceps-risotto.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/duck-leg-red-cabbage.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/hake-green-peppercorns.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/vegetable-broth.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/adrian-tan.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/api-webhooks.png +0 -0
- package/dist/blueprints/assets/photos/saas/approvals-queue.png +0 -0
- package/dist/blueprints/assets/photos/saas/audit-log.png +0 -0
- package/dist/blueprints/assets/photos/saas/erp-sync.png +0 -0
- package/dist/blueprints/assets/photos/saas/policy-editor.png +0 -0
- package/dist/blueprints/assets/photos/saas/spend-reporting.png +0 -0
- package/dist/blueprints/assets/photos/saas/sso-scim.png +0 -0
- package/dist/blueprints/assets/photos/store/brushed-cotton-overshirt.jpg +0 -0
- package/dist/blueprints/assets/photos/store/cable-knit-beanie.jpg +0 -0
- package/dist/blueprints/assets/photos/store/canvas-shoulder-bag.jpg +0 -0
- package/dist/blueprints/assets/photos/store/canvas-tote.jpg +0 -0
- package/dist/blueprints/assets/photos/store/cast-iron-skillet.jpg +0 -0
- package/dist/blueprints/assets/photos/store/field-jacket.jpg +0 -0
- package/dist/blueprints/assets/photos/store/heavyweight-t-shirt.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-card-holder.jpg +0 -0
- package/dist/blueprints/assets/photos/store/linen-table-runner.jpg +0 -0
- package/dist/blueprints/assets/photos/store/porcelain-pour-over-set.jpg +0 -0
- package/dist/blueprints/assets/photos/store/striped-wool-blanket.jpg +0 -0
|
@@ -2,15 +2,25 @@ import { CogentaError } from '@cogenta/core';
|
|
|
2
2
|
import { createContentStore, defineCollection, f, validateCollectionSet, } from '@cogenta/schema';
|
|
3
3
|
import { coverArt, heroArt } from '../demo-art/compositions.js';
|
|
4
4
|
import { definePageCollection, SEO_FIELDS, toBlockZoneEntry, } from './content-pack.js';
|
|
5
|
+
import { RESTAURANT_COPY_EN } from './restaurant-copy-en.js';
|
|
6
|
+
import { RESTAURANT_COPY_FR } from './restaurant-copy-fr.js';
|
|
7
|
+
import { RESTAURANT_PHOTO_CREDITS } from './restaurant-credits.js';
|
|
5
8
|
import { STARTING_SKINS } from './starting-skins.js';
|
|
6
9
|
/**
|
|
7
10
|
* The `restaurant` blueprint (L27, `@cogenta/theme-restaurant`): a
|
|
8
|
-
* contemporary bistro in
|
|
9
|
-
* Croix-Rousse in Lyon. A seasonal menu of nineteen dishes and wines in
|
|
10
|
-
* sections, a page for each of them, and the pages a real restaurant
|
|
11
|
-
* before a guest arrives: the menu with its set menus and allergy
|
|
12
|
-
* story of the kitchen and its suppliers, how to book, the private
|
|
13
|
-
* opening hours and directions, and the legal notice.
|
|
11
|
+
* contemporary bistro in the former offices of a silk merchant on the slopes
|
|
12
|
+
* of the Croix-Rousse in Lyon. A seasonal menu of nineteen dishes and wines in
|
|
13
|
+
* four sections, a page for each of them, and the pages a real restaurant
|
|
14
|
+
* needs before a guest arrives: the menu with its set menus and allergy
|
|
15
|
+
* notes, the story of the kitchen and its suppliers, how to book, the private
|
|
16
|
+
* room, opening hours and directions, and the legal notice.
|
|
17
|
+
*
|
|
18
|
+
* Written in French and in English, not translated at render time (L36): the
|
|
19
|
+
* installer picks the copy for the site's default locale, and with it the
|
|
20
|
+
* addresses (`/carte/…` in French, `/menu/…` in English), the names of the
|
|
21
|
+
* sections of the menu that a dish stores, the collection names the
|
|
22
|
+
* administration shows and every word of demo content. Every photograph is a
|
|
23
|
+
* real one under an open licence, credited on its own page.
|
|
14
24
|
*
|
|
15
25
|
* **No booking engine, and nothing that pretends to be one.** A blueprint
|
|
16
26
|
* writes content; contract B has no reservation block and nothing in a page
|
|
@@ -28,7 +38,10 @@ import { STARTING_SKINS } from './starting-skins.js';
|
|
|
28
38
|
* (the lists sort on `id`, a UUIDv7, so insertion order is the menu's order).
|
|
29
39
|
*/
|
|
30
40
|
export const DEFAULT_RESTAURANT_NAME = 'Laurier';
|
|
31
|
-
|
|
41
|
+
/** The copy for a site's default locale: French for any `fr*` locale, English otherwise. */
|
|
42
|
+
export function restaurantCopyFor(locale) {
|
|
43
|
+
return locale.toLowerCase().startsWith('fr') ? RESTAURANT_COPY_FR : RESTAURANT_COPY_EN;
|
|
44
|
+
}
|
|
32
45
|
const PERMISSIONS = {
|
|
33
46
|
read: ['public'],
|
|
34
47
|
create: ['editor', 'admin'],
|
|
@@ -36,42 +49,45 @@ const PERMISSIONS = {
|
|
|
36
49
|
delete: ['admin'],
|
|
37
50
|
publish: ['admin'],
|
|
38
51
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
required: true,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
max:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
52
|
+
/**
|
|
53
|
+
* The content model, named and routed in the copy's language. Field labels are
|
|
54
|
+
* not declared here: the administration translates them from its own
|
|
55
|
+
* dictionaries, and the options of `category` are the names of the sections
|
|
56
|
+
* the copy prints, so a French dish is filed under "Plats", not "Mains".
|
|
57
|
+
*/
|
|
58
|
+
export function restaurantSchema(copy) {
|
|
59
|
+
const menuItem = defineCollection({
|
|
60
|
+
name: 'menu_item',
|
|
61
|
+
versioning: { drafts: true, history: true },
|
|
62
|
+
labels: copy.schema.dishLabels,
|
|
63
|
+
routing: { pattern: copy.schema.dishRoute },
|
|
64
|
+
fields: {
|
|
65
|
+
name: f.text({ required: true, max: 120 }),
|
|
66
|
+
slug: f.slug({ from: 'name', unique: true }),
|
|
67
|
+
description: f.text({ max: 300, multiline: true }),
|
|
68
|
+
price: f.number({ required: true, min: 0 }),
|
|
69
|
+
currency: f.select({ options: ['EUR', 'CHF', 'GBP', 'DKK', 'USD'], default: 'EUR' }),
|
|
70
|
+
category: f.select({ options: [...copy.sections], required: true }),
|
|
71
|
+
vegetarian: f.boolean({ default: false }),
|
|
72
|
+
sourcing: f.text({ max: 200 }),
|
|
73
|
+
pairing: f.text({ max: 160 }),
|
|
74
|
+
allergens: f.text({ max: 200 }),
|
|
75
|
+
photo: f.media({ accept: ['image'] }),
|
|
76
|
+
blocks: f.blocks(),
|
|
77
|
+
...SEO_FIELDS,
|
|
78
|
+
},
|
|
79
|
+
indexes: [['slug'], ['category']],
|
|
80
|
+
permissions: PERMISSIONS,
|
|
81
|
+
});
|
|
82
|
+
const page = definePageCollection('/:slug');
|
|
83
|
+
const collections = [menuItem, page];
|
|
84
|
+
validateCollectionSet(collections);
|
|
85
|
+
return { menuItem, page, collections };
|
|
86
|
+
}
|
|
87
|
+
const ENGLISH_SCHEMA = restaurantSchema(RESTAURANT_COPY_EN);
|
|
88
|
+
export const menuItem = ENGLISH_SCHEMA.menuItem;
|
|
89
|
+
export const page = ENGLISH_SCHEMA.page;
|
|
90
|
+
export const RESTAURANT_COLLECTIONS = ENGLISH_SCHEMA.collections;
|
|
75
91
|
const BLOCK_VERSION = '1.0.0';
|
|
76
92
|
// ---------------------------------------------------------------------------
|
|
77
93
|
// The house: address, telephone, mailboxes
|
|
@@ -95,7 +111,7 @@ export function restaurantEmail(siteName, mailbox = 'table') {
|
|
|
95
111
|
}
|
|
96
112
|
/**
|
|
97
113
|
* A paragraph where `[words](href)` becomes a link. Nothing else is
|
|
98
|
-
* interpreted: the copy stays plain text a person can read in
|
|
114
|
+
* interpreted: the copy stays plain text a person can read in its file.
|
|
99
115
|
*/
|
|
100
116
|
function textBlock(key, style, text) {
|
|
101
117
|
const parts = text.split(/(\[[^\]]+\]\([^)]+\))/).filter((part) => part !== '');
|
|
@@ -153,245 +169,39 @@ function table(key, title, rows) {
|
|
|
153
169
|
})),
|
|
154
170
|
};
|
|
155
171
|
}
|
|
172
|
+
function pricingTable(key, title, tiers) {
|
|
173
|
+
return {
|
|
174
|
+
_key: key,
|
|
175
|
+
_type: 'pricingTable',
|
|
176
|
+
_version: BLOCK_VERSION,
|
|
177
|
+
title,
|
|
178
|
+
tiers: tiers.map((tier, index) => ({
|
|
179
|
+
_key: `${key}-${index}`,
|
|
180
|
+
name: tier.name,
|
|
181
|
+
price: tier.price,
|
|
182
|
+
interval: tier.interval,
|
|
183
|
+
features: [...tier.features],
|
|
184
|
+
...(tier.highlighted === true ? { highlighted: true } : {}),
|
|
185
|
+
})),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function withCategory(copy) {
|
|
189
|
+
return copy.dishes.map((dish) => ({ ...dish, category: copy.sections[dish.section] }));
|
|
190
|
+
}
|
|
156
191
|
/**
|
|
157
192
|
* Nineteen dishes and wines for a week in early autumn, in the order the menu
|
|
158
|
-
* prints them.
|
|
159
|
-
*
|
|
193
|
+
* prints them. Ten of them have a photograph (`RESTAURANT_DISH_PHOTOS`), and
|
|
194
|
+
* every photograph shows the dish it is filed under.
|
|
160
195
|
*/
|
|
161
|
-
export const RESTAURANT_DEMO_DISHES =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
price: 12,
|
|
167
|
-
vegetarian: true,
|
|
168
|
-
description: 'Crapaudine beetroot baked in salt, fresh goat’s curd, Grenoble walnuts toasted in brown butter and a few leaves from the farm.',
|
|
169
|
-
sourcing: 'Beetroot from the Morel farm in Vourles, curd from a goat dairy near Condrieu',
|
|
170
|
-
pairing: 'Mâcon-Villages, 2023',
|
|
171
|
-
allergens: 'Milk, walnuts',
|
|
172
|
-
note: 'Crapaudine is an old variety with a rough, dark skin like bark. Baked slowly in a crust of salt it keeps all of its sweetness, and the walnuts are toasted to order so they are still warm when the plate leaves the pass.',
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
name: 'Autumn vegetable broth, confit garlic',
|
|
176
|
-
slug: 'vegetable-broth',
|
|
177
|
-
category: 'Starters',
|
|
178
|
-
price: 10,
|
|
179
|
-
vegetarian: true,
|
|
180
|
-
description: 'A clear tomato and vegetable broth with squash, turnip and white beans, a clove of garlic confit in olive oil and flat parsley.',
|
|
181
|
-
sourcing: 'Vegetables from the Morel farm in Vourles',
|
|
182
|
-
allergens: 'Celery',
|
|
183
|
-
note: 'The broth is made every morning from the trimmings of the vegetables delivered that day, so it changes a little from one week to the next. At lunch it comes with a slice of toasted sourdough.',
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
name: 'Grilled octopus, saffron and orange',
|
|
187
|
-
slug: 'grilled-octopus',
|
|
188
|
-
category: 'Starters',
|
|
189
|
-
price: 17,
|
|
190
|
-
vegetarian: false,
|
|
191
|
-
description: 'Octopus braised for two hours, then grilled over vine cuttings, with an emulsion of saffron, orange and olive oil and a sprig of wild marjoram.',
|
|
192
|
-
sourcing: 'Day boats at Saint-Gilles-Croix-de-Vie, delivered overnight',
|
|
193
|
-
pairing: 'Saint-Joseph blanc, 2022',
|
|
194
|
-
allergens: 'Molluscs, egg',
|
|
195
|
-
note: 'We buy whole octopus of around two kilos and cook it the day it arrives. The vine cuttings come from a grower in Beaujolais who prunes in February and keeps a trailer of them for us.',
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
name: 'Pâté en croûte, pickled girolles',
|
|
199
|
-
slug: 'pate-en-croute',
|
|
200
|
-
category: 'Starters',
|
|
201
|
-
price: 15,
|
|
202
|
-
vegetarian: false,
|
|
203
|
-
description: 'Pork, duck and pistachio in a hot-water crust, made on Monday for the week, with girolles pickled in cider vinegar.',
|
|
204
|
-
sourcing: 'Pork from the Monts du Lyonnais, duck from the Dombes',
|
|
205
|
-
pairing: 'Morgon Côte du Py, 2022',
|
|
206
|
-
allergens: 'Gluten, egg, pistachio, sulphites',
|
|
207
|
-
note: 'One pâté makes eighteen slices and we make two each Monday. When they are gone, the dish comes off the menu until the following week.',
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
name: 'Leeks vinaigrette, soft egg and hazelnuts',
|
|
211
|
-
slug: 'leeks-vinaigrette',
|
|
212
|
-
category: 'Starters',
|
|
213
|
-
price: 11,
|
|
214
|
-
vegetarian: true,
|
|
215
|
-
description: 'Young leeks poached until tender, a sharp mustard vinaigrette, a soft-boiled egg from the farm and toasted hazelnuts.',
|
|
216
|
-
sourcing: 'Leeks and eggs from the Morel farm in Vourles',
|
|
217
|
-
allergens: 'Egg, mustard, hazelnuts',
|
|
218
|
-
note: 'A bistro dish we have served since the first week. The leeks are pulled when they are no thicker than a thumb, and dressed while they are still warm so they take the vinaigrette.',
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
name: 'Hake, brown butter and green peppercorns',
|
|
222
|
-
slug: 'hake-green-peppercorns',
|
|
223
|
-
category: 'Mains',
|
|
224
|
-
price: 28,
|
|
225
|
-
vegetarian: false,
|
|
226
|
-
description: 'A thick fillet of line-caught hake roasted on its skin, brown butter with fresh green peppercorns and roasted Delicata squash.',
|
|
227
|
-
sourcing: 'Day boats at Saint-Gilles-Croix-de-Vie',
|
|
228
|
-
pairing: 'Saint-Joseph blanc, 2022',
|
|
229
|
-
allergens: 'Fish, milk',
|
|
230
|
-
note: 'Fresh green peppercorns arrive on the stem, packed in brine, and taste of pepper without the heat. They go into the butter at the last moment, with a squeeze of lemon.',
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
name: 'Duck leg, red cabbage and juniper',
|
|
234
|
-
slug: 'duck-leg-red-cabbage',
|
|
235
|
-
category: 'Mains',
|
|
236
|
-
price: 26,
|
|
237
|
-
vegetarian: false,
|
|
238
|
-
description: 'Duck leg cured overnight and cooked slowly in its own fat, crisped to order, with red cabbage braised with apple and a juniper jus.',
|
|
239
|
-
sourcing: 'Ducks raised in the Dombes, forty minutes north of Lyon',
|
|
240
|
-
pairing: 'Crozes-Hermitage, 2021',
|
|
241
|
-
allergens: 'Sulphites',
|
|
242
|
-
note: 'The legs are cured with salt, thyme and crushed juniper for a night before they are cooked. The cabbage spends three hours in the oven with apple, red wine vinegar and a little of the duck fat.',
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
name: 'Risotto of ceps and girolles, aged Comté',
|
|
246
|
-
slug: 'ceps-risotto',
|
|
247
|
-
category: 'Mains',
|
|
248
|
-
price: 24,
|
|
249
|
-
vegetarian: true,
|
|
250
|
-
description: 'Carnaroli rice cooked in a stock of roasted mushroom trimmings, ceps and girolles, Comté aged for twenty-four months and a leaf of lemon balm.',
|
|
251
|
-
sourcing: 'Mushrooms picked in the Monts du Forez, Comté from an affineur on the Croix-Rousse market',
|
|
252
|
-
pairing: 'Mâcon-Villages, 2023',
|
|
253
|
-
allergens: 'Milk, celery',
|
|
254
|
-
note: 'The mushrooms come from a picker who drives down from the Forez on Tuesdays and Fridays. When the weather has been dry there are none, and the risotto is made with squash instead.',
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
name: 'Pork chop, cider and apples',
|
|
258
|
-
slug: 'pork-chop-cider',
|
|
259
|
-
category: 'Mains',
|
|
260
|
-
price: 29,
|
|
261
|
-
vegetarian: false,
|
|
262
|
-
description: 'A thick chop from the Monts du Lyonnais roasted on the bone, apples cooked in cider and a spoonful of the pan juices.',
|
|
263
|
-
sourcing: 'Pork from a farm in the Monts du Lyonnais',
|
|
264
|
-
pairing: 'Morgon Côte du Py, 2022',
|
|
265
|
-
allergens: 'Milk, sulphites',
|
|
266
|
-
note: 'The pigs are a cross of Large White and Duroc, raised outdoors and slaughtered at ten months. The chop rests for as long as it cooked before it is carved.',
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
name: 'Pike quenelle, crayfish sauce',
|
|
270
|
-
slug: 'pike-quenelle',
|
|
271
|
-
category: 'Mains',
|
|
272
|
-
price: 25,
|
|
273
|
-
vegetarian: false,
|
|
274
|
-
description: 'The Lyon classic, made light: pike and choux pastry poached, then baked in a sauce of crayfish shells, cream and a little Cognac.',
|
|
275
|
-
sourcing: 'Pike from the lakes of the Dombes, crayfish from Savoie',
|
|
276
|
-
pairing: 'Mâcon-Villages, 2023',
|
|
277
|
-
allergens: 'Fish, crustaceans, gluten, egg, milk',
|
|
278
|
-
note: 'A quenelle rises like a soufflé in the oven and falls a little on the way to the table, which is how you know it was made that evening. Allow twenty minutes.',
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
name: 'Saint-Marcellin, walnut bread',
|
|
282
|
-
slug: 'saint-marcellin',
|
|
283
|
-
category: 'Cheese and desserts',
|
|
284
|
-
price: 9,
|
|
285
|
-
vegetarian: false,
|
|
286
|
-
description: 'A soft cow’s milk cheese from the Isère, ripened until it runs, with walnut bread from the bakery on rue d’Austerlitz.',
|
|
287
|
-
sourcing: 'An affineur on the Croix-Rousse market',
|
|
288
|
-
allergens: 'Milk, gluten, walnuts',
|
|
289
|
-
note: 'Saint-Marcellin is served in its small earthenware dish, at room temperature. Ask for it runny or firm and the affineur’s shelf will usually have both.',
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
name: 'Dark chocolate tart, sea salt',
|
|
293
|
-
slug: 'chocolate-tart',
|
|
294
|
-
category: 'Cheese and desserts',
|
|
295
|
-
price: 10,
|
|
296
|
-
vegetarian: true,
|
|
297
|
-
description: 'A ganache of seventy per cent chocolate set in a sablé crust and finished with flakes of salt from Guérande.',
|
|
298
|
-
sourcing: 'Chocolate from a maker in the Drôme',
|
|
299
|
-
pairing: 'Muscat de Beaumes-de-Venise, 2020',
|
|
300
|
-
allergens: 'Milk, gluten, egg, soya',
|
|
301
|
-
note: 'The crust is baked blind in the afternoon and the ganache poured an hour before service, so the tart is set but never cold from the refrigerator.',
|
|
302
|
-
},
|
|
303
|
-
{
|
|
304
|
-
name: 'Pear poached in Beaujolais, vanilla cream',
|
|
305
|
-
slug: 'poached-pear',
|
|
306
|
-
category: 'Cheese and desserts',
|
|
307
|
-
price: 10,
|
|
308
|
-
vegetarian: true,
|
|
309
|
-
description: 'A Williams pear poached in Beaujolais with cinnamon and orange peel, a spoonful of vanilla cream and the reduced poaching wine.',
|
|
310
|
-
sourcing: 'Pears from an orchard in the Monts du Lyonnais',
|
|
311
|
-
pairing: 'Muscat de Beaumes-de-Venise, 2020',
|
|
312
|
-
allergens: 'Milk, sulphites',
|
|
313
|
-
note: 'The pears are poached two days ahead and left in the wine, which turns them the colour of the glass all the way to the core.',
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
name: 'Pink praline tart',
|
|
317
|
-
slug: 'praline-tart',
|
|
318
|
-
category: 'Cheese and desserts',
|
|
319
|
-
price: 9,
|
|
320
|
-
vegetarian: true,
|
|
321
|
-
description: 'The praline tart of Lyon: almonds and hazelnuts coated in red sugar, crushed and melted with cream into a sweet pastry case.',
|
|
322
|
-
sourcing: 'Pralines from a confectioner in the Presqu’île',
|
|
323
|
-
allergens: 'Gluten, egg, milk, almonds, hazelnuts',
|
|
324
|
-
note: 'Made the way it has been made in Lyon since the 1950s, with a little less sugar. A slice is small and very sweet, and goes well with a coffee.',
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
name: 'Mâcon-Villages, 2023',
|
|
328
|
-
slug: 'macon-villages-2023',
|
|
329
|
-
category: 'Wine by the glass',
|
|
330
|
-
price: 8,
|
|
331
|
-
vegetarian: false,
|
|
332
|
-
description: 'Chardonnay from old vines above Lugny, fermented in steel tanks. Bright and a little salty.',
|
|
333
|
-
sourcing: 'A family estate in the Mâconnais, farmed organically since 2011',
|
|
334
|
-
note: 'We pour this with the risotto, the quenelle and the beetroot. It is the wine we open most often at lunch.',
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
name: 'Saint-Joseph blanc, 2022',
|
|
338
|
-
slug: 'saint-joseph-blanc-2022',
|
|
339
|
-
category: 'Wine by the glass',
|
|
340
|
-
price: 12,
|
|
341
|
-
vegetarian: false,
|
|
342
|
-
description: 'Marsanne and roussanne from granite terraces on the right bank of the Rhône. Round, with apricot and almond.',
|
|
343
|
-
sourcing: 'A grower in Tournon-sur-Rhône with four hectares of terraces',
|
|
344
|
-
note: 'Rich enough for the hake and the octopus, and served a little warmer than most white wines so the fruit comes through.',
|
|
345
|
-
},
|
|
346
|
-
{
|
|
347
|
-
name: 'Morgon Côte du Py, 2022',
|
|
348
|
-
slug: 'morgon-cote-du-py-2022',
|
|
349
|
-
category: 'Wine by the glass',
|
|
350
|
-
price: 10,
|
|
351
|
-
vegetarian: false,
|
|
352
|
-
description: 'Gamay from the hill of Py, fermented in whole bunches and bottled without filtering. Dark cherry and a stony finish.',
|
|
353
|
-
sourcing: 'A grower in Villié-Morgon we have bought from since we opened',
|
|
354
|
-
note: 'Served slightly cool, at about fourteen degrees. It is the wine we drink with the pâté en croûte and the pork.',
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
name: 'Crozes-Hermitage, 2021',
|
|
358
|
-
slug: 'crozes-hermitage-2021',
|
|
359
|
-
category: 'Wine by the glass',
|
|
360
|
-
price: 11,
|
|
361
|
-
vegetarian: false,
|
|
362
|
-
description: 'Syrah from the northern Rhône, aged fifteen months in old barrels. Black olive, pepper and violets.',
|
|
363
|
-
sourcing: 'A cooperative of eleven growers in Tain-l’Hermitage',
|
|
364
|
-
note: 'A cooler vintage than most, with fine tannins and a long, peppery finish. We decant a bottle at the start of each service, and it drinks best with the duck.',
|
|
365
|
-
},
|
|
366
|
-
{
|
|
367
|
-
name: 'Muscat de Beaumes-de-Venise, 2020',
|
|
368
|
-
slug: 'muscat-beaumes-de-venise-2020',
|
|
369
|
-
category: 'Wine by the glass',
|
|
370
|
-
price: 9,
|
|
371
|
-
vegetarian: false,
|
|
372
|
-
description: 'A sweet white from the southern Rhône, served cold in a glass of eight centilitres. Orange peel and honey.',
|
|
373
|
-
sourcing: 'A domaine at the foot of the Dentelles de Montmirail',
|
|
374
|
-
note: 'The one sweet wine we pour by the glass, kept for the poached pear and the chocolate tart. A half bottle is on the list for a table that wants more than a glass.',
|
|
375
|
-
},
|
|
376
|
-
];
|
|
196
|
+
export const RESTAURANT_DEMO_DISHES = withCategory(RESTAURANT_COPY_EN);
|
|
197
|
+
/** The photographed dishes of a copy, by slug, with what each photograph shows. */
|
|
198
|
+
export function restaurantDishPhotos(copy) {
|
|
199
|
+
return Object.fromEntries(copy.dishes.flatMap((dish) => dish.photoAlt === undefined ? [] : [[dish.slug, dish.photoAlt]]));
|
|
200
|
+
}
|
|
377
201
|
/** The dishes photographed for the site, by slug. Every other dish has no photograph, on purpose. */
|
|
378
|
-
export const RESTAURANT_DISH_PHOTOS =
|
|
379
|
-
'beetroot-goats-curd': 'Cubes of dark beetroot, white goat’s curd and toasted walnuts on a white plate',
|
|
380
|
-
'vegetable-broth': 'A bowl of clear tomato broth with squash, turnip, white beans and flat parsley',
|
|
381
|
-
'grilled-octopus': 'A grilled octopus tentacle on a pool of saffron and orange emulsion, with a sprig of marjoram',
|
|
382
|
-
'hake-green-peppercorns': 'A roasted fillet of hake with fresh green peppercorns on the stem and cubes of squash',
|
|
383
|
-
'duck-leg-red-cabbage': 'A crisp duck leg on braised red cabbage with juniper jus, on an oak table',
|
|
384
|
-
'ceps-risotto': 'A bowl of risotto with sliced ceps, grated Comté and a leaf of lemon balm',
|
|
385
|
-
'chocolate-tart': 'A slice of dark chocolate tart with flakes of salt, a fork resting on the plate',
|
|
386
|
-
'poached-pear': 'A pear poached dark red in Beaujolais, with vanilla cream and the reduced wine',
|
|
387
|
-
};
|
|
202
|
+
export const RESTAURANT_DISH_PHOTOS = restaurantDishPhotos(RESTAURANT_COPY_EN);
|
|
388
203
|
/** The four plates that make the band of photographs on the home page. */
|
|
389
|
-
const HOME_PLATES = [
|
|
390
|
-
'beetroot-goats-curd',
|
|
391
|
-
'grilled-octopus',
|
|
392
|
-
'duck-leg-red-cabbage',
|
|
393
|
-
'poached-pear',
|
|
394
|
-
];
|
|
204
|
+
const HOME_PLATES = ['beetroot-carpaccio', 'grilled-octopus', 'duck-confit', 'poached-pear'];
|
|
395
205
|
function menuList(key, options) {
|
|
396
206
|
return {
|
|
397
207
|
_key: key,
|
|
@@ -405,58 +215,46 @@ function menuList(key, options) {
|
|
|
405
215
|
layout: options.layout ?? 'grid',
|
|
406
216
|
};
|
|
407
217
|
}
|
|
408
|
-
const MORE_TITLES = {
|
|
409
|
-
Starters: 'The other starters',
|
|
410
|
-
Mains: 'The other mains',
|
|
411
|
-
'Cheese and desserts': 'Cheese and desserts',
|
|
412
|
-
'Wine by the glass': 'Wine by the glass',
|
|
413
|
-
};
|
|
414
218
|
/** The body of one dish's page: the note from the kitchen, then the rest of its section. */
|
|
415
|
-
export function restaurantDishBlocks(dish) {
|
|
219
|
+
export function restaurantDishBlocks(dish, copy = RESTAURANT_COPY_EN) {
|
|
416
220
|
return [
|
|
417
|
-
prose(`dish-${dish.
|
|
418
|
-
menuList(`dish-${dish.
|
|
419
|
-
title:
|
|
420
|
-
category: dish.
|
|
221
|
+
prose(`dish-${dish.id}-note`, [dish.note]),
|
|
222
|
+
menuList(`dish-${dish.id}-more`, {
|
|
223
|
+
title: copy.moreTitles[dish.section],
|
|
224
|
+
category: copy.sections[dish.section],
|
|
421
225
|
layout: 'list',
|
|
422
226
|
}),
|
|
423
227
|
];
|
|
424
228
|
}
|
|
425
|
-
function
|
|
426
|
-
return
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
},
|
|
434
|
-
];
|
|
229
|
+
function pageContext(copy, siteName) {
|
|
230
|
+
return {
|
|
231
|
+
name: siteName,
|
|
232
|
+
email: (mailbox) => restaurantEmail(siteName, mailbox),
|
|
233
|
+
href: (key) => `/${copy.pageSlugs[key]}`,
|
|
234
|
+
phoneHref: PHONE_LINK,
|
|
235
|
+
mapHref: MAP_LINK,
|
|
236
|
+
};
|
|
435
237
|
}
|
|
436
|
-
const HOURS_ROWS = [
|
|
437
|
-
{ title: 'Lunch', text: 'Thursday and Friday, 12:00 to 13:45' },
|
|
438
|
-
{ title: 'Dinner', text: 'Tuesday to Saturday, 19:30 to 21:45' },
|
|
439
|
-
{ title: 'Closed', text: 'Sunday and Monday, three weeks in August and Christmas week' },
|
|
440
|
-
];
|
|
441
238
|
export function buildRestaurantHomeBlocks(options = {}) {
|
|
239
|
+
const copy = options.copy ?? RESTAURANT_COPY_EN;
|
|
442
240
|
const media = options.media ?? {};
|
|
443
241
|
const siteName = nameOf(options.siteName);
|
|
444
|
-
const
|
|
242
|
+
const context = pageContext(copy, siteName);
|
|
243
|
+
const words = copy.pages(context);
|
|
244
|
+
const plates = HOME_PLATES.map((id) => media[`dish-${id}`]).filter((id) => id !== undefined);
|
|
445
245
|
return [
|
|
446
246
|
{
|
|
447
247
|
_key: 'home-hero',
|
|
448
248
|
_type: 'hero',
|
|
449
249
|
_version: BLOCK_VERSION,
|
|
450
|
-
eyebrow:
|
|
250
|
+
eyebrow: words.home.heroEyebrow,
|
|
451
251
|
title: siteName,
|
|
452
|
-
subtitle:
|
|
252
|
+
subtitle: words.home.heroSubtitle,
|
|
453
253
|
...(media.hero === undefined ? {} : { media: media.hero }),
|
|
454
|
-
actions: [{ label:
|
|
254
|
+
actions: [{ label: words.home.heroAction, target: { href: context.href('reservations') } }],
|
|
455
255
|
},
|
|
456
|
-
prose('home-welcome', [
|
|
457
|
-
|
|
458
|
-
], { align: 'center' }),
|
|
459
|
-
menuList('home-menu', { title: 'This week’s menu' }),
|
|
256
|
+
prose('home-welcome', [words.home.welcome], { align: 'center' }),
|
|
257
|
+
menuList('home-menu', { title: words.home.menuTitle }),
|
|
460
258
|
...(plates.length === 0
|
|
461
259
|
? []
|
|
462
260
|
: [
|
|
@@ -468,419 +266,248 @@ export function buildRestaurantHomeBlocks(options = {}) {
|
|
|
468
266
|
items: plates.map((id, index) => ({ _key: `home-plates-${index}`, media: id })),
|
|
469
267
|
},
|
|
470
268
|
]),
|
|
471
|
-
prose('home-kitchen',
|
|
472
|
-
'## The kitchen',
|
|
473
|
-
`${siteName} opened in 2016 in a canut workshop on rue Burdeau, built in 1827 with ceilings four and a half metres high so that Jacquard looms could stand in it. Élise Marchand runs the kitchen with three cooks; Karim Benali looks after the room and the wine.`,
|
|
474
|
-
'Almost everything we cook comes from within a hundred kilometres of the door: vegetables from a farm in Vourles, ducks and pike from the Dombes, pork from the Monts du Lyonnais, cheese from the market at the top of the hill. The fish is the exception, and it comes overnight from the day boats of the Vendée coast.',
|
|
475
|
-
'[Read about the kitchen and the people we buy from](/our-story)',
|
|
476
|
-
]),
|
|
269
|
+
prose('home-kitchen', words.home.kitchen),
|
|
477
270
|
{
|
|
478
271
|
_key: 'home-press',
|
|
479
272
|
_type: 'quote',
|
|
480
273
|
_version: BLOCK_VERSION,
|
|
481
|
-
text:
|
|
482
|
-
author:
|
|
483
|
-
role:
|
|
274
|
+
text: words.home.press.text,
|
|
275
|
+
author: words.home.press.author,
|
|
276
|
+
role: words.home.press.role,
|
|
484
277
|
},
|
|
485
|
-
table('home-hours',
|
|
486
|
-
...
|
|
487
|
-
{ title:
|
|
488
|
-
{ title:
|
|
278
|
+
table('home-hours', words.home.hoursTitle, [
|
|
279
|
+
...words.hours,
|
|
280
|
+
{ title: words.labels.address, text: copy.address, href: context.href('visit') },
|
|
281
|
+
{ title: words.labels.telephone, text: copy.phoneDisplay, href: PHONE_LINK },
|
|
489
282
|
]),
|
|
490
283
|
{
|
|
491
284
|
_key: 'home-private',
|
|
492
285
|
_type: 'cta',
|
|
493
286
|
_version: BLOCK_VERSION,
|
|
494
|
-
title:
|
|
495
|
-
text:
|
|
496
|
-
actions: [
|
|
287
|
+
title: words.home.privateCta.title,
|
|
288
|
+
text: words.home.privateCta.text,
|
|
289
|
+
actions: [
|
|
290
|
+
{
|
|
291
|
+
label: words.home.privateCta.action,
|
|
292
|
+
target: { href: context.href('privateDining') },
|
|
293
|
+
},
|
|
294
|
+
],
|
|
497
295
|
},
|
|
498
296
|
{
|
|
499
297
|
_key: 'home-book',
|
|
500
298
|
_type: 'cta',
|
|
501
299
|
_version: BLOCK_VERSION,
|
|
502
300
|
variant: { background: 'muted' },
|
|
503
|
-
title:
|
|
504
|
-
text:
|
|
505
|
-
actions: reservationActions(siteName),
|
|
301
|
+
title: words.home.bookCta.title,
|
|
302
|
+
text: words.home.bookCta.text,
|
|
303
|
+
actions: reservationActions(words, siteName),
|
|
304
|
+
},
|
|
305
|
+
];
|
|
306
|
+
}
|
|
307
|
+
function reservationActions(words, siteName) {
|
|
308
|
+
return [
|
|
309
|
+
{ label: words.actions.call, target: { href: PHONE_LINK }, emphasis: 'primary' },
|
|
310
|
+
{
|
|
311
|
+
label: words.actions.write,
|
|
312
|
+
target: {
|
|
313
|
+
href: `mailto:${restaurantEmail(siteName)}?subject=${encodeURIComponent(words.actions.tableSubject)}`,
|
|
314
|
+
},
|
|
506
315
|
},
|
|
507
316
|
];
|
|
508
317
|
}
|
|
318
|
+
/** A prose block that lists the photographs, each credited with its author, licence and source. */
|
|
319
|
+
function creditsBlock(key, intro, sourceWord, credits) {
|
|
320
|
+
const paragraphs = intro.map((line, index) => textBlock(`${key}-${index}`, 'normal', line));
|
|
321
|
+
const items = credits.map((credit, index) => {
|
|
322
|
+
const itemKey = `${key}-credit-${index}`;
|
|
323
|
+
const links = [];
|
|
324
|
+
const children = [];
|
|
325
|
+
const add = (text, href) => {
|
|
326
|
+
const spanKey = `${itemKey}-s${children.length}`;
|
|
327
|
+
if (href === undefined) {
|
|
328
|
+
children.push({ _key: spanKey, _type: 'span', text, marks: [] });
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
const markKey = `${itemKey}-l${links.length}`;
|
|
332
|
+
links.push({ _key: markKey, _type: 'link', href });
|
|
333
|
+
children.push({ _key: spanKey, _type: 'span', text, marks: [markKey] });
|
|
334
|
+
};
|
|
335
|
+
add(`${credit.title} · ${credit.author} · `);
|
|
336
|
+
add(credit.licence.replaceAll(' ', '\u00A0'), credit.licenceUrl);
|
|
337
|
+
add(' ·\u00A0');
|
|
338
|
+
add(sourceWord, credit.source);
|
|
339
|
+
return {
|
|
340
|
+
_key: itemKey,
|
|
341
|
+
_type: 'block',
|
|
342
|
+
style: 'normal',
|
|
343
|
+
listItem: 'bullet',
|
|
344
|
+
level: 1,
|
|
345
|
+
children,
|
|
346
|
+
markDefs: links,
|
|
347
|
+
};
|
|
348
|
+
});
|
|
349
|
+
return {
|
|
350
|
+
_key: key,
|
|
351
|
+
_type: 'prose',
|
|
352
|
+
_version: BLOCK_VERSION,
|
|
353
|
+
body: [...paragraphs, ...items],
|
|
354
|
+
};
|
|
355
|
+
}
|
|
509
356
|
/**
|
|
510
|
-
* `home`,
|
|
511
|
-
*
|
|
357
|
+
* `home`, the menu, the story, reservations, private dining, hours and
|
|
358
|
+
* address, the legal notice and the photo credits: every page the menus and
|
|
359
|
+
* the copy link to, in the copy's language.
|
|
512
360
|
*/
|
|
513
361
|
export function buildRestaurantDemoPages(options = {}) {
|
|
362
|
+
const copy = options.copy ?? RESTAURANT_COPY_EN;
|
|
514
363
|
const media = options.media ?? {};
|
|
515
364
|
const siteName = nameOf(options.siteName);
|
|
516
|
-
const
|
|
365
|
+
const context = pageContext(copy, siteName);
|
|
366
|
+
const words = copy.pages(context);
|
|
367
|
+
const slugs = copy.pageSlugs;
|
|
517
368
|
const events = restaurantEmail(siteName, 'events');
|
|
518
|
-
const
|
|
369
|
+
const figure = (key, name, caption, align) => media[name] === undefined
|
|
370
|
+
? []
|
|
371
|
+
: [
|
|
372
|
+
{
|
|
373
|
+
_key: key,
|
|
374
|
+
_type: 'mediaFigure',
|
|
375
|
+
_version: BLOCK_VERSION,
|
|
376
|
+
media: media[name],
|
|
377
|
+
ratio: '3:2',
|
|
378
|
+
align,
|
|
379
|
+
caption,
|
|
380
|
+
},
|
|
381
|
+
];
|
|
519
382
|
return [
|
|
520
|
-
{ title: 'Home', slug: 'home', blocks: buildRestaurantHomeBlocks({ siteName, media }) },
|
|
521
383
|
{
|
|
522
|
-
title:
|
|
523
|
-
slug:
|
|
384
|
+
title: words.titles.home,
|
|
385
|
+
slug: slugs.home,
|
|
386
|
+
blocks: buildRestaurantHomeBlocks({ siteName, media, copy }),
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
title: words.titles.menu,
|
|
390
|
+
slug: slugs.menu,
|
|
524
391
|
blocks: [
|
|
525
|
-
prose('menu-intro', [
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
{
|
|
529
|
-
_key: 'menu-sets',
|
|
530
|
-
_type: 'pricingTable',
|
|
531
|
-
_version: BLOCK_VERSION,
|
|
532
|
-
title: 'Set menus',
|
|
533
|
-
tiers: [
|
|
534
|
-
{
|
|
535
|
-
_key: 'menu-sets-lunch',
|
|
536
|
-
name: 'Lunch',
|
|
537
|
-
price: '€29',
|
|
538
|
-
interval: 'two courses, Thursday and Friday',
|
|
539
|
-
features: [
|
|
540
|
-
'A starter and a main, or a main and a dessert',
|
|
541
|
-
'Three courses for €36',
|
|
542
|
-
'A glass of the white or red of the week for €7',
|
|
543
|
-
],
|
|
544
|
-
},
|
|
545
|
-
{
|
|
546
|
-
_key: 'menu-sets-evening',
|
|
547
|
-
name: 'The evening menu',
|
|
548
|
-
price: '€62',
|
|
549
|
-
interval: 'five courses, for the whole table',
|
|
550
|
-
features: [
|
|
551
|
-
'Two starters, a main, cheese and a dessert',
|
|
552
|
-
'Five glasses chosen by Karim for €38',
|
|
553
|
-
'Served until 20:30',
|
|
554
|
-
],
|
|
555
|
-
highlighted: true,
|
|
556
|
-
},
|
|
557
|
-
{
|
|
558
|
-
_key: 'menu-sets-carte',
|
|
559
|
-
name: 'À la carte',
|
|
560
|
-
price: '€10 to €29',
|
|
561
|
-
interval: 'a dish, at lunch and dinner',
|
|
562
|
-
features: [
|
|
563
|
-
'Every dish on this page',
|
|
564
|
-
'Half portions for children',
|
|
565
|
-
'Bread and butter included',
|
|
566
|
-
],
|
|
567
|
-
},
|
|
568
|
-
],
|
|
569
|
-
},
|
|
570
|
-
menuList('menu-all', { title: 'This week’s menu' }),
|
|
392
|
+
prose('menu-intro', [words.menu.intro]),
|
|
393
|
+
pricingTable('menu-sets', words.menu.setsTitle, words.menu.tiers),
|
|
394
|
+
menuList('menu-all', { title: words.menu.listTitle }),
|
|
571
395
|
{
|
|
572
396
|
_key: 'menu-notes',
|
|
573
397
|
_type: 'accordion',
|
|
574
398
|
_version: BLOCK_VERSION,
|
|
575
|
-
title:
|
|
576
|
-
items: questions('menu-notes',
|
|
577
|
-
[
|
|
578
|
-
'Allergies',
|
|
579
|
-
'Each dish lists the fourteen regulated allergens it contains. Tell us about an allergy when you book and again at the table, and the kitchen will say plainly what it can and cannot change. Our kitchen handles nuts, gluten and shellfish every day, so we cannot promise that a dish is free of traces.',
|
|
580
|
-
],
|
|
581
|
-
[
|
|
582
|
-
'Vegetarian guests',
|
|
583
|
-
'Dishes marked vegetarian contain no meat or fish. Some of our cheeses are made with animal rennet, so ask and we will tell you which. There is always a vegetarian main, and we can cook the evening menu without meat or fish if you tell us when you book.',
|
|
584
|
-
],
|
|
585
|
-
[
|
|
586
|
-
'Vegan guests',
|
|
587
|
-
'Write to us before you come and we will plan a meal for you. On a busy evening without notice, the kitchen can make two courses at most.',
|
|
588
|
-
],
|
|
589
|
-
]),
|
|
399
|
+
title: words.menu.notesTitle,
|
|
400
|
+
items: questions('menu-notes', words.menu.notes),
|
|
590
401
|
},
|
|
591
402
|
],
|
|
592
403
|
},
|
|
593
404
|
{
|
|
594
|
-
title:
|
|
595
|
-
slug:
|
|
405
|
+
title: words.titles.story,
|
|
406
|
+
slug: slugs.story,
|
|
596
407
|
blocks: [
|
|
597
|
-
prose('story-intro',
|
|
598
|
-
|
|
599
|
-
'## The kitchen',
|
|
600
|
-
'Élise Marchand grew up in Villefranche-sur-Saône and cooked for eight years in Paris and Copenhagen before coming home to open the restaurant. She writes the menu on Monday afternoon, once the farms have told her what they will send, and cooks every service with three cooks and a pastry chef who works mornings.',
|
|
601
|
-
'The cooking is plain on purpose. A dish has three or four things on the plate, each of them chosen for the week it is in season, and the sauces are made from the bones and trimmings of what we buy whole.',
|
|
602
|
-
'## The room and the wine',
|
|
603
|
-
'Karim Benali runs the room. He trained as a sommelier in Beaune and has built a list of about two hundred wines, almost all from growers in Beaujolais, the Mâconnais and the northern Rhône, most of whom he has visited. Six are poured by the glass and change with the menu.',
|
|
604
|
-
]),
|
|
605
|
-
...(media.hero === undefined
|
|
606
|
-
? []
|
|
607
|
-
: [
|
|
608
|
-
{
|
|
609
|
-
_key: 'story-room',
|
|
610
|
-
_type: 'mediaFigure',
|
|
611
|
-
_version: BLOCK_VERSION,
|
|
612
|
-
media: media.hero,
|
|
613
|
-
ratio: '3:2',
|
|
614
|
-
align: 'start',
|
|
615
|
-
caption: 'The dining room on rue Burdeau, set for dinner under the skylight the weavers put in.',
|
|
616
|
-
},
|
|
617
|
-
]),
|
|
408
|
+
prose('story-intro', words.story.intro),
|
|
409
|
+
...figure('story-room', 'hero', words.story.roomCaption, 'start'),
|
|
618
410
|
{
|
|
619
411
|
_key: 'story-figures',
|
|
620
412
|
_type: 'stats',
|
|
621
413
|
_version: BLOCK_VERSION,
|
|
622
|
-
title:
|
|
623
|
-
items:
|
|
624
|
-
{
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
{
|
|
630
|
-
_key: 'story-figures-room',
|
|
631
|
-
value: '14',
|
|
632
|
-
label: 'guests at one table in the room upstairs',
|
|
633
|
-
},
|
|
634
|
-
{
|
|
635
|
-
_key: 'story-figures-growers',
|
|
636
|
-
value: '11',
|
|
637
|
-
label: 'farms, boats and growers we buy from each week',
|
|
638
|
-
},
|
|
639
|
-
{
|
|
640
|
-
_key: 'story-figures-km',
|
|
641
|
-
value: '100',
|
|
642
|
-
unit: 'km',
|
|
643
|
-
label: 'from the door to almost everything we cook',
|
|
644
|
-
},
|
|
645
|
-
],
|
|
414
|
+
title: words.story.figuresTitle,
|
|
415
|
+
items: words.story.figures.map((item, index) => ({
|
|
416
|
+
_key: `story-figures-${index}`,
|
|
417
|
+
value: item.value,
|
|
418
|
+
...(item.unit === undefined ? {} : { unit: item.unit }),
|
|
419
|
+
label: item.label,
|
|
420
|
+
})),
|
|
646
421
|
},
|
|
647
|
-
table('story-suppliers',
|
|
648
|
-
|
|
649
|
-
title: 'Vegetables and eggs',
|
|
650
|
-
text: 'The Morel family farm in Vourles, twenty minutes south-west of Lyon, delivers on Tuesday and Friday mornings.',
|
|
651
|
-
},
|
|
652
|
-
{
|
|
653
|
-
title: 'Duck and pike',
|
|
654
|
-
text: 'Two farms and a fishery in the Dombes, the plateau of ponds north of the city.',
|
|
655
|
-
},
|
|
656
|
-
{
|
|
657
|
-
title: 'Pork and pears',
|
|
658
|
-
text: 'A farm and an orchard in the Monts du Lyonnais, where the pigs are raised outdoors.',
|
|
659
|
-
},
|
|
660
|
-
{
|
|
661
|
-
title: 'Fish and shellfish',
|
|
662
|
-
text: 'Day boats at Saint-Gilles-Croix-de-Vie, through a merchant who sends the catch overnight.',
|
|
663
|
-
},
|
|
664
|
-
{
|
|
665
|
-
title: 'Cheese',
|
|
666
|
-
text: 'An affineur on the Croix-Rousse market, two hundred metres up the hill.',
|
|
667
|
-
},
|
|
668
|
-
{
|
|
669
|
-
title: 'Bread',
|
|
670
|
-
text: 'A sourdough bakery on rue d’Austerlitz, collected by one of the cooks every morning at seven.',
|
|
671
|
-
},
|
|
672
|
-
]),
|
|
422
|
+
table('story-suppliers', words.story.suppliersTitle, words.story.suppliers),
|
|
423
|
+
...figure('story-market', 'market', words.story.marketCaption, 'start'),
|
|
673
424
|
],
|
|
674
425
|
},
|
|
675
426
|
{
|
|
676
|
-
title:
|
|
677
|
-
slug:
|
|
427
|
+
title: words.titles.reservations,
|
|
428
|
+
slug: slugs.reservations,
|
|
678
429
|
blocks: [
|
|
679
|
-
prose('reservations-intro',
|
|
680
|
-
|
|
681
|
-
'## By telephone',
|
|
682
|
-
`Call [${RESTAURANT_PHONE}](${PHONE_LINK}) from Tuesday to Saturday between 10:00 and 18:00. During service the phone is answered when someone is free, so the afternoon is the best time to reach us.`,
|
|
683
|
-
'## By email',
|
|
684
|
-
`Write to [${tableEmail}](mailto:${tableEmail}) with the date, the time, the number of guests and a telephone number. We reply the same day, and a table is only booked once you have our reply.`,
|
|
685
|
-
'## Without a booking',
|
|
686
|
-
'The six seats at the counter are kept for guests who walk in at dinner, and the full menu is served there. On Friday and Saturday they are usually taken by 20:00.',
|
|
687
|
-
]),
|
|
688
|
-
table('reservations-summary', 'Booking at a glance', [
|
|
689
|
-
{
|
|
690
|
-
title: 'Tables',
|
|
691
|
-
text: 'For two to six guests. For seven to fourteen, see private dining.',
|
|
692
|
-
href: '/private-dining',
|
|
693
|
-
},
|
|
694
|
-
{ title: 'Booking ahead', text: 'Up to eight weeks, by telephone or by email' },
|
|
695
|
-
{ title: 'Deposits', text: 'None for up to six guests. €20 a guest for eight or more.' },
|
|
696
|
-
{
|
|
697
|
-
title: 'Cancelling',
|
|
698
|
-
text: 'Please tell us 24 hours ahead, so we can give the table to someone else',
|
|
699
|
-
},
|
|
700
|
-
]),
|
|
430
|
+
prose('reservations-intro', words.reservations.intro),
|
|
431
|
+
table('reservations-summary', words.reservations.summaryTitle, words.reservations.summary),
|
|
701
432
|
{
|
|
702
433
|
_key: 'reservations-faq',
|
|
703
434
|
_type: 'faq',
|
|
704
435
|
_version: BLOCK_VERSION,
|
|
705
|
-
title:
|
|
706
|
-
items: questions('reservations-faq',
|
|
707
|
-
[
|
|
708
|
-
'What happens if we are running late?',
|
|
709
|
-
'We keep a table for fifteen minutes. Call us if you will be later than that and we will do what we can, although on a full evening we may have to shorten the meal.',
|
|
710
|
-
],
|
|
711
|
-
[
|
|
712
|
-
'How do I cancel?',
|
|
713
|
-
`Call us or reply to the email that confirmed your table, at least 24 hours before. For eight guests or more the deposit is returned in full if you cancel 72 hours ahead.`,
|
|
714
|
-
],
|
|
715
|
-
[
|
|
716
|
-
'Do you welcome children?',
|
|
717
|
-
'Yes. We have two high chairs, and the kitchen makes a half portion of most dishes. There is no separate children’s menu.',
|
|
718
|
-
],
|
|
719
|
-
[
|
|
720
|
-
'Is the restaurant accessible by wheelchair?',
|
|
721
|
-
'The room is on the ground floor, with a step of six centimetres at the door and a ramp we put down when you arrive. The toilets are downstairs and are not adapted, which we are sorry about.',
|
|
722
|
-
],
|
|
723
|
-
[
|
|
724
|
-
'Can I bring a dog?',
|
|
725
|
-
'A small, quiet dog is welcome at the counter and at the tables by the window.',
|
|
726
|
-
],
|
|
727
|
-
]),
|
|
436
|
+
title: words.reservations.faqTitle,
|
|
437
|
+
items: questions('reservations-faq', words.reservations.faq),
|
|
728
438
|
},
|
|
729
439
|
{
|
|
730
440
|
_key: 'reservations-book',
|
|
731
441
|
_type: 'cta',
|
|
732
442
|
_version: BLOCK_VERSION,
|
|
733
|
-
title:
|
|
734
|
-
text:
|
|
735
|
-
actions: reservationActions(siteName),
|
|
443
|
+
title: words.reservations.cta.title,
|
|
444
|
+
text: words.reservations.cta.text,
|
|
445
|
+
actions: reservationActions(words, siteName),
|
|
736
446
|
},
|
|
737
447
|
],
|
|
738
448
|
},
|
|
739
449
|
{
|
|
740
|
-
title:
|
|
741
|
-
slug:
|
|
450
|
+
title: words.titles.privateDining,
|
|
451
|
+
slug: slugs.privateDining,
|
|
742
452
|
blocks: [
|
|
743
|
-
prose('private-intro',
|
|
744
|
-
|
|
745
|
-
'We plan every meal upstairs with you. Tell us the date, the number of guests and what the occasion is, and Élise will suggest a menu from the week’s produce a fortnight before; Karim will do the same with the wine.',
|
|
746
|
-
]),
|
|
747
|
-
{
|
|
748
|
-
_key: 'private-menus',
|
|
749
|
-
_type: 'pricingTable',
|
|
750
|
-
_version: BLOCK_VERSION,
|
|
751
|
-
title: 'Menus for the room upstairs',
|
|
752
|
-
tiers: [
|
|
753
|
-
{
|
|
754
|
-
_key: 'private-menus-lunch',
|
|
755
|
-
name: 'Lunch',
|
|
756
|
-
price: '€48',
|
|
757
|
-
interval: 'a guest, Tuesday to Saturday',
|
|
758
|
-
features: [
|
|
759
|
-
'Three courses and coffee',
|
|
760
|
-
'For eight to fourteen guests',
|
|
761
|
-
'The room is yours from 12:00 to 15:30',
|
|
762
|
-
],
|
|
763
|
-
},
|
|
764
|
-
{
|
|
765
|
-
_key: 'private-menus-dinner',
|
|
766
|
-
name: 'Dinner',
|
|
767
|
-
price: '€72',
|
|
768
|
-
interval: 'a guest, Tuesday to Saturday',
|
|
769
|
-
features: [
|
|
770
|
-
'Five courses, with cheese',
|
|
771
|
-
'For eight to fourteen guests',
|
|
772
|
-
'The room is yours from 19:30 to midnight',
|
|
773
|
-
],
|
|
774
|
-
highlighted: true,
|
|
775
|
-
},
|
|
776
|
-
{
|
|
777
|
-
_key: 'private-menus-wine',
|
|
778
|
-
name: 'Wine',
|
|
779
|
-
price: '€38',
|
|
780
|
-
interval: 'a guest, with dinner',
|
|
781
|
-
features: [
|
|
782
|
-
'A glass with each course',
|
|
783
|
-
'Or bottles from the list, chosen with you',
|
|
784
|
-
'Soft drinks and coffee included',
|
|
785
|
-
],
|
|
786
|
-
},
|
|
787
|
-
],
|
|
788
|
-
},
|
|
453
|
+
prose('private-intro', words.privateDining.intro),
|
|
454
|
+
pricingTable('private-menus', words.privateDining.menusTitle, words.privateDining.tiers),
|
|
789
455
|
{
|
|
790
456
|
_key: 'private-note',
|
|
791
457
|
_type: 'testimonial',
|
|
792
458
|
_version: BLOCK_VERSION,
|
|
793
|
-
quote: answer('private-note-quote',
|
|
794
|
-
attribution: {
|
|
459
|
+
quote: answer('private-note-quote', words.privateDining.testimonial.quote),
|
|
460
|
+
attribution: {
|
|
461
|
+
name: words.privateDining.testimonial.name,
|
|
462
|
+
role: words.privateDining.testimonial.role,
|
|
463
|
+
},
|
|
795
464
|
},
|
|
796
465
|
{
|
|
797
466
|
_key: 'private-faq',
|
|
798
467
|
_type: 'faq',
|
|
799
468
|
_version: BLOCK_VERSION,
|
|
800
|
-
title:
|
|
801
|
-
items: questions('private-faq',
|
|
802
|
-
[
|
|
803
|
-
'Is there a minimum number of guests?',
|
|
804
|
-
'Eight guests for lunch and ten for dinner on Friday and Saturday. Smaller parties are welcome in the dining room.',
|
|
805
|
-
],
|
|
806
|
-
[
|
|
807
|
-
'How do we confirm the booking?',
|
|
808
|
-
'With a deposit of €20 a guest, by bank transfer or card, within a week of our proposal. It is taken off the bill on the evening.',
|
|
809
|
-
],
|
|
810
|
-
[
|
|
811
|
-
'Can we bring our own cake or decorations?',
|
|
812
|
-
'A cake, yes, with no charge for serving it. Flowers and place cards are welcome; we ask that nothing is fixed to the walls.',
|
|
813
|
-
],
|
|
814
|
-
[
|
|
815
|
-
'Is the room upstairs accessible?',
|
|
816
|
-
'It is up a flight of eighteen stairs, and there is no lift. For a guest who cannot manage the stairs, we can set a long table in the dining room at lunch.',
|
|
817
|
-
],
|
|
818
|
-
]),
|
|
469
|
+
title: words.privateDining.faqTitle,
|
|
470
|
+
items: questions('private-faq', words.privateDining.faq),
|
|
819
471
|
},
|
|
820
472
|
{
|
|
821
473
|
_key: 'private-plan',
|
|
822
474
|
_type: 'cta',
|
|
823
475
|
_version: BLOCK_VERSION,
|
|
824
|
-
title:
|
|
825
|
-
text:
|
|
476
|
+
title: words.privateDining.cta.title,
|
|
477
|
+
text: words.privateDining.cta.text,
|
|
826
478
|
actions: [
|
|
827
479
|
{
|
|
828
|
-
label:
|
|
480
|
+
label: words.actions.write,
|
|
829
481
|
target: {
|
|
830
|
-
href: `mailto:${events}?subject=${encodeURIComponent(
|
|
482
|
+
href: `mailto:${events}?subject=${encodeURIComponent(words.actions.eventsSubject)}`,
|
|
831
483
|
},
|
|
832
484
|
emphasis: 'primary',
|
|
833
485
|
},
|
|
834
|
-
{ label:
|
|
486
|
+
{ label: words.actions.call, target: { href: PHONE_LINK } },
|
|
835
487
|
],
|
|
836
488
|
},
|
|
837
489
|
],
|
|
838
490
|
},
|
|
839
491
|
{
|
|
840
|
-
title:
|
|
841
|
-
slug:
|
|
492
|
+
title: words.titles.visit,
|
|
493
|
+
slug: slugs.visit,
|
|
842
494
|
blocks: [
|
|
843
|
-
table('visit-hours',
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
{ title: 'Bookings by telephone', text: 'Tuesday to Saturday, 10:00 to 18:00' },
|
|
848
|
-
]),
|
|
849
|
-
table('visit-access', 'Finding us', [
|
|
850
|
-
{ title: 'Address', text: RESTAURANT_ADDRESS, href: MAP_LINK },
|
|
851
|
-
{ title: 'The door', text: 'Under the stone arch, next to the bookbinder' },
|
|
852
|
-
{
|
|
853
|
-
title: 'Metro',
|
|
854
|
-
text: 'Line C to Croix-Paquet, then four minutes on foot up rue Burdeau',
|
|
855
|
-
},
|
|
856
|
-
{ title: 'Bus', text: 'Lines S6 and 2 to Burdeau, a minute away' },
|
|
857
|
-
{
|
|
858
|
-
title: 'Car',
|
|
859
|
-
text: 'There is no parking on the slopes. The Terreaux car park is a ten-minute walk and closes at 01:00.',
|
|
860
|
-
},
|
|
861
|
-
{
|
|
862
|
-
title: 'Bicycle',
|
|
863
|
-
text: 'A Vélo’v station on place Sathonay, and two racks across the street',
|
|
864
|
-
},
|
|
865
|
-
]),
|
|
866
|
-
prose('visit-note', [
|
|
867
|
-
'The Pentes are steep, and rue Burdeau is a street of stairs in places. From the Terreaux, the gentlest way up is along rue Sainte-Catherine and rue Burdeau, rather than the stairs of the passage Mermet.',
|
|
868
|
-
]),
|
|
495
|
+
table('visit-hours', words.visit.hoursTitle, [...words.hours, ...words.visit.extraHours]),
|
|
496
|
+
table('visit-access', words.visit.accessTitle, words.visit.access),
|
|
497
|
+
...figure('visit-street', 'street', words.visit.streetCaption, 'wide'),
|
|
498
|
+
prose('visit-note', [words.visit.note]),
|
|
869
499
|
],
|
|
870
500
|
},
|
|
871
501
|
{
|
|
872
|
-
title:
|
|
873
|
-
slug:
|
|
502
|
+
title: words.titles.legal,
|
|
503
|
+
slug: slugs.legal,
|
|
504
|
+
blocks: [prose('legal-body', words.legal)],
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
title: words.titles.credits,
|
|
508
|
+
slug: slugs.credits,
|
|
874
509
|
blocks: [
|
|
875
|
-
|
|
876
|
-
`This site is published by ${siteName} SAS, ${RESTAURANT_ADDRESS}, France, registered with the Lyon trade and companies register under number 821 405 617, VAT FR 34 821405617. Publication director: Karim Benali.`,
|
|
877
|
-
'## Your booking details',
|
|
878
|
-
`When you book, we keep your name, telephone number, the size of your party and anything you tell us about allergies, for the sole purpose of seating you. We delete booking details three months after your visit, and we never send marketing emails. Write to [${hello}](mailto:${hello}) to see or remove what we hold.`,
|
|
879
|
-
'## Cookies',
|
|
880
|
-
'This site sets no advertising or tracking cookies. If you choose a light or dark appearance, that choice is kept in your own browser and nowhere else.',
|
|
881
|
-
'## Photographs',
|
|
882
|
-
'The photographs on this site are of our dishes and our dining room, and may not be reused without permission.',
|
|
883
|
-
]),
|
|
510
|
+
creditsBlock('credits-body', words.credits.intro, words.credits.sourceWord, RESTAURANT_PHOTO_CREDITS),
|
|
884
511
|
],
|
|
885
512
|
},
|
|
886
513
|
];
|
|
@@ -907,42 +534,56 @@ function restaurantPalette() {
|
|
|
907
534
|
}
|
|
908
535
|
/**
|
|
909
536
|
* Every visual this blueprint seeds is a bundled photograph: the dining room,
|
|
910
|
-
* and one photograph for each of the
|
|
911
|
-
* cropped to the same 4:5. The home page's band of
|
|
912
|
-
* page's figure reuse these, never a second copy. `spec`
|
|
913
|
-
* fallback if a file is ever missing, never the intended
|
|
537
|
+
* the street, a market stall, and one photograph for each of the ten dishes
|
|
538
|
+
* that has one, every dish cropped to the same 4:5. The home page's band of
|
|
539
|
+
* plates and the story page's figure reuse these, never a second copy. `spec`
|
|
540
|
+
* is `seedDemoMedia`'s fallback if a file is ever missing, never the intended
|
|
541
|
+
* picture.
|
|
914
542
|
*/
|
|
915
|
-
export
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
{
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
543
|
+
export function restaurantMediaSpecs(copy) {
|
|
544
|
+
const palette = restaurantPalette();
|
|
545
|
+
const dishes = copy.dishes.flatMap((dish, index) => dish.photoAlt === undefined
|
|
546
|
+
? []
|
|
547
|
+
: [
|
|
548
|
+
{
|
|
549
|
+
name: `dish-${dish.id}`,
|
|
550
|
+
spec: coverArt(palette, 100 + index),
|
|
551
|
+
alt: dish.photoAlt,
|
|
552
|
+
photo: `restaurant/${dish.id}.jpg`,
|
|
553
|
+
},
|
|
554
|
+
]);
|
|
555
|
+
return [
|
|
556
|
+
{
|
|
557
|
+
name: 'hero',
|
|
558
|
+
spec: heroArt(palette, 'radial', 7),
|
|
559
|
+
alt: copy.media.hero,
|
|
560
|
+
photo: 'restaurant/hero.jpg',
|
|
561
|
+
},
|
|
562
|
+
...dishes,
|
|
563
|
+
{
|
|
564
|
+
name: 'street',
|
|
565
|
+
spec: coverArt(palette, 140),
|
|
566
|
+
alt: copy.media.street,
|
|
567
|
+
photo: 'restaurant/street-burdeau.jpg',
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
name: 'market',
|
|
571
|
+
spec: coverArt(palette, 141),
|
|
572
|
+
alt: copy.media.market,
|
|
573
|
+
photo: 'restaurant/market-stall.jpg',
|
|
574
|
+
},
|
|
575
|
+
];
|
|
576
|
+
}
|
|
577
|
+
export const RESTAURANT_MEDIA_SPECS = restaurantMediaSpecs(RESTAURANT_COPY_EN);
|
|
578
|
+
export function restaurantMenus(copy) {
|
|
579
|
+
const url = (key) => `/${copy.pageSlugs[key]}`;
|
|
580
|
+
return {
|
|
581
|
+
header: copy.menus.header.map((item) => ({ label: item.label, url: url(item.page) })),
|
|
582
|
+
footer: copy.menus.footer.map((item) => ({ label: item.label, url: url(item.page) })),
|
|
583
|
+
headerAction: { label: copy.menus.action.label, url: url(copy.menus.action.page) },
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
export const RESTAURANT_MENUS = restaurantMenus(RESTAURANT_COPY_EN);
|
|
946
587
|
const DISH_PAGE = { kind: 'collection', collection: 'menu_item' };
|
|
947
588
|
const SEARCH_RESULTS = { kind: 'search' };
|
|
948
589
|
const HOME = { kind: 'home' };
|
|
@@ -950,66 +591,71 @@ const pagePath = (path) => ({ kind: 'path', path });
|
|
|
950
591
|
function shownOn(mode, ...targets) {
|
|
951
592
|
return { pages: { mode, targets } };
|
|
952
593
|
}
|
|
953
|
-
export
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
594
|
+
export function restaurantWidgets(copy) {
|
|
595
|
+
const w = copy.widgets;
|
|
596
|
+
const path = (key) => `/${copy.pageSlugs[key]}`;
|
|
597
|
+
const press = copy.pages({
|
|
598
|
+
name: DEFAULT_RESTAURANT_NAME,
|
|
599
|
+
email: () => '',
|
|
600
|
+
href: path,
|
|
601
|
+
phoneHref: PHONE_LINK,
|
|
602
|
+
mapHref: MAP_LINK,
|
|
603
|
+
}).home.press;
|
|
604
|
+
return [
|
|
605
|
+
{
|
|
606
|
+
area: 'sidebar',
|
|
607
|
+
type: 'cta',
|
|
608
|
+
title: w.reservations.title,
|
|
609
|
+
settings: {
|
|
610
|
+
heading: w.reservations.heading,
|
|
611
|
+
body: w.reservations.body,
|
|
612
|
+
label: w.reservations.label,
|
|
613
|
+
href: path('reservations'),
|
|
614
|
+
},
|
|
615
|
+
visibility: shownOn('only', DISH_PAGE, SEARCH_RESULTS),
|
|
963
616
|
},
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
settings: {
|
|
970
|
-
text: 'Élise Marchand cooks the way the room looks: there is nothing on the plate that is there for show, and nothing missing either.',
|
|
971
|
-
attribution: 'Hélène Vasseur',
|
|
972
|
-
role: 'Tablées, autumn guide 2026',
|
|
617
|
+
{
|
|
618
|
+
area: 'sidebar',
|
|
619
|
+
type: 'quote',
|
|
620
|
+
settings: { text: press.text, attribution: press.author, role: press.role },
|
|
621
|
+
visibility: shownOn('only', DISH_PAGE),
|
|
973
622
|
},
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
settings: {
|
|
981
|
-
hours: [
|
|
982
|
-
{ label: 'Closed', value: 'Sunday and Monday, three weeks in August and Christmas week' },
|
|
983
|
-
{ label: 'The counter', value: 'Six seats at dinner, kept for guests without a booking' },
|
|
984
|
-
{ label: 'Bookings', value: 'By telephone, Tuesday to Saturday, 10:00 to 18:00' },
|
|
985
|
-
],
|
|
623
|
+
{
|
|
624
|
+
area: 'footer-1',
|
|
625
|
+
type: 'contact',
|
|
626
|
+
title: w.goodToKnow.title,
|
|
627
|
+
settings: { hours: w.goodToKnow.hours.map((row) => ({ ...row })) },
|
|
628
|
+
visibility: shownOn('except', HOME, pagePath(path('visit')), pagePath(path('reservations'))),
|
|
986
629
|
},
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
630
|
+
{
|
|
631
|
+
area: 'footer-2',
|
|
632
|
+
type: 'cta',
|
|
633
|
+
title: w.privateDining.title,
|
|
634
|
+
settings: {
|
|
635
|
+
heading: w.privateDining.heading,
|
|
636
|
+
body: w.privateDining.body,
|
|
637
|
+
label: w.privateDining.label,
|
|
638
|
+
href: path('privateDining'),
|
|
639
|
+
},
|
|
640
|
+
visibility: shownOn('except', HOME, pagePath(path('privateDining'))),
|
|
998
641
|
},
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
export
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
642
|
+
];
|
|
643
|
+
}
|
|
644
|
+
export const RESTAURANT_WIDGETS = restaurantWidgets(RESTAURANT_COPY_EN);
|
|
645
|
+
export function restaurantSiteSettings(copy) {
|
|
646
|
+
return {
|
|
647
|
+
'general.tagline': copy.settings.tagline,
|
|
648
|
+
'general.socialLinks': [
|
|
649
|
+
{ label: 'Instagram', url: 'https://instagram.com/example' },
|
|
650
|
+
{ label: 'Facebook', url: 'https://facebook.com/example' },
|
|
651
|
+
],
|
|
652
|
+
'general.footerNote': copy.settings.footerNote,
|
|
653
|
+
// A menu is not a discussion: no comment form under a dish. An editor can
|
|
654
|
+
// open comments again per collection or per entry.
|
|
655
|
+
'discussion.enabled': false,
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
export const RESTAURANT_SITE_SETTINGS = restaurantSiteSettings(RESTAURANT_COPY_EN);
|
|
1013
659
|
export const RESTAURANT_RECOMMENDED_AGENTS = [
|
|
1014
660
|
{
|
|
1015
661
|
name: 'seoAgent',
|
|
@@ -1028,49 +674,58 @@ export const RESTAURANT_RECOMMENDED_AGENTS = [
|
|
|
1028
674
|
* then the pages. Everything is published, so every list and every link has
|
|
1029
675
|
* something real behind it.
|
|
1030
676
|
*/
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
const
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
677
|
+
function seedRestaurantDemoContent(copy) {
|
|
678
|
+
return async (ctx) => {
|
|
679
|
+
const { db, defaultLocale, adminId, media } = ctx;
|
|
680
|
+
const siteName = nameOf(ctx.siteName);
|
|
681
|
+
const model = restaurantSchema(copy);
|
|
682
|
+
const dishStore = createContentStore({ db, collection: model.menuItem, defaultLocale });
|
|
683
|
+
const pageStore = createContentStore({ db, collection: model.page, defaultLocale });
|
|
684
|
+
for (const dish of copy.dishes) {
|
|
685
|
+
const photo = media[`dish-${dish.id}`];
|
|
686
|
+
await dishStore.create({
|
|
687
|
+
status: 'published',
|
|
688
|
+
createdBy: adminId,
|
|
689
|
+
values: {
|
|
690
|
+
name: dish.name,
|
|
691
|
+
slug: dish.slug,
|
|
692
|
+
description: dish.description,
|
|
693
|
+
price: dish.price,
|
|
694
|
+
currency: 'EUR',
|
|
695
|
+
category: copy.sections[dish.section],
|
|
696
|
+
vegetarian: dish.vegetarian,
|
|
697
|
+
sourcing: dish.sourcing,
|
|
698
|
+
...(dish.pairing === undefined ? {} : { pairing: dish.pairing }),
|
|
699
|
+
...(dish.allergens === undefined ? {} : { allergens: dish.allergens }),
|
|
700
|
+
...(photo === undefined ? {} : { photo }),
|
|
701
|
+
},
|
|
702
|
+
blocks: { blocks: restaurantDishBlocks(dish, copy).map(toBlockZoneEntry) },
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
for (const demo of buildRestaurantDemoPages({ siteName, media, copy })) {
|
|
706
|
+
await pageStore.create({
|
|
707
|
+
status: 'published',
|
|
708
|
+
createdBy: adminId,
|
|
709
|
+
values: { title: demo.title, slug: demo.slug },
|
|
710
|
+
blocks: { blocks: demo.blocks.map(toBlockZoneEntry) },
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
};
|
|
1065
714
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
715
|
+
/** The whole blueprint, in one language. */
|
|
716
|
+
export function createRestaurantContentPack(locale) {
|
|
717
|
+
const copy = restaurantCopyFor(locale);
|
|
718
|
+
return {
|
|
719
|
+
collections: restaurantSchema(copy).collections,
|
|
720
|
+
recommendedAgents: RESTAURANT_RECOMMENDED_AGENTS,
|
|
721
|
+
seedDemoContent: seedRestaurantDemoContent(copy),
|
|
722
|
+
defaultTheme: '@cogenta/theme-restaurant',
|
|
723
|
+
menus: restaurantMenus(copy),
|
|
724
|
+
widgets: restaurantWidgets(copy),
|
|
725
|
+
siteSettings: restaurantSiteSettings(copy),
|
|
726
|
+
mediaSpecs: restaurantMediaSpecs(copy),
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
/** The English pack, which `BLUEPRINT_CONTENT_PACKS` lists; `contentPackFor` picks by locale. */
|
|
730
|
+
export const restaurantContentPack = createRestaurantContentPack('en');
|
|
1076
731
|
//# sourceMappingURL=restaurant.js.map
|