madeyourday/contao-rocksolid-icon-picker
A Contao extension that adds an icon picker field for selecting icons in the backend, making it easy to assign icons to content elements and templates. Part of the RockSolid custom content elements toolkit, with documentation available in English and German.
Know what you're installing first. madeyourday/contao-rocksolid-icon-picker is a Contao bundle (composer type contao-module), not a Laravel package. It registers a DCA field so editors get a visual icon grid instead of typing CSS classes. In a pure Laravel app, composer require will drop files into vendor/ and do nothing else: no service provider, no routes, no vendor:publish. So "getting started" splits into two tracks:
You are on Contao 4.13+/5.0 — install it and use it directly:
composer require madeyourday/contao-rocksolid-icon-picker
Then clear the Contao cache (var/cache) and look in the bundle's src/ + dca/ folders for the field class and its eval keys. The vendor docs (rocksolidthemes.com, EN/DE links in the README) are the only prose documentation — the changelog is your real API reference. The changelog confirms the keys you'll actually touch: fontPath, the optional blank/"none" entry, and the icon font family.
You are on Laravel — treat the package as a reference implementation and an icon-font asset source. First files to open: the bundled WOFF/WOFF2 fonts and their @font-face CSS, the picker template (how icons are rendered and titled), and the field class (how icon names are discovered from the CSS). That's the 90% you can reuse; the DCA plumbing is the 10% you replace.
First use case to build: a "feature card" or "button" content block where an editor picks an icon and the front end renders <i class="icon icon-{{ $icon }}">. In Contao that's a DCA field + palette entry. In Laravel that's a string column, a validation rule against an icon manifest, and a Blade partial:
{{-- resources/views/components/icon.blade.php --}}
<i class="icon icon-{{ $name }}" aria-hidden="true" title="{{ $title ?? '' }}"></i>
Pick this package over hand-rolling when you want the visual grid UX and a ready icon font rather than SVG-per-icon, and when your editors are non-technical.
Pattern A — Native Contao DCA field (the intended path). Add the field to tl_content (or your own table) via dca/*.php, set fontPath to your icon font's CSS, and reference the field in a palette. Behaviours baked in and worth copying into any reimplementation:
title attributes (v2.0.2) — keep that for accessibility.Pattern B — Laravel: port the manifest, not the DCA. Build a single source of truth for icons and generate everything from it:
// config/icons.php (or storage/app/icons.json generated by a command)
return [
'rocket' => ['title' => 'Launch', 'class' => 'icon-rocket'],
'user' => ['title' => 'Account', 'class' => 'icon-user'],
];
Then:
'icon' => ['nullable', Rule::in(array_keys(config('icons')))], — never trust the raw class string.Pattern C — Filament / Nova admin panel. Wrap the same manifest in a Select with ->options() plus a custom option view that emits <i class="icon ...">, or a Radio with grid columns. This is the closest Laravel analogue to the DCA field and takes an afternoon.
Pattern D — Filament-style "swap the set" abstraction. Store a slug (user), not a CSS class (fa-user). It survives font swaps (Font Awesome → bundled WOFF set → SVG sprite) without a data migration, and it lets you keep the package's font for now and move to Blade Icons/Heroicons later.
Asset pipeline. Copy the WOFF2/WOFF fonts into resources/fonts/ and let Vite rewrite the URLs — do not copy the vendor @font-face block verbatim, because it points at Contao-symlinked web/ paths:
@font-face {
font-family: 'rs-icons';
src: url('../fonts/rs-icons.woff2') format('woff2'),
url('../fonts/rs-icons.woff') format('woff');
font-display: swap;
}
.icon { font-family: 'rs-icons'; font-style: normal; line-height: 1; }
Load the icon CSS only in your admin layout (and wherever the front end genuinely uses the icons) — it's a full icon font, so don't ship it to every public page if you only use three glyphs.
Hybrid Contao + Laravel. If you run a bridge/embedded backend, let Contao own the picker and expose the stored value read-only to Laravel (repository or small API endpoint). Don't try to render a Contao DCA widget from Blade — you'll inherit the widget's JS, its save-mode handling, and its backend asset loading for zero benefit.
vendor:publish or a config file is wrong for this package.fontPath is the number-one failure point. v2.0.2 fixed paths starting with web/; v2.0.5-era fixes covered Windows path separators and empty fontPath. If icons silently don't render, check fontPath first, then the font family name — v1.0.3 existed because IE choked on over-long family names.composer install leaves you with 403s or a symlink loop, that's a known class of problem, not your server being weird. In Laravel you avoid it entirely by copying fonts into resources/ and building with Vite.title attributes and dark theme are features, not decoration. Use fill: currentColor / inherit colour when you port the CSS, or your icons will be invisible in dark admin themes (the 2.1.1 work exists for exactly this).@font-face, and if you're on Laravel you're writing that regardless.composer.json, and if you depend on undocumented eval keys, read the field class in vendor/ rather than guessing — the changelog references DCA-config access bugs (#12) that only surface once you start customising fields.var/cache, verify the palette actually references the field, inspect the rendered <i> classes; Laravel → config:clear/view:clear after editing the manifest, and check that the font file is emitted by Vite (public/build/manifest.json).fontPath) and point fontPath at your own stylesheet. In Laravel the equivalent extension point is the manifest array — which is why storing slugs rather than classes matters.How can I help you explore Laravel packages today?