webflorist / routetree
RouteTree:Laravel(≥v5.5)的高级路由管理
Requires
- laravel/framework: >=5.5
Requires (Dev)
- orchestra/testbench: >=3.5
README
此包包含用于创建和访问Laravel路由及其相关信息的特殊API。其主要概念是使用表达性语法(大部分模仿Laravel本身)创建一个分层多语言RouteTree。利用这个层次结构,RouteTree可以轻松创建:
- 任何类型的导航。
- 语言无关的链接。
- 语言切换菜单。
- 面包屑菜单。
- 网站地图菜单。
以下是完整的功能概述
- 自动路径生成:为所有配置的语言自动生成路由,将地区作为第一个路径段(例如,
en/company/team/contact
)。 - 自动生成表达性路由名称(例如,
en.company.team.contact.get
)。 - 自动继承各种路由设置(模仿Laravel的
Route::group()
)。 - Payload 功能,用于为您的路由设置任何自定义数据(例如,页面标题,元描述,
includeInMenu
)并在应用程序的任何位置检索它。 - 自动翻译通过各种数据源(例如,使用文件夹树中与分层RouteTree结构相对应的结构化语言文件)。这用于:
- 本地化路径段(例如,英文的
en/company/team/contact
和德语的de/firma/team/kontakt
)。 - 使用相应的Eloquent模型本地化路由键(用于参数或资源路由)。
- 本地化 Payload(页面标题和任何其他自定义信息)- 也适用于参数或资源路由,使用相应的Eloquent模型。
- 您还可以利用此结构通过包含的
trans_by_route()
助手函数使用页面内容。)
- 本地化路径段(例如,英文的
- 独特的语言无关路由ID(例如,
company.team.contact
)可用于应用程序中的各种目的。以下是用route_node()
助手函数的示例:- 当前语言的链接
route_node('company.team.contact')->getUrl()
. - 特定语言的链接
route_node('company.team.contact')->getUrl()->locale('de')
. - 访问分层父/兄弟/子节点
route_node('company.team')->getChildNodes()
- 使用以下方式访问页面标题
route_node('company.team')->getTitle()
(回退到路由名称的大写形式 - 例如Team
)。 - 访问任何其他类型的自定义信息(通过
Payload
)route_node('company.team')->payload->get('icon/description/keywords/author/layout/last_update/whatever')
.
- 当前语言的链接
- 自动地区设置:
- 从当前路由名称的第一个段开始(例如,
en.company.news.get
)。 - 从一个(自动保存的)会话值。
- 从一个客户端发送的
HTTP_ACCEPT_LANGUAGE
头。
- 从当前路由名称的第一个段开始(例如,
- 自动重定向:
- 从网站根目录
/
到特定语言的首页(例如,/en
)。 - 从省略地区路径的路径(例如,从
/company/team/contact
到en/company/team/contact
)。
- 从网站根目录
- XML-Sitemap
- 通过
artisan
命令生成静态文件。 - 注册一个提供动态网站地图的路由的选项。
- 自动排除
auth
路由和重定向。 - 手动排除路由和子路由。
- 解决所有可能的参数/资源路由键。
- 通过流畅设置器设置可选标签(lastmod,changefreq,priority),或通过访问Eloquent模型(对于参数/资源路由)。
- 通过
- 可缓存(与Laravel的路由缓存结合使用)。
- REST-API 用于检索路由列表或各种信息或特定路由的
Payload
。 (需要至少 Laravel 5.6!)
目录
- RouteTree:Laravel(≥v5.5)的高级路由管理
安装
- 通过 composer 需求包
php composer require webflorist/routetree
- 发布配置
php artisan vendor:publish --provider="Webflorist\RouteTree\RouteTreeServiceProvider"
- 在您的
routetree.php
配置文件中的locales
键下定义您想要在网站上使用的所有区域设置。
例如:'locales' => ['en','de']
。
(或者您可以将它设置为null
以强制单语言应用(使用配置app.locale
)。)
请注意,此包已配置为自动发现 Laravel。因此,包的 Service Provider Webflorist\RouteTree\RouteTreeServiceProvider
以及 RouteTree
别名将自动注册到 Laravel 中。
访问 RouteTree-service
访问 RouteTree 服务的方法有几种
- 通过辅助函数:
route_tree()
- 通过 Laravel 门面:
\RouteTree::
- 通过 Laravel 容器:
app('Webflorist\RouteTree\RouteTree')
或app()['Webflorist\RouteTree\RouteTree']
以下代码示例将使用门面 RouteTree::
。
定义 RouteTree
就像 Laravel 自身的路由一样,您可以在您的 routes/web.php
中定义 RouteTree。
为了更好地比较语法,以下示例将在可能的情况下对应于在 Laravel 的路由文档 中呈现的示例。它们还将假定配置了 2 种语言('en','de'
) - 如果没有其他说明。
基本路由
RouteTree::node('foo', function (RouteNode $node) { $node->get(function() { if (\App::getLocale() === 'de') { return 'Hallo Welt'; } return 'Hello World'; }); });
node()
方法创建一个名为(和 ID)foo
的 RouteNode,然后使用其第二个参数中的闭包进行设置。
RouteNode 本身类似于 Laravel 的路由组。它本身不会产生任何注册的路由,但它集中共享各种数据(例如路径、中间件、命名空间等)及其动作,并将它们继承给任何子节点。
$node->get()
调用使用 HTTP 请求方法 GET
添加一个名为 get
的 RouteAction,并使用闭包作为其回调。
RouteAction 将在每个配置的语言中生成一个 Laravel 路由。
上述代码将注册以下路由
- 名为
de.foo.get
且路径为de/foo
的路由 - 名为
en.foo.get
且路径为en/foo
的路由
与 Laravel 的语法一样,您也可以使用 Controller@method
表达式指定动作的回调
RouteTree::node('foo')->get('Controller@method');
在上面的示例中,RouteNode 的设置闭包被省略,而是直接将 get
调用链接到 node
调用。这是一种设置(返回 RouteNode 并允许链接各种流畅方法)的替代方法,从而实现了一行代码的可读性。一旦 RouteNode 变得更复杂并具有多个子节点,建议使用设置闭包。此外,请注意,动作创建方法(如 get
、post
、redirect
、view
等)返回 RouteAction 对象而不是 RouteNode。
以下示例将使用两种语法变体。
可用的 RouteActions
RouteNodes 提供公共方法来注册响应任何 HTTP 动词的 RouteActions
RouteTree::node('foo', function (RouteNode $node) { $node->get($callback); $node->post($callback); $node->put($callback); $node->patch($callback); $node->delete($callback); $node->options($callback); });
重定向动作
您还可以定义重定向节点,并通过其 ID 指定目标节点
RouteTree::node('here')->redirect('there'); RouteTree::node('there', function (RouteNode $node) { $node->get(function() { return 'You are now there'; }); });
默认情况下,$node->redirect()
返回 302 状态码。
您可以使用可选的第二个参数自定义状态码
$node->redirect('there', 301);
.
您还可以使用 $node->permanentRedirect()
返回 301 状态码。
视图动作
如果 RouteNode 应仅返回视图,可以使用 view
方法
RouteTree::node('welcome')->view('welcome');
您可以通过 view
方法的第二个参数向视图传递数据。
配置根节点
上面示例中使用的 RouteTree::node()
方法会自动创建以根节点为父节点的节点。您可以使用 root
方法来配置根节点本身
RouteTree::root()->view('welcome');
您不能为根节点指定名称。它的名称和 ID 总是空字符串(''
)。
添加子节点
有几种方法可以将节点作为另一个节点的子节点创建
- 在父节点的 setup-callback 中调用
$node->child($childName, $childCallback)
。 - 通过将父 RouteNode 的 ID 作为
node
方法的第三个参数指定:RouteTree::node($childName, $childCallback, $parentId);
- 使用
RouteTree::getRoute('parent')->child('child', $childCallback)
第一个变体将在任何进一步示例中使用。它使用嵌套闭包构建 RouteTree,这有利于在定义代码的缩进中表示分层 RouteTree。
子节点将自动接收一个唯一节点 ID,表示其祖先的层次结构。例如,名为 bar
的子节点,其父节点名为 foo
,将具有 ID foo.bar
。
这与路径段的情况相同,例如 en/foo/bar
。
您可以通过调用 $node->inheritSegment(false)
来禁用将段继承到其子代。如果您只想将 RouteNode 用于分组目的,而不在 URL 路径中表示,这很有用。
与 Laravel 的 Route groups 一样,默认情况下,中间件和(控制器-)命名空间也将继承。
路径段
默认情况下,RouteNode 的名称也将是其路径段。但您也可以通过调用 RouteNode 的 segment
方法为节点指定不同的段
RouteTree::node('company', function (RouteNode $node) { $node->segment('our-great-company'); $node->get($callback); });
上述代码将注册以下路由
- 名为
de.company.get
且路径为de/our-great-company
的路由 - 名为
en.company.get
且路径为en/our-great-company
的路由
您可以通过传递包括所有语言段的 LanguageMapping
对象来定义本地化路径段
$node->segment( Webflorist\RouteTree\LanguageMapping::create() ->set('en', 'our-great-company') ->set('de', 'unsere-tolle-firma') );
这将注册以下路由
- 名为
de.company.get
且路径为de/our-great-company
的路由 - 名为
en.company.get
且路径为en/unsere-tolle-firma
的路由
您还可以通过使用 自动翻译 功能来处理段翻译。
中间件
您可以使用以下方法将中间件分配给 RouteNodes
$node->middleware('auth');
这将将 auth
中间件附加到 RouteNode 的所有操作,并将其继承到所有子节点。
可以在 middleware
方法的第二个参数中指定中间件参数。
可以通过将布尔值 false
作为 middleware
方法的第三个参数传递来禁用中间件的继承。
如果您希望子节点不使用继承的中间件,只需在子节点的回调中声明以下内容
$node->skipMiddleware('auth');
也可能存在这样的情况,您希望 RouteNode 的特定操作具有额外的中间件或跳过在 RouteNode 上定义的中间件。您可以通过将 middleware
调用链接到操作调用来实现这一点。以下是一个示例
RouteTree::node('user', function (RouteNode $node) { $node->middleware('auth'); $node->get($callback)->skipMiddleware('auth'); $node->post($callback); $node->delete($callback)->middlware('admin'); });
这将注册以下路由
GET
路由没有任何中间件。POST
路由具有auth
中间件。DELETE
路由具有auth
和admin
中间件。
控制器命名空间
默认情况下,所有 Controller@method
回调定义都将使用 App\Http\Controllers
作为命名空间。
使用RouteNode的namespace
方法将向该命名空间追加一个段并将其继承到其子节点。可以通过在命名空间前加反斜杠来覆盖继承。
RouteTree::node('account', function (RouteNode $node) { $node->namespace('Account'); $node->child('address' function (RouteNode $node) { $node->get('AddressController@get'); // will point to `App\Http\Controllers\Account\AddressController` }) $node->child('password' function (RouteNode $node) { $node->get('\My\Other\Namespace\PasswordController@get'); // will point to `My\Other\Namespace\PasswordController` }) });
路由参数
以下代码将生成路由en/user/{id}
和de/user/{id}
。
RouteTree::node('user', function (RouteNode $node) { $node->child('id', function (RouteNode $node) { $node->parameter('id'); $node->get('id', function ($id) { return 'User '.$id; }); }); });
您还可以为参数设置正则表达式约束。
$node->parameter('id')->regex('[0-9]+');
当使用parameter
或resource
节点时,您可能还希望能够翻译路由键(例如,实现博客文章的语言切换菜单,不同语言有不同的slug)。
有两种实现方式
- 您可以使用此语法为每种语言声明参数的可能路由键的静态列表(通过数组键(0,1,' whatever')启用
translation
)
$node->parameter('blog_category')->routeKeys(LanguageMapping::create() ->set('en', [ 0 => 'search-engine-optimization', 1 => 'web-development' ]) ->set('de', [ 0 => 'suchmaschinen-optimierung', 1 => 'web-entwicklung' ]) );
- 您还可以通过
Eloquent
模型来翻译路由键。这有两个要求
- 必须使用
RouteParameter
或RouteResource
的model
方法来声明Eloquent
模型
$node->resource('blog_category', 'BlogCategoryController')->model('App\BlogCategory');
或
$node->parameter('blog_category')->model('App\BlogCategory');
- 模型必须实现接口
Webflorist\RouteTree\Interfaces\TranslatesRouteKey
及其随后的translateRouteKey
方法。以下是一个示例实现
public static function translateRouteKey(string $value, string $toLocale, string $fromLocale): string { return BlogCategory::bySlug($value, $fromLocale)->slugs->where('locale', $toLocale)->first()->slug ?? $value; }
资源路由节点
类似于Laravel的Route::resource()
方法,RouteTree也可以注册资源路由
RouteTree::node('photos')->resource('photo', 'PhotoController');
这将生成所有语言的完整资源路由集
还支持使用only
或except
方法使用部分资源路由
$node->resource('photo', 'PhotoController')->only(['index', 'show']); $node->resource('photo', 'PhotoController')->except(['create', 'store', 'update', 'destroy']);
资源节点也可以有子节点。在这种情况下,在$node->resource
上调用child
方法而不是$node
RouteTree::node('photos', function (RouteNode $node) { $node->resource('photo', 'PhotoController') $node->resource->child('featured', function (RouteNode $node) { $node->get('PhotoController@featured'); }); });
以上代码将额外生成以下路由
- 路由
en.photos.featured.get
,URI为en/photos/{photo}/featured
。 - 路由
de.photos.featured.get
,URI为de/photos/{photo}/featured
。
从 RouteTree 检索节点
现在我们已经定义了RouteTree,可以在应用程序的任何地方使用route_node()
助手来访问其RouteNodes
route_node()
route_node()
是RouteTree::getCurrentNode()
的快捷方式,将返回当前活动的RouteNode。route_node('company.team.contact')
route_node('company.team.contact')
是RouteTree::getNode('company.team.contact')
的快捷方式,将返回ID为company.team.contact
的RouteNode
如果RouteTree无法找到当前/指定的节点,它将抛出NodeNotFoundException
,除非在配置中设置了回退节点routetree.fallback_node
。默认配置将回退节点设置为根节点,因为在生产环境中您可能希望抑制NodeNotFoundExceptions
。
生成 URL
RouteTree的一个主要用例是创建语言无关的链接。RouteNodes和RouteActions都有一个getUrl()
方法,该方法返回一个RouteUrlBuilder
对象,该对象在转换为字符串时将生成相应的URL。
(string) route_node('company.team.contact')->getUrl()
将返回RouteNode动作的URL。如果节点有多个动作,它将返回到其第一个get
动作(或资源中的index
动作)的链接。
返回的RouteUrlBuilder
对象有几个流畅的设置器来修改生成的链接
-
->locale ( ?string $locale=null ) : RouteUrlBuilder
(string) route_node('company')->getUrl()->locale('en')
将返回英文语言的URL(例如,en/company
)。(默认为当前语言环境) -
->absolute ( ?bool $absolute=null ) : RouteUrlBuilder
(string) route_node('company')->getUrl()->absolute(false)
将返回一个相对路径而不是包含域的绝对URL(默认可以配置在routetree.absolute_urls
中) -
->action (字符串 $locale) : RouteUrlBuilder
(字符串) route_node('photos')->action('create')
将返回资源操作create
的 URL(默认情况下,在en
区域设置下将'/create'
添加到 URL)。有关详细信息,请参阅资源化路由节点表格。默认情况下将使用index
或第一个GET
操作。注意,对于show
、edit
、update
和destroy
操作,您还必须指定设置 URL参数
的路由键(见下文)。 -
->parameters (数组 $parameters) : RouteUrlBuilder
(字符串) route_node('photos')->action('edit')->parameters(['photo' => 'my-slug'])
将产生 URL/en/photos/my-slug/edit
使用区域设置en
。任何包含一个或多个参数的路由 URL 都需要填充这些参数的值,因此需要在传递的数组中指定一个键。例如,photo/{photo_id}/comments/{comment_id}
需要传递['photo_id' => $photoId, 'comment_id' => $commentId]
。任何缺失的路由键(即参数值或别名)将来自当前活动的 LaravelRequest
- 如果可能的话。
路由 Payload
您可以使用关联的 RoutePayload
对象来定义任何想要传递给路由节点的信息,该对象可以通过节点的 payload
属性公开访问。
定义 Payload
您可以使用以下语法选项直接在 RoutePayload
对象中设置负载项:
- 通过调用
RoutePayload
的set
方法
$node->payload->set('title', 'My photos');
- 通过调用名为您想要设置的键的魔法设置器
$node->payload->title('My photos');
- 通过简单的属性定义
$node->payload->title = 'My photos';
负载项的值可以是任何数据类型,以及 Closure
。闭包将接收两个参数
route parameter => route key
对的数组,用于检索负载项(这样可以使负载项依赖于当前的路由参数)。- 要检索负载项的语言的区域设置。
与路径段一样,任何负载项也可以使用 LanguageMapping
对象进行多语言处理
$node->payload->title = LanguageMapping::create() ->set('en', 'My photos') ->set('de', 'Meine Photos') );
您还可以通过使用自动翻译功能来处理负载项的翻译。
如果您想要根据操作有不同的负载项值,您可以覆盖路由节点的负载项,使用路由操作的负载项。以下是一个示例
$node->getAction('edit')->payload->set('title', 'Edit photo');
对于 parameter/resource
节点,还有从 Eloquent
模型获取负载项的可能性。为此有两个要求
- 必须使用
RouteParameter
或RouteResource
的model
方法来声明Eloquent
模型
$node->resource('photos', 'PhotoController')->model('App\Photo');
或
$node->parameter('photo')->model('App\Photo');
- 该模型必须实现接口
Webflorist\RouteTree\Interfaces\ProvidesRoutePayload
并随后实现getRoutePayload
方法。以下是一个示例实现
public static function getRoutePayload(string $payloadKey, array $parameters, string $locale, ?string $action) { if ($payloadKey === 'title' && $action === 'show') { return self::find($parameters['photo'])->title; } }
检索 Payload
负载项可以在应用程序的任何位置通过 RoutePayload
的 get
方法检索。以下是一个使用当前路由节点和路由操作的示例
route_node()->payload->get('title');
这将按照以下顺序查找 title
负载项
- 在此类中直接设置的负载项。
- 在路由节点的
RoutePayload
中设置的负载项(仅当此RoutePayload
是特定于路由操作的。) - 从 Eloquent 模型返回的负载项(仅当路由节点与一个关联的路由参数相关联,并且该路由参数实现了
ProvidesRoutePayload
接口。) - 通过自动翻译在相对于路由节点 ID 的翻译键中查找(见自动翻译)。
有很多用例,其中这种负载项功能非常有用。这对于例如非常有用。
- 设置图标的类,使其在页面标题旁边的菜单中可见。
- 为每个页面设置特定语言的内容摘要,在网站地图中显示。
- 还有更多...
特殊的 title
和 navTitle
Payload
页面标题(用于元标签、规范标签、链接标题属性、导航菜单、面包屑、h1标签等)可能是最常用的负载应用之一。你也可能想要为导航菜单中的页面设置一个特殊的(较短的)标题。为了简化处理,RouteNodes 和 RouteActions 有特殊的 getTitle()
和 getNavTitle()
方法,这些方法添加了一些额外的回退魔法。
- 未设置
navTitle
将回退到title
。 - 最后的回退总是 RouteNode 的名称的大写(例如
Photos
)。 - 资源节点的一些操作已经带有有意义的默认页面标题(例如,为
create
操作的'创建资源'
)。
要利用这个魔法,始终使用例如 route_node()->getTitle()
而不是 route_node()->payload->get('title')
,以及使用 route_node()->getNavTitle()
而不是 route_node()->payload->get('navTitle')
。
自动翻译
RouteTree 还包括有关自动翻译的一些魔法。基本概念是将 RouteTree 的层次结构映射到本地化文件夹内的文件夹结构。
配置键 localization.base_folder
设置了 RouteTree 使用的本地化文件和文件夹的基本文件夹。默认值是 pages
,这表示文件夹 \resources\lang\%locale%\pages
。
有 2 个独立的自动翻译功能。
- 自动翻译节点的路径段和负载(例如,标题、navTitle、描述等)。
- 自动翻译常规页面内容。
自动翻译节点路径段和 Payload
这提供了一种简单直观的方式来配置通过 Laravel 的本地化文件的多语言路径段、页面标题或任何其他自定义信息。
每个 RouteNode 都表示为一个文件夹,并且节点所在的文件夹中包含所有自动翻译信息。该文件的命名方式是在配置键 localization.file_name
下配置的。默认值是 pages
,这意味着所有一级页面的信息都应该放在这个文件中:\resources\lang\%locale%\pages\pages.php
示例:假设你已定义以下 RouteNodes(为了简单起见,省略了任何操作或其他选项)
RouteTree::node('company', function (RouteNode $node) { $node->child('history', ...); $node->child('team', function (RouteNode $node) { $node->child('office', ...); $node->child('service', ...); }); }); RouteTree::node('contact', ...);
请注意,任何节点上都没有定义路径段、页面标题或自定义信息。我们将为此使用自动翻译。
要使用自动翻译,应在每个区域定义的基本文件夹中存在以下文件和文件夹结构(默认为 \resources\lang\%locale%\pages
)
.
├── pages.php
├── company
├── pages.php
└── team
└── pages.php
每个 pages.php 文件都包括对应于其所在文件夹的节点的子节点的自动翻译信息。以下是一个德语语言文件的示例内容
./pages.php
<?php return [ 'segment' => [ 'company' => 'firma', 'contact' => 'kontakt', ], 'title' => [ 'company' => 'Über unsere Firma', 'contact' => 'Kontaktieren Sie uns!', '' => 'Startseite', ], 'abstract' => [ 'company' => 'Hier finden Sie allgemeine Informationen über unsere Firma.', 'contact' => 'Hier finden Sie Möglichkeiten, mit uns in Kontakt zu treten.', ] ];
注意,在标题数组中有一个额外的条目,其键为空字符串,值为 "Home"。这是根节点的标题(因为根节点的 ID 和名称始终是空字符串 ''
)。
./company/pages.php
<?php return [ 'segment' => [ 'history' => 'geschichte', 'team' => 'mitarbeiter', ], 'title' => [ 'history' => 'Die Firmengeschichte', 'team' => 'Unsere Mitarbeiter', ], 'description' => [ 'history' => 'Hier finden Sie die Entstehungsgeschichte unserer Firma.', 'team' => 'Hier sind unsere Mitarbeiter zu finden.', ] ];
./company/team/pages.php
<?php return [ 'segment' => [ 'office' => 'buero', 'service' => 'kundendienst', ], 'title' => [ 'office' => 'Büro', 'service' => 'Kundendienst', ], 'description' => [ 'office' => 'Hier finden Sie unsere Büro-Mitarbeiter.', 'service' => 'Hier finden Sie unsere Service-Mitarbeiter.', ] ];
使用此设置,语言文件中定义的段将自动用于对应节点的路由路径。
标题也将通过每个针对特定节点提交的 getTitle-call
来检索(例如,如果当前区域是 de
,则 route_node('company.team.service')->getTitle()
将返回 Büro
)。
相同的事情也适用于描述(或任何其他负载)。(例如,如果当前区域是 de
,则 route_node('company.team.service')->payload->get('description')
将返回 Hier finden Sie unsere Service-Mitarbeiter.
)。
您还可以通过在节点名称后附加下划线和操作来设置特定于操作的标题或 navTitles 通过自动翻译。这对于资源节点非常有用。以下是一个示例
<?php return [ 'title' => [ 'users' => 'Users', 'users_create' => 'Create new user', 'users_show' => 'User :userName', 'users_edit' => 'Edit user :userName', ], ];
自动翻译常规页面内容
在大多数网站上,您都希望将视图中的页面内容进行翻译。RouteTree 包含一个方便的辅助函数 trans_by_route()
,该函数将使用相同的文件夹结构,但语言文件的名称是最后一个 RouteNode。
使用上面的示例,对于 office
页面,此文件的路径会是: ./company/team/office.php
缓存
如果您使用 Laravel 的路由缓存,RouteTree 也必须缓存自己的数据。所以,不要使用 'artisan route:cache'
,而要使用 RouteTree 的缓存命令,这个命令也会处理 Laravel 路由的缓存。
php artisan routetree:route-cache
XML 站点地图
拥有一个最新的 sitemap.xml
文件是现代搜索引擎优化网站的一个重要标准。RouteTree 包含创建此类文件的功能。
以下 artisan 命令将创建一个静态的 XML 网站地图文件
php artisan routetree:generate-sitemap
默认情况下,输出文件将位于 'public/sitemap.xml'
。但是,您可以在 RouteTree 的配置文件中配置此路径。
您还可以启用一个路由来动态提供网站地图(请参阅 routetree.sitemap.route
下的配置选项)。
网站地图中的任何 URL 都会自动使用 config('app.url')
作为基础 URL。但是,您也可以在 routetree.sitemap.base_url
配置下指定不同的值。
默认情况下,所有使用 RouteTree 创建的路由都将包含在网站地图中。尽管有一些排除标准
- 只有
GET
路由将被包含。 - 使用在
routetree.sitemap.excluded_middleware
下配置的中间件的路由将被自动排除(默认为['auth']
)。 - 重定向路由将被自动排除。
- 具有
parameters
的路由只有在 RouteTree 可以检索这些参数的所有可能值时才能被包含。有两种实现方式- 使用
routeKeys()
方法(请参阅 路由参数) - 通过声明一个实现接口
Webflorist\RouteTree\Interfaces\ProvidesRouteKeyList
的Eloquent
模型,并因此拥有getRouteKeyList()
方法。默认实现包含在特性Webflorist\RouteTree\Interfaces\Traits\ProvidesRouteKeyListDefault
中
- 使用
public static function getRouteKeyList(string $locale = null, ?array $parameters = null): array { return self::pluck( (new self())->getRouteKeyName() )->toArray(); }
此外,您还可以明确从网站地图中排除一个 RouteNode(及其所有子节点)
$node->sitemap->exclude();
sitemap.xml
还允许为搜索引擎定义额外的信息(请参阅 https://www.sitemaps.org/protocol.html#xmlTagDefinitions)。您可以使用以下代码为节点声明此数据
$node->sitemap ->lastmod(Carbon::parse('2019-11-16T17:46:30.45+01:00')) ->changefreq('monthly') ->priority(1.0);
此外,您还可以使用负载翻译(通过 Eloquent
模型或语言文件)自动检索这些值。
API (需要至少 Laravel 5.6!)
RouteTree 还包括一个 API,允许检索与 RouteTree 注册的路由相关的信息。必须通过配置 routetree.api.enabled
启用 API,默认基本 URL 为 api/routetree/
(也可以配置)。
目前有两个端点
GET api/routetree/routes
:
返回注册到 Routetree 的路由集合。GET api/routetree/routes/{route_name}
:
返回有关注册到 Routetree 的路由的信息。
事件
RouteTree 在各种情况下调度事件
-
\Webflorist\RouteTree\Events\LocaleChanged
当RouteTreeMiddleware
保存到会话中的区域设置更改时,将调度。旧的区域设置可通过事件的$oldLocale
属性访问,新的区域设置可通过$newLocale
访问。 -
\Webflorist\RouteTree\Events\NodeNotFound
当调用route_node()
时,如果当前或指定的节点找不到,将调度。指定的 RouteNode ID 可通过事件的$nodeId
属性访问,如果没有找到当前节点,则为null
。 -
\Webflorist\RouteTree\Events\Redirected
当RouteTreeMiddleware
执行自动重定向时,将调度。目标 URI 可通过事件的$toUri
属性访问,源 URI 可通过$fromUri
访问。
重要的 RouteTree 方法
对于已经提及和解释的 root()
、node()
方法,请参阅上述相应部分。
以下是 RouteTree 类的其他一些有用方法
- getRootNode:获取根节点,它也是整个 RouteTree。
- getCurrentNode:获取当前活动的 RouteNode。(使用
route_node()
作为快捷方式) - getCurrentAction:获取当前活动操作。
- doesNodeExist:检查RouteTree中是否存在节点。它接受一个参数,即要检查的节点ID。(例如:
RouteTree::doesNodeExist('company.team.office')
) - getNode:获取并返回通过其ID的RouteNode。(例如:
RouteTree::getNode('company.team.office')
;可以使用route_node('company.team.office')
作为快捷方式)
重要的 RouteNode 方法
关于已提及并解释的方法getUrl
、getTitle
和getNavTitle
,请参见上面的相应部分。
以下是RouteNode类的其他一些有用方法
- getParentNode:获取此节点的父节点。(例如:
route_node('company.team.office')->getParentNode()
将检索ID为company.team
的节点。) - getParentNodes:获取此节点所有层级父节点(以根节点为第一个元素)的数组。(例如:
route_node()->getParentNodes()
将检索从当前活动节点到根节点的所有祖先节点。这对于网站地图或面包屑非常有用。) - hasChildNodes:检查此节点是否有任何子节点。
- getChildNodes:获取所有子节点的数组(例如,对于子菜单很有用)。
- hasChildNodes:检查此节点是否有任何子节点。
- getChildNode:检查此节点是否有具有指定名称的子节点。
- getId:获取此节点的完整ID。
- isActive:检查当前节点是否当前活动(可选地带有所需参数)(例如,用于向活动链接应用CSS类)。
- nodeOrChildIsActive:检查当前节点或其子节点是否当前活动(可选地带有所需参数)(例如,用于向活动链接应用CSS类)。
辅助函数
此包包含几个辅助函数
-
route_tree:从Laravel的服务容器中获取RouteTree单例。您可以在应用的任何地方(控制器、视图等)使用它来访问RouteTree服务。
-
route_node:
- 如果没有参数调用:获取当前活动的RouteNode。
- 如果有参数调用:
route_node('company.team.contact')
将返回ID为'company.team.contact'
的RouteNode。
-
route_node_url:是
route_node()->getUrl()
的快捷方式。 -
trans_by_route:使用当前节点的内容语言文件翻译页面内容(请参见上面的
自动翻译常规页面内容
部分)。