PHPackages                             mrnewport/laravel-nestedterms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. mrnewport/laravel-nestedterms

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

mrnewport/laravel-nestedterms
=============================

A super dynamic &amp; extensible Terms + Tags system for Laravel, featuring infinite nesting, dynamic casting, hierarchical slugs, etc.

v1.0.0(1y ago)11MITPHPPHP &gt;=8.1

Since Jan 25Pushed 1y ago1 watchersCompare

[ Source](https://github.com/MrNewport/laravel-nestedterms)[ Packagist](https://packagist.org/packages/mrnewport/laravel-nestedterms)[ RSS](/packages/mrnewport-laravel-nestedterms/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (2)Used By (0)

Laravel Nested Terms &amp; Tags
===============================

[](#laravel-nested-terms--tags)

A **dynamic &amp; extensible** system for **nested** Terms and **dynamic-cast** Tags in Laravel. This package includes:

- **Infinite nesting** of Tags via a self-referencing `parent_id`.
- **Hierarchical slugs** (e.g. `specifications.bedrooms.5`).
- **Dynamic casting** of a Tag’s `value` based on a `type` field (`integer`, `boolean`, `float`, `array`, etc.).
- **Polymorphic pivot** for attaching Tags to any Eloquent model.
- **Config-driven architecture** for easy customization.
- **Comprehensive tests** and a production-ready codebase.

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
    - [Creating Terms](#creating-terms)
    - [Creating Tags](#creating-tags)
    - [Infinite Nesting](#infinite-nesting)
    - [Tag Values &amp; Casting](#tag-values--casting)
    - [Attaching Tags to Models](#attaching-tags-to-models)
    - [Filtering by Term](#filtering-by-term)
- [Customization](#customization)
    - [Custom Table Names](#custom-table-names)
    - [Custom Models](#custom-models)
- [Testing](#testing)
- [Contributing](#contributing)
- [License](#license)

---

Requirements
------------

[](#requirements)

- **PHP** `^8.1` or higher
- **Laravel** `^11.0` (or equivalent)
- **Composer** for dependency management

---

Installation
------------

[](#installation)

1. **Install** via Composer:

    ```
    composer require mrnewport/laravel-nestedterms
    ```
2. **Publish** the config (optional):

    ```
    php artisan vendor:publish --provider="MrNewport\LaravelNestedTerms\Providers\NestedTermsServiceProvider" --tag=nestedterms-config
    ```
3. **Migrate**:

    ```
    php artisan migrate
    ```

---

Configuration
-------------

[](#configuration)

**`config/nestedterms.php`** (published if desired):

```
return [
    'terms_table'     => 'terms',
    'tags_table'      => 'tags',
    'model_tag_table' => 'model_tag',

    'term_model' => \MrNewport\LaravelNestedTerms\Models\Term::class,
    'tag_model'  => \MrNewport\LaravelNestedTerms\Models\Tag::class,

    'allowed_cast_types' => [
        'integer','float','double','boolean','string','array','json','object',
    ],

    'custom_type_map' => [
        'number' => 'integer',
    ],
];
```

- **Table Names**: `terms_table`, `tags_table`, `model_tag_table`
- **Model Classes**: `term_model` &amp; `tag_model`
- **Casting**: `'allowed_cast_types'` &amp; `'custom_type_map'`

---

Usage
-----

[](#usage)

### Creating Terms

[](#creating-terms)

```
use MrNewport\LaravelNestedTerms\Models\Term;

$term = Term::create([
    'name' => 'Specifications',
    'slug' => 'specifications', // or omit to auto-generate
]);
```

### Creating Tags

[](#creating-tags)

```
use MrNewport\LaravelNestedTerms\Models\Tag;

$bedrooms = Tag::create([
    'term_id' => $term->id,
    'name'    => 'Bedrooms',
]);
```

### Infinite Nesting

[](#infinite-nesting)

Tags can nest via `parent_id`:

```
$parent = Tag::create([
  'term_id' => $term->id,
  'name'    => 'SubItem',
]);

$child = Tag::create([
  'term_id'   => $term->id,
  'parent_id' => $parent->id,
  'name'      => 'Child Tag',
]);

// slug => "specifications.subitem.child-tag"
$descendants = $parent->allDescendants(); // includes "Child Tag"
```

### Tag Values &amp; Casting

[](#tag-values--casting)

```
$tag = Tag::create([
    'term_id' => $term->id,
    'name'    => 'NumberOfRooms',
    'type'    => 'integer',
    'value'   => '5',
]);

// Eloquent interprets $tag->value as integer
echo $tag->value;       // 5
```

### Attaching Tags to Models

[](#attaching-tags-to-models)

Any model can “have tags”:

```
use MrNewport\LaravelNestedTerms\Traits\HasTags;

class Article extends Model
{
    use HasTags;
}
```

```
$article->attachTags($tagIdOrSlug);
$article->detachTags($tagInstance);
$article->syncTags([...]);
$article->hasTag('bedrooms');
```

### Filtering by Term

[](#filtering-by-term)

```
$article->tagsByTerm('specifications')->get();
// returns tags whose term->slug == "specifications"
```

---

Customization
-------------

[](#customization)

### Custom Table Names

[](#custom-table-names)

In **`nestedterms.php`**:

```
'terms_table' => 'cms_terms',
'tags_table'  => 'cms_tags',
```

Then re-run `php artisan migrate`. The included migrations reference these config values.

### Custom Models

[](#custom-models)

Define your own **Term** or **Tag** classes:

```
namespace App\Models;

use MrNewport\LaravelNestedTerms\Models\Tag as BaseTag;

class CustomTag extends BaseTag
{
    protected $fillable = [
        'term_id','parent_id','slug','type','value','name','description','meta','is_active',
        'icon','color'
    ];

    public function generateHierarchySlug(): string
    {
        $slug = parent::generateHierarchySlug();
        return $slug.'-extended';
    }
}
```

Then update:

```
'tag_model' => \App\Models\CustomTag::class,
```

---

Testing
-------

[](#testing)

A **Pest-based** suite covers Terms, Tags, and the `HasTags` trait. Run:

```
composer test
```

- **TermTest**: verifying creation, slug generation, etc.
- **TagTest**: infinite nesting, dynamic casting, hierarchical slugs.
- **HasTagsTraitTest**: attaching/detaching tags on a test model.

---

Contributing
------------

[](#contributing)

1. **Fork** this repo.
2. **Create** a feature/fix branch.
3. **Add** tests covering changes.
4. **Submit** a Pull Request.

---

License
-------

[](#license)

Licensed under the [MIT license](LICENSE).

Enjoy building infinite nesting, dynamic-cast tags, and configurable terms in your Laravel projects!

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance42

Moderate activity, may be stable

Popularity3

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

470d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/19dc283a8ecb45d1efbc444dc510eb63c8aab21427be09f3c1aefd507a5ab40c?d=identicon)[mrnewport](/maintainers/mrnewport)

---

Top Contributors

[![MrNewport](https://avatars.githubusercontent.com/u/48736345?v=4)](https://github.com/MrNewport "MrNewport (1 commits)")

---

Tags

sluglaravelnestedtagscastingtaxonomyterms

###  Code Quality

TestsPest

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/mrnewport-laravel-nestedterms/health.svg)

```
[![Health](https://phpackages.com/badges/mrnewport-laravel-nestedterms/health.svg)](https://phpackages.com/packages/mrnewport-laravel-nestedterms)
```

###  Alternatives

[aliziodev/laravel-taxonomy

Laravel Taxonomy is a flexible and powerful package for managing taxonomies, categories, tags, and hierarchical structures in Laravel applications. Features nested-set support for optimal query performance on hierarchical data structures.

23318.4k](/packages/aliziodev-laravel-taxonomy)[livewire/volt

An elegantly crafted functional API for Laravel Livewire.

4195.3M84](/packages/livewire-volt)[torann/laravel-meta-tags

A package to manage Header Meta Tags

65273.3k4](/packages/torann-laravel-meta-tags)[netgen/tagsbundle

Netgen Tags Bundle is an Ibexa DXP bundle for taxonomy management and easier classification of content, providing more functionality for tagging content than ibexa\_keyword field type included in Ibexa core.

49456.8k21](/packages/netgen-tagsbundle)[forxer/laravel-gravatar

A library providing easy gravatar integration in a Laravel project.

4235.6k](/packages/forxer-laravel-gravatar)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
