Don't understand how to make with nested set
schel4ok opened this issue · 6 comments
Summary of issue
Don't understand how to use breadcrumbs with nestedset
The complete error message, including file & line numbers
When I go to route links.index
I get this error
Missing argument 1 for App\Http\Controllers\FileController::getIndex()
When I go to route links.cat
page is rendered, but breadcrumbs are not showing
When I go to route links.item
I get this error
ErrorException in RouteServiceProvider.php line 44: Object of class Illuminate\Routing\Route could not be converted to string
Software versions
Laravel Breadcrumbs: 3.0.1
Laravel: 5.1.43
PHP: 5.5.28
routes.php
Route::get('/', ['as' => 'home', 'uses' => 'HomeController@index']);
Route::get('about-us', ['as' => 'about', 'uses' => 'PageController@o_kompanii']);
Route::get('sitemap', ['as' => 'sitemap', 'uses' => 'CategoryController@sitemap']);
Route::get('contacts', ['as' => 'contacts', 'uses' => 'PageController@contacts']);
Route::get('news', ['as' => 'news.index', 'uses' => 'NewsController@getIndex']);
Route::get('news/{newsitem}', ['as' => 'news.item', 'uses' => 'NewsController@getItem']);
Route::get('links', ['as' => 'links.index', 'uses' => 'FileController@getIndex']);
Route::get('links/{linkscat}', ['as' => 'links.cat', 'uses' => 'FileController@getCategory']);
Route::get('links/{cat}/{linksitem}', ['as' => 'links.item', 'uses' => 'FileController@getItem']);
Category model is nestedset.
Home (instance of Category model level 0)
-News (instance of Category model level 1)
--NewsItem1 (instance of News model)
--NewsItem2
--NewsItem3
...
-Links (instance of Category model level 1)
--LinkItem1 (instance of Link model)
--LinkItem2
--LinkItem3
...
-Catalog (instance of Category model level 1)
--Cat1 (instance of Category model level 2)
--Product1 (instance of Product model)
--Product2
--Product3
...
--Cat2 (instance of Category model level 2)
---Product1 (instance of Product model)
---Product2
---Product3
...
---Cat3 (instance of Category model level 3)
----Product1 (instance of Product model)
----Product2
----Product3
...
----Cat3 (instance of Category model level 4)
-----Product1 (instance of Product model)
-----Product2
-----Product3
...
breadcrumbs.php
use App\News;
// Home
Breadcrumbs::register('home', function($breadcrumbs)
{
$breadcrumbs->push('Главная', route('home'));
});
// Home > About
Breadcrumbs::register('about', function($breadcrumbs)
{
$breadcrumbs->parent('home');
$breadcrumbs->push('О компании', route('about'));
});
// Home > News
Breadcrumbs::register('news.index', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Новости', route('news.index'));
});
// Home > News > Item
Breadcrumbs::register('news.item', function($breadcrumbs, $item) {
$breadcrumbs->parent('news.index');
$breadcrumbs->push($item->title, route('news.item'));
});
// Home > Links
Breadcrumbs::register('links.index', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Ссылки', route('links.index'));
});
// Home > Links > Cat > Item
Breadcrumbs::register('links.item', function($breadcrumbs, $cat, $item) {
$breadcrumbs->parent('links.index');
foreach ($category->ancestors as $ancestor) {
$breadcrumbs->push($ancestor->title, route('links.cat'));
}
$breadcrumbs->push($item->title, route('links.item'));
});
HomeController.php
here I just get home category, which has sef=bez-kategorii
public function index()
{
$category = Category::where('sef', '=', 'bez-kategorii')->first();
return view('home')->withCategory($category);
}
FileController.php
public function getIndex($category)
{
$category = Category::where('type', '=', 'link')->first();
$categories = $category->descendants()->orderBy('title', 'asc')->paginate(9);
return view('links.index')->withCategory($category)
->withCategories($categories);
}
public function getCategory($category)
{
$items = Link::where('category_id', $category->id)->paginate(20);
$previous = $category->getPrevSibling();
$next = $category->getNextSibling();
return view('links.cat')->withCategory($category)
->withItems($items)
->withPrevious($previous)
->withNext($next);
}
public function getItem($category, $item)
{
$previous = Link::where('id', '<', $item->id)->orderBy('id', 'desc')->first();
$next = Link::where('id', '>', $item->id)->orderBy('id', 'asc')->first();
return view('links.item')->withCategory($category)
->withItem($item)
->withPrevious($previous)
->withNext($next);
}
RouteServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Routing\Router;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Route;
use App\News;
use App\Link;
use App\Category;
class RouteServiceProvider extends ServiceProvider
{
public function boot(Router $router)
{
parent::boot($router);
Route::bind('newsitem', function($item) {
return News::whereSef($item)->firstOrFail();
});
Route::bind('links', function($cat) {
return Category::whereSef($cat)->firstOrFail();
});
Route::bind('linkscat', function($cat) {
return Category::whereSef($cat)->firstOrFail();
});
Route::bind('linksitem', function($cat, $item) {
return Link::whereUrl('links/'.$cat.'/'.$item)->firstOrFail();
});
}
When I go to route links.index I get this error
Missing argument 1 for App\Http\Controllers\FileController::getIndex()
The action expects a parameter, but the route has none.
When I go to route links.cat page is rendered, but breadcrumbs are not showing
There is no breadcrumb with that name.
When I go to route links.item I get this error
ErrorException in RouteServiceProvider.php line 44: Object of class Illuminate\Routing\Route could not be converted to string
I'm not sure exactly but I suspect the binding for linksitem
receives the router as the second parameter not a string.
ok I did simple with links.index
and links.cat
routes.php
Route::get('links', ['as' => 'links.index', 'uses' => 'FileController@getIndex']);
Route::get('links/{linkscat}', ['as' => 'links.cat', 'uses' => 'FileController@getCategory']);
Route::get('links/{linkscat}/{linksitem}', ['as' => 'links.item', 'uses' => 'FileController@getItem']);
breadcrumbs.php
// Home > Links
Breadcrumbs::register('links.index', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Ссылки', route('links.index'));
});
// Home > Links > Cat
Breadcrumbs::register('links.cat', function($breadcrumbs, $category) {
$breadcrumbs->parent('links.index');
$breadcrumbs->push($category->title, route('links.cat'));
});
// Home > Links > Cat > Item
Breadcrumbs::register('links.item', function($breadcrumbs, $category, $item) {
$breadcrumbs->parent('links.cat', $category);
$breadcrumbs->push($item->title, route('links.item'));
});
but I still cannot understand ho to do breadcrumbs for the item.
Because I see that links.item
needs to receive 2 objects $category
and $item
Breadcrumbs::register('links.item', function($breadcrumbs, $category, $item) {
$breadcrumbs->parent('links.cat', $category);
$breadcrumbs->push($item->title, route('links.item'));
});
RouteServiceProvider.php
Route::bind('links', function($cat) {
return Category::whereSef($cat)->firstOrFail();
});
Route::bind('linkscat', function($cat) {
return Category::whereSef($cat)->firstOrFail();
});
Route::bind('linksitem', function($item) {
return Link::whereSef($item)->firstOrFail();
});
now all routes are working well, but in route links.item
breadcrumbs are not rendered good.
Home / Links / Category / Item
link to Category is showing like that http://site.dev/links/{linkscat}
Trying to understand what happens I was reading manual more and more, but I didn't find detailed description of additional parameters in breadcrumbs.
Though somehow I found solution of my question.
// Home > Links > Cat
Breadcrumbs::register('links.cat', function($breadcrumbs, $category) {
$breadcrumbs->parent('links.index');
$breadcrumbs->push($category->title, route('links.cat', $category->sef)); // here I must put $category->sef as a second parameter of route
});
// Home > Links > Cat > Item
Breadcrumbs::register('links.item', function($breadcrumbs, $category, $item) {
$breadcrumbs->parent('links.cat', $category); // here $category === $category->sef
$breadcrumbs->push($item->title, route('links.item'));
});
But looking API reference for $breadcrumbs->parent($name)
There is nothing saying that you can put after the name second parameter, which will be URL and that parameter must be also mentioned in $breadcrumbs->push section of parent element.
But looking API reference for $breadcrumbs->parent($name)
There is nothing saying that you can put after the name second parameter
It's mentioned here in the API reference: http://laravel-breadcrumbs.davejamesmiller.com/en/latest/api.html#defining-breadcrumbs
$breadcrumbs->parent($name, $param1, ...)
And here in the tutorial: http://laravel-breadcrumbs.davejamesmiller.com/en/latest/defining.html#nested-categories
$breadcrumbs->parent('category', $category->parent);
But I'll try to make it clearer next time I update the documentation.
which will be URL and that parameter must be also mentioned in $breadcrumbs->push section of parent element
That's not quite right, the additional parameters can be whatever you want them to be, and you can use them however you want.
here I must put $category->sef as a second parameter of route
here $category === $category->sef
If you're saying the second one is a string, I wouldn't expect it to work - either both should be an object or both should be a string, because whatever parameters you pass to parent()
are passed into the closure unaltered. (I always use Eloquent objects.)
link to Category is showing like that http://site.dev/links/{linkscat}
That's because you're not passing any parameters to route()
:
$breadcrumbs->push($category->title, route('links.cat'));
Should be something like this:
$breadcrumbs->push($category->title, route('links.cat', $category->sef));
And for the item:
$breadcrumbs->push($item->title, route('links.item', [$category->sef, $item->sef]));
route()
itself is a standard Laravel function, documented here.
yes I saw $breadcrumbs->parent($name, $param1, ...)
and $breadcrumbs->parent('category', $category->parent);
That is why I started to play and check it with different variables.
But there is no clear description what we can pass in additional parameters for $breadcrumbs->parent
Eventually I did my catalod breadcrumbs like this
// Home > Furnitura
Breadcrumbs::register('furnitura.index', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Фурнитура', route('furnitura.index'));
});
// Home > Furnitura > Cat
Breadcrumbs::register('furnitura.cat', function($breadcrumbs, $category) {
$breadcrumbs->parent('furnitura.index');
foreach ($category->getAncestors() as $ancestor) {
if( $ancestor->level > 1 )
$breadcrumbs->push($ancestor->title, route('furnitura.cat', $ancestor->path));
}
$breadcrumbs->push($category->title, route('furnitura.cat', $category->path));
});
// Home > Furnitura > Cat > Item
Breadcrumbs::register('furnitura.item', function($breadcrumbs, $category, $item) {
$breadcrumbs->parent('furnitura.cat', $category); // $category = $category->path from links.cat
$breadcrumbs->push($item->title, route('furnitura.item'));
});
Because if I do like described in your manual then I got home
and `furnitura.index' twice in breadcrumbs. Because they are also instances of nestedset. Home level is 0, catalog index level is 1.