Weave Code
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

Laravel Taxonomies Laravel Package

myerscode/laravel-taxonomies

View on GitHub
Deep Wiki
Context7
## 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
  1. 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',
    ]);
    
  2. Create terms (e.g., "Electronics", "Clothing"):

    $taxonomy = Taxonomy::findBySlug('product-category');
    $taxonomy->terms()->create(['name' => 'Electronics']);
    $taxonomy->terms()->create(['name' => 'Clothing']);
    
  3. 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
    

First Use Case: Tagging Blog Posts

  • Define a taxonomy (blog_tags).
  • Create terms like "Laravel", "PHP", "Tutorial".
  • Attach terms to Post models via HasTaxonomies.
  • Query posts by tag:
    $laravelPosts = Post::whereHasTaxonomy('blog_tags', 'Laravel')->get();
    

Implementation Patterns

Core Workflows

  1. Taxonomy Management

    • CRUD via facade:
      use Myerscode\Taxonomies\Facades\Taxonomy;
      
      $taxonomy = Taxonomy::create([...]);
      $taxonomy = Taxonomy::findBySlug('product-category');
      $taxonomy->update(['description' => 'Updated']);
      $taxonomy->delete();
      
    • Localization: Translate names via Laravel’s lang files:
      // lang/en/taxonomies.php
      return [
        'product_categories' => [
            'name' => 'Product Categories',
            'terms' => [
                'electronics' => 'Electronics',
            ],
        ],
      ];
      
  2. Model Integration

    • Eager loading taxonomies:
      $products = Product::withTaxonomies()->get();
      
    • Dynamic relationships:
      // In Product model
      public function electronicsProducts()
      {
          return $this->whereHasTaxonomy('product_categories', 'Electronics')->get();
      }
      
    • Pivot data: Store extra data (e.g., priority) on the taxonomy_term_model table:
      $product->taxonomies()->attach($termId, ['priority' => 1]);
      
  3. Querying

    • Find models by taxonomy/term:
      // 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();
      
    • Scope queries:
      // In Product model
      public function scopeElectronics($query)
      {
          return $query->whereHasTaxonomy('product_categories', 'Electronics');
      }
      
  4. Admin Interfaces

    • Laravel Nova: Use the myerscode/laravel-nova-taxonomies package for a Nova resource.
    • Custom views: Build a CRUD interface for taxonomies/terms using the facade or direct Eloquent calls.

Gotchas and Tips

Pitfalls

  1. MariaDB Compatibility

    • The package explicitly supports MariaDB, but avoid using JSON columns for pivot data if you encounter serialization issues. Stick to relational pivots for complex data.
    • Workaround: Use a separate pivot table for extra attributes if needed.
  2. Term Slugs vs. IDs

    • Attaching terms by name/slug is convenient but case-sensitive and locale-dependent. Prefer using term IDs for reliability in production:
      // 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);
      
  3. Caching Taxonomies

    • Taxonomies are not cached by default. For high-traffic sites, cache the Taxonomy and Term models:
      Taxonomy::addGlobalScope(new CacheScope());
      
      • Implement 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();
                });
            }
        }
        
  4. Deleting Taxonomies

    • Cascade deletion: By default, deleting a taxonomy does not delete terms or pivot records. Use forceDelete() to cascade:
      $taxonomy->forceDelete(); // Deletes terms and pivots
      
    • Orphaned pivots: Manually clean up pivots if needed:
      DB::table('taxonomy_term_model')->where('taxonomy_term_id', $termId)->delete();
      
  5. Localization Quirks

    • Fallback chain: If a term isn’t translated in the current locale, it falls back to the default (en). Ensure your app.php config has a valid fallback locale.
    • Dynamic slugs: Slugs are not automatically localized. Generate them manually or use a package like spatie/laravel-localization for multi-language slugs.

Debugging Tips

  1. Query Logs Enable Laravel’s query logging to debug complex whereHasTaxonomy queries:

    DB::enableQueryLog();
    $products = Product::whereHasTaxonomy('product_categories', 'Electronics')->get();
    dd(DB::getQueryLog());
    
  2. 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);
    
  3. Pivot Data Issues If pivot data (e.g., priority) isn’t saving, check:

    • The taxonomy_term_model table has the correct columns.
    • You’re using the attach method with an array:
      $product->taxonomies()->attach($termId, ['priority' => 1]);
      

Extension Points

  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,
    ],
    
  2. Events Listen for taxonomy/term events:

    use Myerscode\Taxonomies\Events\TermCreated;
    
    TermCreated::listen(function ($term) {
        // Send notification or log term creation
    });
    
  3. API Resources Create custom API resources for taxonomies/terms:

    namespace App\Http\Resources;
    
    use Illuminate
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle