## Getting Started
### Minimal Setup
1. **Install the package**:
```bash
composer require myerscode/laravel-taxonomies
Publish the migration and config:
php artisan vendor:publish --provider="Myerscode\Taxonomies\TaxonomiesServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Myerscode\Taxonomies\TaxonomiesServiceProvider" --tag="config"
Run migrations:
php artisan migrate
Define a taxonomy (e.g., ProductCategory):
use Myerscode\Taxonomies\Taxonomy;
Taxonomy::create([
'name' => 'product_categories',
'singular_name' => 'Product Category',
'plural_name' => 'Product Categories',
'slug' => 'product-category',
'description' => 'Categories for products',
]);
Create terms (e.g., "Electronics", "Clothing"):
$taxonomy = Taxonomy::findBySlug('product-category');
$taxonomy->terms()->create(['name' => 'Electronics']);
$taxonomy->terms()->create(['name' => 'Clothing']);
Attach terms to a model (e.g., Product):
use Myerscode\Taxonomies\HasTaxonomies;
class Product extends Model
{
use HasTaxonomies;
public $taxonomies = ['product_categories'];
}
$product = new Product();
$product->taxonomies()->attach('Electronics'); // Attach by term name
// OR
$product->taxonomies()->attach($termId); // Attach by term ID
blog_tags).Post models via HasTaxonomies.$laravelPosts = Post::whereHasTaxonomy('blog_tags', 'Laravel')->get();
Taxonomy Management
use Myerscode\Taxonomies\Facades\Taxonomy;
$taxonomy = Taxonomy::create([...]);
$taxonomy = Taxonomy::findBySlug('product-category');
$taxonomy->update(['description' => 'Updated']);
$taxonomy->delete();
lang files:
// lang/en/taxonomies.php
return [
'product_categories' => [
'name' => 'Product Categories',
'terms' => [
'electronics' => 'Electronics',
],
],
];
Model Integration
$products = Product::withTaxonomies()->get();
// In Product model
public function electronicsProducts()
{
return $this->whereHasTaxonomy('product_categories', 'Electronics')->get();
}
priority) on the taxonomy_term_model table:
$product->taxonomies()->attach($termId, ['priority' => 1]);
Querying
// Models with ANY term in taxonomy
$products = Product::whereHasTaxonomy('product_categories')->get();
// Models with SPECIFIC term
$electronics = Product::whereHasTaxonomy('product_categories', 'Electronics')->get();
// Models with ALL specified terms (intersection)
$highPriority = Product::whereHasAllTaxonomies([
'product_categories' => ['Electronics', 'Accessories'],
])->get();
// In Product model
public function scopeElectronics($query)
{
return $query->whereHasTaxonomy('product_categories', 'Electronics');
}
Admin Interfaces
myerscode/laravel-nova-taxonomies package for a Nova resource.MariaDB Compatibility
JSON columns for pivot data if you encounter serialization issues. Stick to relational pivots for complex data.Term Slugs vs. IDs
// Unreliable (locale/name-dependent)
$product->taxonomies()->attach('electronics');
// Reliable (ID-based)
$term = Term::where('taxonomy_slug', 'product-category')->where('slug', 'electronics')->first();
$product->taxonomies()->attach($term->id);
Caching Taxonomies
Taxonomy and Term models:
Taxonomy::addGlobalScope(new CacheScope());
CacheScope to cache queries for 5 minutes:
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Facades\Cache;
class CacheScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
return Cache::remember("taxonomy_{$model->getKey()}", now()->addMinutes(5), function () use ($builder) {
return $builder->get();
});
}
}
Deleting Taxonomies
forceDelete() to cascade:
$taxonomy->forceDelete(); // Deletes terms and pivots
DB::table('taxonomy_term_model')->where('taxonomy_term_id', $termId)->delete();
Localization Quirks
en). Ensure your app.php config has a valid fallback locale.spatie/laravel-localization for multi-language slugs.Query Logs
Enable Laravel’s query logging to debug complex whereHasTaxonomy queries:
DB::enableQueryLog();
$products = Product::whereHasTaxonomy('product_categories', 'Electronics')->get();
dd(DB::getQueryLog());
Raw SQL For debugging, use raw SQL to verify relationships:
$sql = "SELECT * FROM products
INNER JOIN taxonomy_term_model ON products.id = taxonomy_term_model.model_id
INNER JOIN taxonomy_terms ON taxonomy_term_model.taxonomy_term_id = taxonomy_terms.id
WHERE taxonomy_terms.slug = 'electronics' AND taxonomy_terms.taxonomy_slug = 'product-category'";
$products = DB::select($sql);
Pivot Data Issues
If pivot data (e.g., priority) isn’t saving, check:
taxonomy_term_model table has the correct columns.attach method with an array:
$product->taxonomies()->attach($termId, ['priority' => 1]);
Custom Taxonomy Models
Extend the base Taxonomy and Term models:
class CustomTaxonomy extends \Myerscode\Taxonomies\Models\Taxonomy
{
protected $casts = [
'is_active' => 'boolean',
];
}
Bind the custom model in config/taxonomies.php:
'models' => [
'taxonomy' => \App\Models\CustomTaxonomy::class,
],
Events Listen for taxonomy/term events:
use Myerscode\Taxonomies\Events\TermCreated;
TermCreated::listen(function ($term) {
// Send notification or log term creation
});
API Resources Create custom API resources for taxonomies/terms:
namespace App\Http\Resources;
use Illuminate
How can I help you explore Laravel packages today?