visuellverstehen/statamic-classify
Statamic Classify lets you organize entries with custom classifications. Add a fieldtype to your collections, create classification groups, and use Antlers tags to query and display related content. Ideal for categories, tags, and any custom content organization.
Requirements (v4): PHP 8.3+, Laravel 11/12/13, Statamic 5/6. If you're still on Statamic 4 or Laravel 10, stay on ^3.2 and plan an upgrade first — v4 is a hard cut, not a soft deprecation.
composer require visuellverstehen/statamic-classify
There's no mandatory install/seed step; the package registers a fieldtype and augments the control panel automatically. Publish the config only if you need to override defaults:
php artisan vendor:publish --tag="statamic-classify-config"
Where to look first:
config/statamic/classify.php (after publishing) for defaults you might want to change once and forget.First use case (5 minutes): add a classification field to a blog entry blueprint, point it at your existing tags and categories taxonomies, and render it on a post page:
# resources/blueprints/collections/posts/post.yaml
handle: post_classification
field:
type: classify
display: Classify
taxonomies:
- tags
- categories
Then in Antlers/Blade, loop the field as you would any taxonomy field. That's the day-to-day: editors pick terms inline on the entry publish form instead of you building one taxonomy field per taxonomy and wiring categories + tags side-by-side in every blueprint.
One field, many taxonomies. The core win is collapsing N taxonomy fields into a single control panel input. Standardise on one handle (classification or topics) across all collections so your templates and queries are portable:
# resources/blueprints/collections/articles/article.yaml
handle: topics
field:
type: classify
display: Topics
taxonomies:
- topics
- tags
- series
Template partials beat inline loops. Because the field can hold terms from different taxonomies, always branch on the taxonomy before rendering — otherwise a "Series" term ends up styled like a tag:
{{ if topics }}
<ul class="topics">
{{ topics }}
<li class="topic topic--{{ taxonomy.handle }}">
<a href="{{ url }}">{{ title }}</a>
</li>
{{ /topics }}
</ul>
{{ /if }}
Keep this in resources/views/partials/_topics.antlers.html and include it from every listing card, detail page, and RSS/Og meta block. Consistency here is what makes the fieldtype feel native rather than bolted on.
Filtering and archive pages. Classified terms are real taxonomy terms, so you keep using Statamic's taxonomy query API rather than anything package-specific:
{{ collection:articles taxonomies:topics:is="{slug}" }}
Route your archive pages through the taxonomy routes (/topics/{slug}) and let Statamic resolve the term — don't hand-roll a where on the classify field value itself. If you need multi-term filtering (OR logic), build it with a taxonomies:topics:in="a|b" style constraint and test the Stache index behaviour on a realistic dataset before shipping.
Editorial workflow. The practical pattern that pays off is scoping: give marketing a topics field limited to two curated taxonomies, and give internal content a wider field. Because the field config lives in blueprints, you can differ per collection/per site without touching PHP.
Multi-site. Term selection is per-entry, but the taxonomy itself is usually localisable. When you localise taxonomies, an entry in the second site needs its own classification saved — it does not automatically inherit. Add a check to your content QA (or a simple test) if you have many localised entries.
Testing. The package itself moved to Pest 4 in v4, which is irrelevant to your app, but the pattern is worth copying: write a feature test that saves an entry with two terms from different taxonomies and asserts the rendered page contains both, plus a test asserting an entry with no terms renders without an empty <ul>.
Upgrading from v3 is a two-step. v4 requires Statamic 5 and Laravel 11. If you're on Statamic 4, upgrade Statamic first (with this package still on ^3.2), get green, then bump this package. Doing both at once makes failures hard to attribute.
The removed laravel/framework constraint is a subtle one. v4 lets statamic/cms dictate the Laravel version transitively. That's correct dependency hygiene, but it means your lockfile's Laravel version now depends on whatever statamic/cms allows. After upgrading, run composer update statamic/cms visuellverstehen/statamic-classify --with-dependencies and check composer why laravel/framework if you're pinning Laravel anywhere.
Version pinning for CI. Since v4 claims Laravel 13 support that's very fresh, pin exact versions in CI rather than floating ^13.0 until you've verified the control panel fieldtype actually renders — vendor compatibility claims are usually validated against the test matrix, not against your specific field configuration.
Terms must exist. Classification selects from existing taxonomy terms; it isn't a free-text tag creator. If editors report "I can't add the term," the fix is almost always creating the term in the taxonomy first, not a fieldtype bug. Decide early whether editors get taxonomy create permission — if not, budget for an editor to curate the term list.
Empty state hygiene. A classify field with no terms augments to an empty collection, not null, in some contexts. Use {{ if topics }} guards everywhere; {{ topics | length }} checks catch it but a bare loop silently emits your <ul> wrapper with no children.
Stache and caching. Changes to taxonomy term titles/slugs won't always show on already-rendered entries until the Stache updates. In development, php artisan statamic:stache:clear is the fastest way to rule out stale data before you start debugging templates. In production, ensure your deploy runs the Stache warmup.
Inside Replicator/Grid. Nesting a classify field in a Replicator set works, but augmentation shapes get nested accordingly — you'll need a second loop level. If you're doing this, prefer a top-level field; nested classification makes archive/query logic substantially harder for little editorial gain.
Debugging augmentation. When output looks wrong, {{ dump }} on the raw field first, then re-run with the loop. The failure mode is almost always that you're iterating a taxonomy collection when the field returned entries/augmented values, or vice versa — confirm the shape before touching the template.
Extension points are thin by design. There's no plugin system here; if you need custom label formatting or ordering, do it in an Antlers partial or a small view component, not by extending the fieldtype. Forking a single-fieldtype addon for presentation logic is a maintenance trap.
How can I help you explore Laravel packages today?