dcblogdev/laravel-nestable is a Laravel package for laravel 5 nested categories library.
It currently has 6 GitHub stars and 192 downloads on Packagist (latest version v1.0.5).
Install it with composer require dcblogdev/laravel-nestable.
Discover more Laravel packages by dcblogdev
or browse all Laravel packages to compare alternatives.
Last updated
Forked from https://github.com/atayahmet/laravel-nestable due to being archived and needing the package to support Laravel 6. Thanks to Ahmet for this package.
Laravel Nestable to work with recursive logic. Category level there is no limit but this may vary depending on your server performance. Allow the 100000 recursion process execution since PHP 5.2. More info
composer require dcblogdev/laravel-nestable
Then
Add to app.php the Service Provider file.
Nestable\NestableServiceProvider::class
Then add app.php Facade file again.
'Nestable' => Nestable\Facades\NestableService::class
Finally run the artisan command:
php artisan vendor:publish --provider="Nestable\NestableServiceProvider"
That's it!
Suppose that the data came from a database as follows.
Category table:
id | parent_id | name | slug ---| --------- | -------------- | ------- 1 | 0 | T-shirts | t-shirts 2 | 1 | Red T-shirts | red-t-shirts 3 | 1 | Black T-shirts | black-t-shirts 4 | 0 | Sweaters | sweaters 5 | 4 | Red Sweaters | red-sweaters 6 | 4 | Blue Sweaters | blue-sweaters
Example 1:
<?php
use Nestable\NestableTrait;
class Category extends \Eloquent {
use NestableTrait;
protected $parent = 'parent_id';
}
Note: $parent variable refers to the parent category (Default parent_id)
<?php
$categories = Category::nested()->get();
Query result:
<?php
array:6 [
0 => array:5 [
"id" => 1
"name" => "T-shirts"
"slug" => "t-shirts"
"child" => array:2 [
0 => array:5 [
"id" => 2
"name" => "Red T-shirts"
"slug" => "red-t-shirts"
"child" => []
"parent_id" => 1
]
1 => array:5 [
"id" => 3
"name" => "Black T-shirts"
"slug" => "black-t-shirts"
"child" => []
"parent_id" => 1
]
]
"parent_id" => 0
]
1 => array:5 [
"id" => 4
"name" => "Sweaters"
"slug" => "sweaters"
"child" => array:2 [
0 => array:5 [
"id" => 5
"name" => "Red Sweaters"
"slug" => "red-sweaters"
"child" => []
"parent_id" => 4
]
1 => array:5 [
"id" => 6
"name" => "Blue Sweaters"
"slug" => "blue-sweaters"
"child" => []
"parent_id" => 4
]
]
"parent_id" => 0
]
]
For html tree output:
<?php
Category::renderAsHtml();
Output:
<ul>
<li><a href="">T-shirts
<ul>
<li><a href="red-t-shirt">Red T-shirt</a></li>
<li><a href="black-t-shirts">Black T-shirts</a></li>
</ul>
</li>
<li><a href="">Sweaters
<ul>
<li><a href="red-sweaters">Red Sweaters</a></li>
<li><a href="blue-sweaters">Blue Sweaters</a></li>
</ul>
</li>
</ul>
For dropdown output:
<?php
Category::attr(['name' => 'categories'])
->selected(2)
->renderAsDropdown();
Output:
<select name="categories">
<option value="1">T-shirts</option>
<option value="2" selected="selected"> Red T-shirts</option>
<option value="3"> Black T-shirts</option>
<option value="4">Sweaters</option>
<option value="5"> Red Sweaters</option>
<option value="6"> Blue Sweaters</option>
</select>
Selected for multiple list box:
->selected([1,2,3])
name | Parameter |output
----------------------| --------- | -------
renderAsArray() | none | array
renderAsJson() | none | json
renderAsHtml() | none | html
renderAsDropdown() | none | dropdown
renderAsMultiple() | none | Listbox
name | paremeter| description
----------------------| -------- | --------------------------------
parent() | int | Get childs of the defined parent
name | paremeter| description
----------------------| -------- | --------------------------------
parent() | int | Get childs of the defined parent
name | paremeter | description
----------------------| ----------------- | --------------------------------
parent() | int | Get childs of the defined parent
active() | callback/array/int| Selected item(s) for html output
ulAttr() | array/string | Add attribute to parent ul element
firstUlAttr() | array/string | Add attribute to parent ul element
route() | callback/array | Generate url by route name
customUrl() | string | Generate custom url
name | paremeter | description
----------------------| ----------------- | --------------------------------
parent() | int | Get childs of the defined parent
selected()| callback/array/int| Selected item(s) for dropdown
attr() | array | Dropdown/listbox attributes
Get childs of the defined parent.
<?php
Category::parent(2)->renderAsArray();
Note: This methods usable all with output methods
Selected item(s) for html output.
Example 1:
<?php
Menu::active('t-shirts')->renderAsHtml();
Example 2:
<?php
Menu::active('t-shirts', 'black-t-shirts')->renderAsHtml();
Example 3:
<?php
Menu::active(['t-shirts', 'black-t-shirts'])->renderAsHtml();
Example 4:
<?php
Menu::active(function($li, $href, $label) {
$li->addAttr('class', 'active')->addAttr('data-label', $label);
})->renderAsHtml();
Example 5:
<?php
Menu::active(function($li, $href, $label) {
$li->addAttr(['class' => 'active', 'data-label' => $label]);
})->renderAsHtml();
Add attribute to first ul element
Example 1:
<?php
Menu::firstUlAttr('class', 'first-ul')->renderAsHtml();
Example 2:
<?php
Menu::firstUlAttr(['class' => 'first-ul'])->renderAsHtml();
Add attribute to parent ul element
Example 1:
<?php
Menu::ulAttr('class', 'nav-bar')->renderAsHtml();
Example 2:
<?php
Menu::ulAttr(['t-shirts' => 'black-t-shirts'])->renderAsHtml();
Example 3:
<?php
Menu::ulAttr(function($ul, $parent_id) {
if($parent_id == 10) {
$ul->ulAttr('class', 'nav-bar');
}
})->renderAsHtml();
Generate url by route name
Example 1:
<?php
Menu::route(['product' => 'slug'])->renderAsHtml();
Note: product refer to route name and slug refer to paremeter name.
<?php
Route::get('product/{slug}', 'ProductController@show');
Example 2:
<?php
Menu::route(function($href, $label, $parent) {
return \URL::to($href);
})->renderAsHtml();
Generate custom url with slug
Example 1:
<?php
Menu::customUrl('product/detail/{slug}')->renderAsHtml();
Example 1:
<?php
Menu::customUrl('product/{slug}/detail')->renderAsHtml();
Note: slug keyword belongs to html > href in config file.
Selected item(s) for dropdown.
Example 1:
<?php
Category::selected(1)->renderAsDropdown();
Example 2:
<?php
Category::selected(1,5)->renderAsMultiple();
Example 3:
<?php
Category::selected([1,3])->renderAsMultiple();
Example 4:
<?php
Category::selected(function($option, $value, $label) {
$option->addAttr('selected', 'true');
$option->addAttr(['data-item' => $label]);
})->renderAsMultiple();
Dropdown/listbox attributes.
<?php
Category::attr(['name' => 'categories', 'class' => 'red'])->renderAsDropdown();
The above examples were performed with default settings. Config variables in config/nestable.php file.
name | type | description
----------------------| ------- | --------------------------------
parent | string | Parent category column name
primary_key | string | Table primary key
generate_url | boolean | Generate the url for html output
childNode | string | Child node name
body | array | Array output (default)
html | array | Html output columns
dropdown | array | Dropdown/Listbox output
The body variable should be an array and absolutely customizable.
Example:
<?php
'body' => [
'id',
'category_name',
'category_slug'
]
Configuration for html output.
name | description
-------------| -----------------
label | Label column name
href | Url column name
Example:
<?php
'html' => [
'label' => 'name',
'href' => 'slug',
]
Configuration for dropdown/listbox output.
name | description
------- | -------------------
prefix | Label prefix
label | Label column name
value | Value column name
Example:
<?php
'dropdown' => [
'prefix' => '-',
'label' => 'name',
'value' => 'id'
]
Include the Nestable facade.
<?php
use Nestable;
$result = Nestable::make([
[
'id' => 1,
'parent_id' => 0,
'name' => 'T-shirts',
'slug' => 't-shirts'
],
[
'id' => 2,
'parent_id' => 1,
'name' => 'Red T-shirts',
'slug' => 'red-t-shirts'
],
[
'id' => 3,
'parent_id' => 1,
'name' => 'Black T-shirts',
'slug' => 'black-t-shirts'
]
// and more...
]);
For array output:
$result->renderAsArray();
It controls the structure of the data. They also made the rendering process with a second parameter control after they.
name | Parameters ------- | ----------- isValidForArray | boolean isValidForJson | boolean isValidForHtml | boolean isValidForDropdown| boolean isValidForMultiple | boolean
Example 1:
<?php
Menu::make($categories)->isValidForHtml();
// return true or false
Example 2:
<?php
Menu::make($categories)->isValidForHtml(true);
// return html string if data valid
<?php
Nestable::macro('helloWorld', function($nest, $categories) {
return $nest->make($categories)->active('sweater')->route(['tests' => 'slug'])->renderAsHtml();
});
Call the above macro:
<?php
$categories = [
[
'id' => 1,
'parent_id' => 0,
'name' => 'T-shirt',
'slug' => 'T-shirt'
],
[
'id' => 2,
'parent_id' => 0,
'name' => 'Sweater',
'slug' => 'sweater'
]
];
Nestable::helloWorld($categories);
<?php
nestable($data)->renderAsHtml();
<?php
nestable()->make($data)->renderAsHtml();
<?php
nestable()->macro('helloWorld', function() {
return 'Hello Laravel';
});
// run
nestable()->helloWorld();