Will G Will G - 2 months ago 22
PHP Question

Laravel Custom Route Model Binding

I have the following setup:

routes.php

Route::get('{page?}', [
'uses'=>'PageController@getPage',
'as'=>'page'
])->where('page', '(.*)?');


RouteServiceProvider.php

$router->bind('page', function($value, $route)
{
if($value == "/"){ $value = "home"; };
$explodedPage = explode("/",$value);
$page = Page::findBySlug(last($explodedPage));
if(!isset($page)){
\App::abort(404);
}
$ancestors = $page->ancestorsAndSelf()->get();
$sections=array();
foreach($ancestors as $ancestor)
{
$sections[]=$ancestor->slug;
}
if(implode("/",$sections)==$value){
return $page;
}else{
return $page;
//Else Redirect
}
});


Page.php

use Baum\Node;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use URL;
use Venturecraft\Revisionable\RevisionableTrait;
use Illuminate\Database\Eloquent\SoftDeletes;
use Cviebrock\EloquentSluggable\SluggableInterface;
use Cviebrock\EloquentSluggable\SluggableTrait;

class Page extends Node implements SluggableInterface
{

use RevisionableTrait, SoftDeletes, SluggableTrait;

protected $sluggable = array(
'build_from' => 'title',
'save_to' => 'slug',
);

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['title', 'description', 'content', 'owner_id', 'system', 'status'];

/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = ['parent_id','lft','rgt','depth'];

/**
* The attributes excluded from revision
*
* @var array
*/
protected $dontKeepRevisionOf = ['updater_id','parent_id','lft','rgt','depth'];

}


URLS look like such:

localhost/ (uses pre-defined slug)
localhost/page-slug
localhost/parent-slug/page-slug
localhost/parent-parent-slug/parent-slug/page-slug
Etc...


Retrieving pages works fine; but my question is in regards to generating the URL

{{URL::route('page',$page)}}


Simply Generates,
localhost/page-id

I know I can do:

{{URL::route('page',['page'=>$page->generateURLString()])}}


But I would much rather do this cleaner if possible. Does anyone have any recommendations?

Answer

As you say, you can do {{URL::route('page',['page'=>$page->generateURLString()])}} because route('page',$page) will return the patter name.

Then, my advice is, as you need some cleaner, to create a custom function extending the Route class or just declare it as a conventional function:

public function page($bind){
    return route('page', ['page' => $bind]);
}

Then just do:

{{ page($page->generateURLString()) }}