Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tags Laravel Package

cortex/tags

Cortex Tags provides a Laravel tagging system for associating reusable tags with your models. It includes helpers for managing tags and querying tagged records, making it easy to organize and filter content.

View on GitHub
Deep Wiki
Context7

Getting Started

cortex/tags is not a tagging engine — it's the HTTP/admin layer that sits on top of Cortex's polymorphic taggable backend. Before you write a line of code, confirm you actually need this package: if you want $post->attachTag('laravel') in your app, you want the backend package (cortex/taggable or its Rinvex equivalent), not this one. Reach for cortex/tags only when you want ready-made controllers/routes/requests for managing tags over HTTP.

Minimal steps:

  1. Check compatibility first. The repo is archived and has ~6 stars. Open composer.json before installing and note the laravel/framework, php, and Cortex-sibling version constraints. On anything newer than Laravel 6/7 you will likely need --ignore-platform-reqs or a fork. This is the single biggest decision point.
  2. Install the backend + frontend pair. composer require cortex/tags will pull the taggable layer as a dependency; verify the resolved versions in composer.lock rather than trusting the README.
  3. Register the provider. Cortex "classic" packages predate full package auto-discovery in some versions — check config/app.php and any cortex/fort bootstrap config.
  4. Publish and run migrations. Typically php artisan vendor:publish --tag=cortex-tags-migrations followed by php artisan migrate. Confirm you now have a tags table and a taggables morph pivot.
  5. Add the trait to a model. Put the taggable trait on Post (or whatever you're tagging) and verify $post->tags returns a collection.
  6. Hit the routes. Load the package's route file/prefix and GET the tag index. If it renders or returns JSON, the frontend layer is wired correctly — that's your smoke test before touching config.

First real use case: an admin screen that lists, creates, edits, and deletes tags, with a slug-based public URL (/tags/laravel) for browsing tagged content.

Implementation Patterns

Treat the HTTP layer as optional scaffolding. The most common day-to-day pattern is to keep the backend trait and replace the package controllers with your own thin resource controller. You get the polymorphic relations and slugging for free, and full control over authorization, pagination, and response shape.

Attach on write, read via relation. In a form request or action class, sync tags on save:

$post->syncTags($validated['tags']); // IDs or names, depending on backend API

Keep attach/detach inside a transaction with the parent save so a failed tag write doesn't leave a half-saved post.

Use slugs as the public contract. The Sluggable integration means tag URLs should be /tags/{tag:slug}. Enable route model binding on the slug column and never expose raw IDs in links — renaming a tag then doesn't break inbound links if you keep the old slug as a redirect.

Lean on Translatable for display, not identity. Store tag identity as the slug (locale-independent) and translate the name. Render with $tag->getTranslation('name', app()->getLocale()) and always provide a fallback locale.

Compose with an admin panel carefully. If you're already on cortex/fort, let it own routing/auth. If you're not, don't half-adopt it — mount the package routes behind your own auth/can:manage-tags middleware group in a service provider.

Cache the read path. $post->tags and the tag index are read far more than written. Cache per-post tag lists and the full tag cloud, and bust them in the attach/detach path (model events on the pivot are the reliable hook).

Extend by substitution, not modification. Bind your own Tag model and controller in the container/config rather than editing vendor files — the package will never receive upstream fixes, so your overrides are the real codebase.

Gotchas and Tips

  • Archived means frozen. No security patches, no Laravel 10/11 support, no PHP 8.x guarantees. Budget for a fork or a migration to spatie/laravel-tags / rinvex/laravel-tags if this is a long-lived project. Do the migration cost estimate before the prototype.
  • Morph map or regret. If taggables.taggable_type stores fully-qualified class names, renaming or moving a model silently orphans every tag relationship. Register a Relation::morphMap() early, before production data exists.
  • Pivot orphans on delete. Verify the migration sets onDelete('cascade') on the morph columns. Classic Cortex migrations often didn't; add it in your own migration if missing, otherwise deleting a post leaves dangling taggables rows that break counts.
  • Slug collisions are global. Two tags named "Laravel" from different contexts will fight over laravel. If you need per-tenant or per-type tag namespaces, override the Sluggable behavior with a scoped uniqueness rule rather than relying on the default.
  • Slug + translation interaction. Slugs usually generate from the default locale at creation. Changing the app or default locale later doesn't regenerate them — set slugs explicitly if you care about URL stability.
  • Config drift. Cortex packages read settings from config/cortex-tags.php and sometimes from a settings repository. When a route prefix or middleware change "doesn't take", check both and clear config cache (php artisan config:clear).
  • Debug the query, not the relation. When tags don't attach, dump the SQL with DB::listen() or ->toSql() on the morphToMany — nine times out of ten it's a mismatched morph type or a missing taggable_id index, not a package bug.
  • Authorization is yours. Don't assume the shipped controllers check policies. Wrap the tag-management routes in explicit gates before exposing them.
  • Test on a fresh database. Because migrations and pivot schema are inherited from a stale package, run the full install on an empty DB in CI — reproducing "works on my machine" pivot mismatches is expensive.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console