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

Taxonomy Laravel Package

mibo/taxonomy

Taxonomy management for Laravel: organize content with categories, tags, and hierarchical terms. Provides reusable models, relationships, and helpers for attaching and querying taxonomies across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a plain PHP library (MIT, no Laravel-specific glue advertised), so "getting started" means proving it fits before you wire it in.

  1. Read the repo in this order, before installing: composer.json → src/ → tests/. For a library with zero dependents and zero stars, the source is the documentation. At this size it is a 20–40 minute read, and it tells you the PHP version floor, the PSR-4 (or PSR-0) mapping, and whether there are any illuminate/* or framework extras.
  2. Install and pin:
    composer require mibo/taxonomy --prefer-dist
    composer show mibo/taxonomy   # confirm the resolved version and PHP constraint
    
  3. Write one throwaway test before any integration code. Construct a taxonomy, add terms, assert on retrieval/ordering. If the API doesn't map to your domain in that single test, you've spent 15 minutes instead of two days on an adapter you'll delete.
  4. First real use case: a term/taxonomy value object at the edge of your domain — hydrating a Taxonomy/Term-style object from a JSON column or an API payload, doing hierarchy/sibling lookups in memory, and serialising back. Do not start by replacing your categories table with it; this is a data-structure library, not a persistence layer.

Where to look first in your own codebase: whatever currently does parent_id recursion, slug generation, or flat-list-to-tree conversion. That's the seam this package can plausibly occupy.

Implementation Patterns

Wrap it behind a narrow adapter. Put a single class in app/Support/Taxonomy/ (or a small domain service) that exposes 5–10 methods you actually use — findBySlug, childrenOf, tree, flatten — and delegates to the vendor classes. Every vendor call site outside that file is a future upgrade tax.

Bind it, don't new it. Even without a service provider shipped, register the adapter (and any shared/configured instance) in AppServiceProvider:

$this->app->singleton(TaxonomyRepository::class, fn () => new TaxonomyRepository(
    new \Mibo\Taxonomy\... // whatever the entry point is
));

This gives you a mockable seam in tests and one place to swap implementations.

Keep persistence yours. Taxonomy libs typically model terms and relations in memory. Your migrations, pivot tables, and ordering columns stay in your app. The common pattern:

  • Store terms in a terms table plus a self-referencing parent_id (or a closure table if depth matters).
  • Hydrate package objects only at the boundary — one query to load the flat set, then build the tree in PHP.
  • For model attributes, a custom Eloquent cast is the cleanest integration: AsTaxonomy::class on a JSON column, so $model->tags is a package object and $model->tags = [...] serialises back.

Build trees from a cached flat list. If the library offers hierarchy helpers, feed them a single ->get() result rather than walking relations recursively. Cache the flat set (Cache::remember('terms.flat', ...)) and invalidate on write — N+1 recursion is the classic failure mode here.

Contract-test your adapter. Port the package's own tests into your suite as behaviour documentation, then write your own tests against the adapter interface:

it('returns direct children in insertion order', function () {
    $tax = app(TaxonomyRepository::class);
    // arrange via your adapter, not vendor classes
});

If you later fork or replace the package, those tests are the only ones that need to keep passing.

Prefer composition over inheritance. Extending vendor classes couples you to private internals and makes upstream merges painful. If you need behaviour the lib lacks, implement it in your adapter on top of the public API.

Gotchas and Tips

  • Treat this as unvetted code. Zero stars, zero dependents, score 0.2 — that is not a reason to reject it, but it is a reason to read every line before production and to vendor or fork it into your org rather than depending on the upstream tag surviving. Pin the exact version and commit composer.lock.
  • Expect no Laravel auto-discovery. Verify composer.json for extra.laravel — most likely absent, so plan on manual binding.
  • Check the autoload standard. Older tiny libs sometimes still use PSR-0 or a files autoload with global functions. Grep for function outside classes; global helper functions collide silently.
  • PHP version drift. If the constraint targets 7.x, run your suite on 8.2+ and watch for dynamic property deprecations and missing return types. A composer require that resolves is not the same as clean on modern PHP.
  • Silent empty returns. Taxonomy code frequently returns an empty collection rather than throwing on an unknown term or slug collision. Don't assume exceptions — assert explicitly on the "missing" and "duplicate" paths in your adapter tests.
  • Unicode and case-folding. Slug generation, accent stripping, and locale-aware sorting are where these libraries break. Test with non-ASCII, mixed case, and duplicate-after-normalisation inputs on day one, not month three.
  • Ordering is often insertion-order or undefined. If user-visible ordering matters, own it in your own position column; don't rely on the lib's iteration order.
  • Debugging without internals: there's no config file, no logging, no facade. The practical move is a Composer path repository pointing at a local clone, so you can add dump()/xdebug inside src/ and still commit cleanly. Then switch back to the tagged version once the behaviour is understood.
  • Extension points are thin. In a library this size, assume there are no events, no strategy interfaces, and few protected methods. Your adapter is the extension point — keep its interface small so replacing the package with a maintained alternative (or 200 lines of your own tree code) is a single-file change.
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