Examples

Examples

A cookbook — short, copy-pasteable recipes for things a real project needs, not a repeat of the reference.

Docs is the exhaustive reference; the tutorial is a guided walk. This page sits between the two: real, working snippets for specific things — no new concepts, just the pieces from Docs combined the way an actual project ends up using them. Two of the recipes below are actually registered on this site's own _lib/functions.php and demoed live, right where the code says they are.


Config only

SEO and social cards, in two lines

No <title>, no Open Graph tags to hand-write. One block in kirigami.yaml — the unified seo: surface — opts every page into <title>, description, keywords, Open Graph, Twitter Card, canonical link, and (nested inside it, its own independent opt-in) JSON-LD — derived from the kirigami: block plus each page's own PHPDOC:


                        seo:
                          jsonld: {}
                    

A page overrides just what it needs from its own header — @meta_description, @meta_image, @og_type, … — without touching the other pages. Full reference: seo / seo.jsonld. This site runs on exactly this, nothing hand-written in _layouts/header.php.


Live — registered on this page

A one-off Markdown shortcode

A project doesn't need a published plugin for a shortcode it only uses itself — MD::registerPlugin() straight from prepros.includes is enough. This one wraps canva's .badge:


                        // _lib/functions.php
                        md_register_plugin('badge', function (array $args, string $body): string {
                            $tone = ($args[0] ?? 'default') === 'muted' ? ' badge--muted' : '';
                            $text = implode(' ', array_slice($args, 1));
                            if ($text === '') return '<!-- badge: missing text -->';
                            return '<span class="badge' . $tone . '">' . str_htmlesc($text) . '</span>';
                        });
                    

Used right here, in this page's own Markdown:


                        {% badge default Stable %} {% badge muted "Coming soon" %}
                    
Stable Coming soon

{% %} plugins work inside <markdown> blocks, .md data files, and anywhere else MD::toHtml() runs. Full mechanics, including the default shortcodes Kirigami ships: Writing pages → MD plugins.


Live — registered on this page

A one-off HTML tag

Same idea via PREPROS::registerTag() — an authoring tag that expands at render time, for markup instead of {% %} shortcodes. This one turns a +-separated key combo into a row of <kbd>:


                        // _lib/functions.php
                        register_tag('shortcut', function (string $tag, array $attrs, string $body): string {
                            $keys = array_filter(array_map('trim', explode('+', $attrs['keys'] ?? '')));
                            if (!$keys) return '<!-- shortcut: missing keys attribute -->';
                            return implode('', array_map(fn($k) => '<kbd>' . str_htmlesc($k) . '</kbd>', $keys));
                        });
                    

Used right here:


                        <shortcut keys="Ctrl+K">
                    

Ctrl K

PREPROS::registerTag() is also how a real plugin — not just a one-off in prepros.includes — adds its own tag; see <extlink> or Writing a plugin for the packaged version of the same mechanism.


FS::getChildren()

A page list that maintains itself

A hub page that auto-lists its own sub-pages, in @position order, straight from their PHPDOC — no array to keep in sync when a page is added or removed. This is exactly how Docs builds its own card grid:


                        $sections = fs_get_children();

                        foreach ($sections as $s) {
                            $href = kirigami_page_href($s, $relroot);
                            echo '<a class="card" href="' . str_htmlesc($href) . '">'
                               . '<h3>' . str_htmlesc($s->title ?? '') . '</h3>'
                               . '<p>' . str_htmlesc($s->abstract ?? '') . '</p>'
                               . '</a>';
                        }
                    

kirigami_page_href() is this site's own two-line helper turning a child's ->file into a relative URL — see it in _lib/functions.php. Full signature: FS.



Live — the default Markdown plugin

The same thing, one line, inside Markdown

For a single image dropped straight into prose — no PHPDOC annotation, no loop — {% img-asset %} is the same IMG::asset() call as a Markdown shortcode, shipped by default (no plugin to install):


                        {% img-asset male-african-bush-elephant.jpg 320 180 cover %}
                    

Positional args: path [width [height [cover]]] — a missing or unresolvable path degrades to an HTML comment instead of failing the build. Full mechanics: Writing pages → MD plugins.


Two official plugins

Rich cards without hand-rolled scraping

Link previews and video embeds both look like small scraping projects until you actually need caching, image cropping, and an oEmbed lookup that doesn't block the build. Two plugins do the work:


                        <extlink src="https://github.com/php-kirigami/kirigami">

                        <youtube id="jNQXAC9IVRw">
                        <vimeo id="1084537">
                    

<extlink> scrapes once at build time and caches to disk — <youtube>/<vimeo> resolve client-side, cached in localStorage, nothing fetched until the visitor clicks play. Both are demoed live, with the real cards, on Plugins.