title: 'Story' # Inherits Grav's default page form — this is what supplies the page-media # uploader, plus the standard Options and Advanced tabs. Without it the form is # standalone and has no way to upload images (see entry.yaml, same pattern). '@extends': type: default context: blueprints://pages form: fields: tabs: type: tabs active: 1 fields: content: ordering@: 0 type: tab title: Content fields: header.title: type: text label: Title validate: required: true header.date: type: datetime label: Start Date format: 'Y-m-d' validate: required: true header.end_date: type: datetime label: End Date format: 'Y-m-d' help: 'Optional — leave blank for a single-day story' header.hero_image: type: text label: Hero Image placeholder: 'hero.jpg' help: 'Filename of an image uploaded in the Images field below' header.hero_alt: type: text label: Hero Image Alt Text placeholder: 'Description of the hero image' content: type: markdown label: Content help: 'Prose renders as a normal reading column. For layout blocks (scrolly sections, galleries, pull quotes) use the shortcodes listed on the Blocks tab.' validate: required: true header.media_order: type: pagemedia label: Images help: 'Upload every image the story needs here first — shortcodes refer to them by bare filename (photo-1.jpg), never by path.' blocks: ordering@: 1 type: tab title: Blocks fields: blocks_intro: type: spacer text: "

Paste these into the Content field. Image parameters take a bare filename of an image uploaded in the Images field on the Content tab. The hero image is not a block \u2014 it has its own field on the Content tab.

" blocks_scrolly: type: spacer text: "

Scrolly section \u2014 text panels scroll over a pinned image

[scrolly-section image=\"hero.jpg\" alt=\"What the image shows\" caption=\"Optional caption\"]\nFirst panel.\n\n---\n\nSecond panel. A --- starts a new panel.\n[/scrolly-section]
" blocks_pullquote: type: spacer text: "

Pull quote \u2014 large extracted quote, image optional

[pull-quote image=\"photo-1.jpg\" alt=\"What the image shows\"]\nThe quote itself. Markdown works in here.\n[/pull-quote]

Drop image and alt for the plain no-image variant.

" blocks_chapter: type: spacer text: "

Chapter break \u2014 section transition over a background image

[chapter-break image=\"photo-1.jpg\" title=\"After Dark\" number=\"II\" alt=\"What the image shows\" /]

number is optional.

" blocks_gallery: type: spacer text: "

Snap gallery \u2014 swipeable carousel

[snap-gallery images=\"hero.jpg,photo-1.jpg\" captions=\"First caption,Second caption\" alts=\"First alt,Second alt\" /]

No commas inside captions. The three lists are split on commas and zipped by position, so one comma in a caption shifts every caption after it. Use em dashes or semicolons.

" blocks_fullbleed: type: spacer text: "

Full bleed \u2014 single edge-to-edge image as a visual pause

[full-bleed image=\"photo-2.jpg\" alt=\"What the image shows\" caption=\"Optional\" credit=\"Optional\" /]
" blocks_imagecaption: type: spacer text: "

Image with caption \u2014 photo at a chosen width

[image-caption image=\"photo-2.jpg\" alt=\"What the image shows\" caption=\"Optional\" credit=\"Optional\" width=\"column\" /]

width: column (default), full, or bleed.

" blocks_gotchas: type: spacer text: "

Two things that bite

Self-closing tags need the space before /]. And a mistyped shortcode fails silently \u2014 it renders as literal text or vanishes, with no warning. Preview the page after adding each block.

" location: ordering@: 2 type: tab title: Location fields: header.location_name: type: text label: Location Name placeholder: 'e.g. Val d''Orcia' header.location_country: type: text label: Country placeholder: 'e.g. Italy' header.lat: type: text label: Latitude placeholder: '43.0780' help: 'GPS latitude (decimal degrees)' header.lng: type: text label: Longitude placeholder: '11.6760' help: 'GPS longitude (decimal degrees)' header.transport_mode: type: select label: How I arrived here default: '' options: '': '— not specified —' 'walking': 'Walking' 'bicycle': 'Bicycle' 'bus': 'Bus' 'train': 'Train' 'car': 'Car' header.force_connect: type: toggle label: Force connector line help: 'When GPX tracks are present, always draw a connector from the previous marker to this one' highlight: 1 default: 0 options: 1: 'Yes' 0: 'No' validate: type: bool # Published now comes from the inherited Options tab — defining it here # too would render two toggles bound to the same header key. publishing: ordering@: 3 type: tab title: Publishing fields: header.featured: type: toggle label: Featured highlight help: 'Show as a homepage highlight when not travelling' highlight: 1 default: 0 options: 1: 'Yes' 0: 'No' validate: type: bool # Drop the inherited Date field — Story defines its own required # "Start Date" on the Content tab, and both bind to header.date. options: fields: publishing: fields: header.date: unset@: true