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.
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.
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.composer require mibo/taxonomy --prefer-dist
composer show mibo/taxonomy # confirm the resolved version and PHP constraint
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.
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:
terms table plus a self-referencing parent_id (or a closure table if depth matters).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.
composer.lock.composer.json for extra.laravel — most likely absent, so plan on manual binding.files autoload with global functions. Grep for function outside classes; global helper functions collide silently.composer require that resolves is not the same as clean on modern PHP.position column; don't rely on the lib's iteration order.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.How can I help you explore Laravel packages today?