This page exercises various arguments and features of the leaflet shortcode extension, including a suite of error cases. For error cases the extension must never crash — it must either render a visible error message or silently skip the bad input and continue rendering.
All tests are run in the HTML output format.
1 YAML-based maps
1.1 Minimal — center only
Default height (400px) is used when height is omitted.
leaflet:
t-minimal:
center: [51.505, -0.09]{{< leaflet t-minimal >}}1.2 Basic — center, zoom, height
leaflet:
t-basic:
center: [51.505, -0.09]
zoom: 13
height: "380px"{{< leaflet t-basic >}}1.3 Markers — all popup/tooltip combinations
Tests four markers:
| Marker | popup | tooltip |
|---|---|---|
| Stockholm | ✓ | ✓ |
| Djurgården | — | ✓ |
| Södermalm | ✓ | — |
| Unnamed point | — | — |
1.4 Markers from TSV (markers-file + separator)
Loads markers from data/stockholm-markers.tsv using lat/lon, popup, tooltip, and icon columns.
leaflet:
t-markers-tab:
center: [59.33, 18.07]
zoom: 12
markers-file: "data/stockholm-markers.tsv"
markers-sep: "\t"1.5 Markers from CSV
Loads markers from data/stockholm-markers.csv using the generic markers-file option.
leaflet:
t-markers-csv:
center: [59.33, 18.07]
zoom: 12
markers-file: "data/stockholm-markers.csv"1.6 Markers from semicolon-separated .txt
leaflet:
t-markers-semi-txt:
center: [59.33, 18.07]
zoom: 12
markers-file: "data/stockholm-markers-semicolon.txt"
markers-sep: ";"1.7 Markers from pipe-separated .txt
leaflet:
t-markers-pipe-txt:
center: [59.33, 18.07]
zoom: 12
markers-file: "data/stockholm-markers-pipe.txt"
markers-sep: "|"1.8 Icon markers — Font Awesome
Tests icon, icon-color, icon-size, and icon-anchor.
---
leaflet:
t-icons:
center: [48.86, 2.35]
zoom: 13
height: "380px"
markers:
- lat: 48.8584
lon: 2.2945
popup: "<b>Eiffel Tower</b>"
icon: "fa-solid fa-house"
icon-color: "tomato"
icon-size: 16
- lat: 48.8606
lon: 2.3376
popup: "<b>Louvre Museum</b>"
icon: "fa-solid fa-building-columns"
icon-color: "#4a90d9"
icon-size: 16
icon-anchor: [12, 24] # explicit anchor offset
- lat: 48.853
lon: 2.3499
popup: "<b>Notre-Dame</b>"
icon: "fa-solid fa-church"
icon-color: "green"
icon-size: 16
---
{{< leaflet t-icons >}}1.9 Default markers and Font Awesome icons together
This map exists to catch the packaging bug where default Leaflet markers disappear while Font Awesome icon markers still render. All three markers below must be visible at the same time.
---
leaflet:
t-default-vs-fonticon:
center: [51.505, -0.09]
zoom: 13
height: "340px"
markers:
- lat: 51.505
lon: -0.09
popup: "Default Leaflet marker"
tooltip: "Default marker"
- lat: 51.51
lon: -0.082
popup: "Font Awesome marker"
tooltip: "Font Awesome icon"
icon: "fa-solid fa-house"
icon-color: "tomato"
icon-size: 20
- lat: 51.5
lon: -0.1
popup: "Second default Leaflet marker"
tooltip: "Default marker 2"
---
{{< leaflet t-default-vs-fonticon >}}1.10 FontAwesome markers
These icon-font markers render without extra page setup because the extension loads Font Awesome automatically.
leaflet:
t-fontawesome:
center: [41.9028, 12.4964]
zoom: 13
markers:
- lat: 41.9028
lon: 12.4964
icon: "fa-solid fa-landmark"
- lat: 41.89
lon: 12.4922
icon: "fa-solid fa-torii-gate"
- lat: 41.8986
lon: 12.4768
icon: "fa-solid fa-tree"1.11 FontAwesome dense markers
Stress test with 50 markers and 50 different Font Awesome icon classes.
1.12 Custom image icon
The first marker uses a remote PNG via icon: {url: ..., size: [...], anchor: [...]}.
leaflet:
t-image-icon:
center: [51.5, -0.09]
zoom: 13
height: "340px"
markers:
- lat: 51.5
lon: -0.09
popup: "Custom image icon"
icon:
url: "https://leafletjs.com/examples/custom-icons/leaf-green.png"
size: [38, 95]
anchor: [22, 94]
- lat: 51.505
lon: -0.07
popup: "Default blue marker alongside custom icon"1.13 Custom tile layer — CartoDB dark
Tests the tile sub-object with url, attribution, subdomains, and maxZoom.
leaflet:
t-tile-dark:
center: [40.7128, -74.006]
zoom: 11
height: "380px"
tile:
url: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png"
attribution: "© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors © CARTO"
subdomains: "abcd"
maxZoom: 20
markers:
- lat: 40.7128
lon: -74.006
popup: "<b>New York City</b>"
icon: "fa-solid fa-house"
icon-color: "#ff6b6b"
icon-size: 201.14 Custom tile layer — CartoDB Voyager
leaflet:
t-tile-voyager:
center: [35.68, 139.69]
zoom: 12
height: "340px"
tile:
url: "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
attribution: "© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors © CARTO"
subdomains: "abcd"
maxZoom: 191.15 Passthrough Leaflet options
Passes zoomControl, scrollWheelZoom, dragging, doubleClickZoom, keyboard, minZoom, and maxZoom directly to L.map(). Scroll-wheel zoom and double-click zoom are disabled; dragging is on.
leaflet:
t-passthrough:
center: [40.7128, -74.006]
zoom: 14
height: "340px"
zoomControl: false
scrollWheelZoom: false
dragging: true
doubleClickZoom: false
keyboard: false
minZoom: 10
maxZoom: 181.16 Passthrough Leaflet options — full map option set
Exercises the remaining top-level L.map() options listed in README, including mixed-type options like doubleClickZoom, scrollWheelZoom, and touchZoom with the string value "center".
leaflet:
t-passthrough-all:
center: [40.7128, -74.006]
zoom: 13
height: "340px"
zoomControl: true
attributionControl: true
closePopupOnClick: true
minZoom: 3
maxZoom: 18
zoomSnap: 0.5
zoomDelta: 0.5
trackResize: true
boxZoom: true
doubleClickZoom: "center"
dragging: true
scrollWheelZoom: "center"
inertia: true
inertiaDeceleration: 3200
inertiaMaxSpeed: 1400
easeLinearity: 0.2
worldCopyJump: false
maxBoundsViscosity: 0.5
keyboard: true
keyboardPanDelta: 80
wheelDebounceTime: 40
wheelPxPerZoomLevel: 60
touchZoom: "center"
bounceAtZoomLimits: true
tapHold: true
tapTolerance: 15
zoomAnimation: true
zoomAnimationThreshold: 4
fadeAnimation: true
markerZoomAnimation: true
transform3DLimit: 8388608
preferCanvas: false1.17 Custom tile layer — all listed tile options
Exercises all listed tile sub-options from README in a single map config.
leaflet:
t-tile-all-options:
center: [40.7128, -74.006]
zoom: 11
height: "340px"
tile:
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution: "© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"
minZoom: 0
maxZoom: 19
minNativeZoom: 0
maxNativeZoom: 19
subdomains: "abc"
errorTileUrl: "https://tile.openstreetmap.org/0/0/0.png"
zoomOffset: 0
tms: false
zoomReverse: false
detectRetina: false
crossOrigin: "anonymous"
referrerPolicy: "no-referrer"
opacity: 0.95
zIndex: 1
className: "ql-test-tile"
pane: "tilePane"
tileSize: 256
updateWhenIdle: false
updateWhenZooming: true
updateInterval: 200
keepBuffer: 2
noWrap: false2 Inline shortcode maps
2.1 Minimal inline — center + zoom
{{< leaflet center="[48.86, 2.35]" zoom=14 >}}2.2 Inline with explicit height
{{< leaflet center="[48.86, 2.35]" zoom=14 height="320px" >}}2.3 Inline with passthrough options
scrollWheelZoom and zoomControl passed inline.
{{< leaflet center="[35.68, 139.69]" zoom=11 height="320px" scrollWheelZoom=false zoomControl=false >}}2.4 Inline passthrough with string-valued options
Checks that case-sensitive string values are preserved inline (for options that accept string forms in Leaflet).
{{< leaflet center="[35.68, 139.69]" zoom=11 height="320px" scrollWheelZoom="center" touchZoom="center" doubleClickZoom="center" >}}2.5 Inline custom tile JSON
Checks inline tile JSON object parsing.
{{< leaflet center="[40.7128, -74.006]" zoom=11 height="320px" tile='{"url":"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png","attribution":"© OpenStreetMap"}' >}}2.6 Inline custom tile JSON (single-item array wrapper)
Checks backward-compatible parsing of tile as a one-element JSON array.
{{< leaflet center="[40.7128, -74.006]" zoom=11 height="320px" tile='[{"url":"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png","attribution":"© OpenStreetMap"}]' >}}2.7 Inline with JSON markers
Markers are supplied as a JSON string.
{{< leaflet center="[59.33, 18.07]" zoom=12 height="320px"
markers='[{"lat":59.33,"lon":18.07,"popup":"<b>Stockholm</b>","tooltip":"Stockholm"},{"lat":59.35,"lon":18.10,"popup":"Djurgården"},{"lat":59.31,"lon":18.05,"popup":"Södermalm"}]' >}}2.8 Inline with TSV markers (markers-file + separator)
{{< leaflet center="[59.33, 18.07]" zoom=12 height="320px" markers-file="data/stockholm-markers.tsv" markers-sep="\t" >}}2.9 Inline with CSV markers
{{< leaflet center="[59.33, 18.07]" zoom=12 height="320px" markers-file="data/stockholm-markers.csv" >}}2.10 Inline with semicolon-separated .txt markers
{{< leaflet center="[59.33, 18.07]" zoom=12 height="320px" markers-file="data/stockholm-markers-semicolon.txt" markers-sep=";" >}}2.11 Multiple inline maps on the same page
Each map must receive a unique HTML id and JS variable name.
{{< leaflet center="[35.68, 139.69]" zoom=10 height="260px" >}}
{{< leaflet center="[-33.87, 151.21]" zoom=11 height="260px" >}}2.12 Inline Font Awesome icons
This checks inline JSON markers using Font Awesome classes.
{{< leaflet center="[41.9028, 12.4964]" zoom=13 height="320px"
markers='[{"lat":41.9028,"lon":12.4964,"popup":"<b>Roman Forum</b>","icon":"fa-solid fa-landmark","icon-color":"#b04a2b","icon-size":20},{"lat":41.89,"lon":12.4922,"popup":"<b>Colosseum</b>","icon":"fa-solid fa-torii-gate","icon-color":"#5c6f7b","icon-size":20},{"lat":41.8986,"lon":12.4768,"popup":"<b>Piazza Navona</b>","icon":"fa-solid fa-tree","icon-color":"#2f7d32","icon-size":20}]' >}}3 Error handling
All cases below must not crash Quarto rendering. The extension either emits a visible error notice or silently skips the offending input.
3.1 No arguments whatsoever
With no center and no usable marker coordinates, the extension must report the error without crashing.
{{< leaflet >}}Expected: visible error — 'center' is required
⚠ leaflet: 'center' is required
3.2 Named label that does not exist in metadata
{{< leaflet no-such-map >}}Expected: visible error — map 'no-such-map' not found in metadata
⚠ leaflet: map 'no-such-map' not found in metadata
3.3 Invalid center — no brackets
{{< leaflet center="51.505,-0.09" zoom=13 >}}Expected: visible error — 'center' is required (no marker coordinates are available to derive it)
⚠ leaflet: 'center' is required
3.4 Invalid center — only one coordinate
{{< leaflet center="[51.505]" zoom=13 >}}Expected: visible error — 'center' is required (no marker coordinates are available to derive it)
⚠ leaflet: 'center' is required
3.5 Invalid center — non-numeric values
{{< leaflet center="[abc, xyz]" zoom=13 >}}Expected: visible error — 'center' is required (no marker coordinates are available to derive it)
⚠ leaflet: 'center' is required
3.6 Invalid center — empty brackets
{{< leaflet center="[]" zoom=13 >}}Expected: visible error — 'center' is required (no marker coordinates are available to derive it)
⚠ leaflet: 'center' is required
3.7 Invalid center — too many coordinates
{{< leaflet center="[51.5, -0.09, 100]" zoom=13 >}}Expected: visible error — 'center' is required (parser requires exactly 2 values and no marker coordinates are available)
⚠ leaflet: 'center' is required
3.8 Zoom as non-numeric string
zoom is invalid (tonumber returns nil); the shortcode falls back to 13.
{{< leaflet center="[51.505, -0.09]" zoom="very-high" height="300px" >}}Expected: map renders with zoom level 13
3.9 Inline markers without center
Center is derived from the midpoint of the bounding box of the marker coordinates.
Expected: map renders and auto-centers on the marker centroid
3.10 YAML markers without center or zoom
Both values are derived from defaults: center from the marker centroid, zoom from the shortcode default.
Expected: map renders centered on the three markers at zoom 13
3.11 Marker file without center or zoom
The shortcode derives center from the file coordinates and uses zoom 13.
Expected: map renders with TSV markers, auto-centered at zoom 13
3.12 Invalid JSON for inline markers
Markers are silently dropped; the map still renders.
{{< leaflet center="[51.505, -0.09]" zoom=13 height="300px" markers="not-json-at-all" >}}Expected: map renders without markers
3.13 Inline markers JSON — wrong root type (not an array)
{{< leaflet center="[51.505, -0.09]" zoom=13 height="300px" markers='{"lat":51.5,"lon":-0.1,"popup":"object not array"}' >}}Expected: map renders without markers (JSON object instead of array is ignored)
3.14 Inline marker with missing position in JSON array
The marker without position is silently skipped; valid markers are added.
{{< leaflet center="[51.505, -0.09]" zoom=13 height="300px"
markers='[{"popup":"no position"},{"lat":51.5,"lon":-0.1,"popup":"valid marker"}]' >}}Expected: map renders with one marker (lat 51.5, lon -0.1)
3.15 YAML map with bad marker entries mixed with valid ones
Uses the t-bad-markers YAML map (defined in frontmatter) which includes:
- A marker with no
positionkey → skipped - A marker with
position: "not-a-list"→ skipped - Two valid markers → rendered
Expected: map renders with 3 visible markers (valid + out-of-range as Leaflet handles it)
3.16 YAML tile given as a boolean, not a sub-table
Uses the t-tile-bool YAML map where tile: true instead of a sub-object.
Expected: map renders using the default OpenStreetMap tile layer
3.17 Unknown / extra kwargs (passthrough)
Unrecognised kwargs are forwarded to L.map() as options. Leaflet ignores unrecognised options, so no error should occur.
{{< leaflet center="[51.505, -0.09]" zoom=13 height="280px" unknownOption="foo" anotherFake=42 >}}Expected: map renders normally (unknown options are ignored by Leaflet)
3.18 Wrong separator for markers-file
The file exists, but markers-sep is intentionally wrong. Rows should fail to parse into valid marker coordinates, while the map itself still renders without crashing.
{{< leaflet center="[59.33, 18.07]" zoom=12 height="300px" markers-file="data/stockholm-markers-semicolon.txt" markers-sep="," >}}Expected: map renders, but no markers are added.
3.19 Multiple positional args (not a valid named-label call)
When more than one positional arg is given, the shortcode falls through to kwargs mode. With no center kwarg the extension must report the missing argument because there are still no marker coordinates to derive it.
{{< leaflet t-basic extra-arg >}}Expected: visible error — 'center' is required
⚠ leaflet: 'center' is required
3.20 Named label call with extra kwargs (kwargs win)
When both a positional label and kwargs are present, the code switches to kwargs mode and the label is ignored. With no center kwarg the shortcode reports the error because there are no marker coordinates in kwargs.
{{< leaflet t-basic zoom=13 >}}Expected: visible error — 'center' is required (label is ignored; center kwarg and marker coordinates are absent)
⚠ leaflet: 'center' is required