Laravel 自定义路由模型绑定
Laravel Custom Route Model Binding
我有以下设置:
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 看起来像这样:
localhost/ (uses pre-defined slug)
localhost/page-slug
localhost/parent-slug/page-slug
localhost/parent-parent-slug/parent-slug/page-slug
Etc...
检索页面工作正常;但我的问题是关于生成 URL
{{URL::route('page',$page)}}
简单生成,
localhost/page-id
我知道我能做到:
{{URL::route('page',['page'=>$page->generateURLString()])}}
但如果可能的话,我更愿意做这个清洁工。有人有什么建议吗?
如您所说,您可以{{URL::route('page',['page'=>$page->generateURLString()])}}
因为route('page',$page)
将return模式名称。
然后,我的建议是,因为你需要一些更清洁的东西,所以创建一个自定义函数来扩展路由 class 或者只是将其声明为常规函数:
public function page($bind){
return route('page', ['page' => $bind]);
}
然后就这样做:
{{ page($page->generateURLString()) }}
从版本 5 开始,您现在可以在 Model
(通过 UrlRoutable
)上拥有一个 getRouteKey()
,您可以将其用于 return 您的自定义路由键。
类似于:
class Page extends Node implements SluggableInterface
{
//......
public function getRouteKey() {
return $this->generateURLString();
}
}
让{{ route('page', $page) }}
如你所愿。
我有以下设置:
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 看起来像这样:
localhost/ (uses pre-defined slug)
localhost/page-slug
localhost/parent-slug/page-slug
localhost/parent-parent-slug/parent-slug/page-slug
Etc...
检索页面工作正常;但我的问题是关于生成 URL
{{URL::route('page',$page)}}
简单生成, localhost/page-id
我知道我能做到:
{{URL::route('page',['page'=>$page->generateURLString()])}}
但如果可能的话,我更愿意做这个清洁工。有人有什么建议吗?
如您所说,您可以{{URL::route('page',['page'=>$page->generateURLString()])}}
因为route('page',$page)
将return模式名称。
然后,我的建议是,因为你需要一些更清洁的东西,所以创建一个自定义函数来扩展路由 class 或者只是将其声明为常规函数:
public function page($bind){
return route('page', ['page' => $bind]);
}
然后就这样做:
{{ page($page->generateURLString()) }}
从版本 5 开始,您现在可以在 Model
(通过 UrlRoutable
)上拥有一个 getRouteKey()
,您可以将其用于 return 您的自定义路由键。
类似于:
class Page extends Node implements SluggableInterface
{
//......
public function getRouteKey() {
return $this->generateURLString();
}
}
让{{ route('page', $page) }}
如你所愿。