Kirby Helpers is a collection of useful helper functions for Kirby CMS.
- 🎨 CSS Helpers - Lazy loading, conditional loading by template or block type
- 🔗 Link Helpers - Automatic link labels, external link detection, mailto builders
- 📝 String Helpers - Prefix/suffix utilities for consistent formatting
- 🌐 Translation Helpers - Translation status checking, filtering, and badges
- ♿️ Accessibility - SVG accessibility attributes, automatic link titles
- 🎯 Block Helpers - Extract and analyze block types for conditional styling
- ⚡️ Vite Integration - Dev mode detection, asset inlining
- 🏗️ HTML Utilities - Heading level validation and manipulation
To install Kirby Helpers via Composer, run the following command:
composer require timnarr/kirby-helpersLoad a CSS file lazily using preload with low priority.
cssLazy('assets/css/carousel.css');
cssLazy(vite()->asset('styles/carousel.scss'), true);Load CSS only if a specific block type is used on the page.
$pageBlocks = getUsedBlockTypes($page->text()->toBlocks());
cssIfBlock('assets/css/carousel.css', 'carousel', $pageBlocks);
cssIfBlock(vite()->asset('styles/carousel.scss'), 'carousel', $pageBlocks, true);Load CSS only for specific page template(s).
cssIfTemplate('assets/css/contact.css', 'contact');
cssIfTemplate('assets/css/forms.css', ['contact', 'signup']);Ensure a string starts with a specific prefix.
ensureLeft('example.com', 'https://'); // 'https://example.com'
ensureLeft('https://example.com', 'https://'); // 'https://example.com'Ensure a string ends with a specific suffix.
ensureRight('example', '.com'); // 'example.com'
ensureRight('example.com', '.com'); // 'example.com'Ensure a string starts with a hash character (#). Useful for anchor links.
ensureHashed('section-1'); // '#section-1'
ensureHashed('#section-1'); // '#section-1'Generate an HTML heading element with specified level, text, and attributes.
heading('h2', 'Welcome', ['class' => 'title']);
// <h2 class="title">Welcome</h2>Increment or decrement a heading level, clamped between h1 and h6.
incrementHeadingLevel('h2', 1); // 'h3'
incrementHeadingLevel('h2', -1); // 'h1'
incrementHeadingLevel('h6', 1); // 'h6' (clamped)Validate a heading level string. Throws exception if invalid.
validateHeadingLevel('h2'); // OK
validateHeadingLevel('h7'); // Throws InvalidArgumentExceptionExtract all used block types from a Blocks object or array. Useful for conditional CSS loading.
$pageBlocks = getUsedBlockTypes($page->text()->toBlocks());
// ['heading', 'text', 'image', 'gallery']
// Use with cssIfBlock
cssIfBlock('assets/css/gallery.css', 'gallery', $pageBlocks);Determine if a link is external and return appropriate attributes (target="_blank" for external links).
setBlankIfExternal('https://example.com');
// ['href' => 'https://example.com', 'target' => '_blank']
setBlankIfExternal('mailto:[email protected]');
// ['href' => 'mailto:[email protected]']Generate accessible link labels for different link types.
linkLabel('internal', $page); // "Link to page: {title}"
linkLabel('external', 'https://example.com'); // "External link: https://example.com (Opens new tab)"
linkLabel('document', $file); // "Download file: document.pdf (2.5 MB)"
linkLabel('mail', '[email protected]'); // "Send email to: [email protected]"
linkLabel('tel', '+1234567890'); // "Call phone number: +1234567890"Build a mailto link with optional subject and body parameters.
buildMailtoLink('[email protected]', 'Hello', 'This is a test');
// 'mailto:[email protected]?subject=Hello&body=This%20is%20a%20test'
buildMailtoLink('[email protected]', 'Hello', 'Line 1\nLine 2');
// Line breaks are properly encodedshouldIgnorePageFromCache(Page $page, Pages|null $ignoredPages, array $ignoredSlugs = [], array $ignoredTemplates = []): bool
Determine if a page should be excluded from caching.
shouldIgnorePageFromCache($page, site()->notCachedPages()->toPages(), ['my-slug'], ['contact']);Get available translation language codes for a page (excluding current language).
getAvailableTranslations($page); // ['de', 'fr']Get an array of language codes for which the page translation does not exist.
getMissingTranslations($page); // ['de', 'fr']readAccessible(File $file, string $title = '', string $description = '', bool $isDecorative = false): string
Read and enhance SVG files with accessibility attributes (title, description, ARIA attributes).
readAccessible($file, 'Icon description', 'Detailed description');
readAccessible($file, '', '', true); // Decorative SVG with aria-hiddenCheck if Vite is in development mode by verifying manifest file presence.
if (isViteDevMode()) {
// Development-specific code
}Inline Vite assets (stylesheet or script) based on environment.
inlineViteAsset('main.css', 'stylesheet');
inlineViteAsset(['app.js', 'vendor.js'], 'script');Ensure a field value starts with a specific prefix. Returns the field for chaining.
$page->url()->ensureLeft('https://')->value();Ensure a field value ends with a specific suffix. Returns the field for chaining.
$page->path()->ensureRight('/')->value();Ensure a field value starts with a hash character (#). Useful for anchor links. Returns the field for chaining.
$page->anchor()->ensureHashed()->value();
// 'section-1' becomes '#section-1'Automatically add accessible title attributes to all links in HTML content. Detects internal pages, files, email, phone, and external links. Returns the field for chaining.
$page->text()->kirbytext()->autoLinkTitles();
// Adds appropriate title attributes to all <a> tags$file->readAccessible('Icon title', 'Icon description');if ($page->hasTranslations()) {
// Page has translations
}$translations = $page->getTranslations(); // ['de', 'fr']Get an array of language codes for which the page translation does not exist.
$missing = $page->missingTranslationCodes(); // ['de', 'fr']Generate a Kirby Panel info badge showing translation status. Returns a green badge if all translations exist, or a red badge with missing language codes.
echo $page->missingTranslationsBadge();
// <span class="k-info-badge" data-theme="green">All translated</span>
// or
// <span class="k-info-badge" data-theme="red">Missing: DE, FR</span>The following options are available for customization:
| Option | Default | Type | Description |
|---|---|---|---|
vite.manifestPath |
kirby()->root() . '/build/manifest.json' |
string | Path to vites manifest file to determine dev mode. Used by isViteDevMode() |
Translations are required for the labels returned by the linkLabel() function. This plugin provides translations for English and German. The following translation keys are available for customization:
| Key | Default |
|---|---|
link_label_internal_home |
Link to homepage: { title } |
link_label_internal |
Link to page: { title } |
link_label_document |
Download file: { filename } |
link_label_external |
External link: { url } (Opens new tab) |
link_label_mail |
Send email to: { mail } (Opens new window of your email program) |
link_label_tel |
Call phone number: { tel } (Opens new window/program) |
Kirby Helpers is licensed under the MIT License. © 2024-present Tim Narr