urlManager 配置中的 Yii 2 规范 URL
Yii 2 canonical URL in urlManager configuration
我在应用配置中有 urlManager
部分,每个路由有多个 URL:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
'article-a' => 'article/a', // canonic comes first
'article-deprecated-a' => 'article/a',
'article-another-a-is-deprecated' => 'article/a',
'b-annoucement' => 'announcement/b', // canonic comes first
'legacy-b-annoncement' => 'announcement/b',
...
路由的 SEF URLs 作为数组存储在 frontend/config/main.php
中,每个路由有多个 URLs。给定路由的第一个 URL(即 /article-a
)是规范的,其余的是旧版 URL。
为指向同一路由的一组 URL 指定规范 URL 的最自然方法是什么?它可以是 rel="canonical"
在视图中或 301/302 重定向到规范 URL.
Canonical URLs 最好在定义路由的地方指定(在本例中为 frontend/config/main.php
配置文件)。 这里的要求是规范 URL 应该在控制器之外定义,而不是硬编码到控制器。
我认为您在从应用程序创建 URL 到 "article/a" 时会遇到问题。
为什么不使用 htaccess 或 vhost 文件进行 302 重定向到正确的 URL?
如果你想通过 urlManager 处理它,我想你可以只注册规范 link
$this->registerLinkTag(['rel' => 'canonical', 'href' => 'article/a']);
在视图中。
此处的模式详细信息:http://www.yiiframework.com/doc-2.0/yii-helpers-baseurl.html#canonical()-detail
Yii2 提供了一个工具来根据您的规则生成规范 url。
\helpers\Url::canonical()
我们的想法是它将为您提供 url 到 'article-a'。
我不确定您究竟需要如何管理您的规则,所以我会选择一个一般用例,我的回答将基于我从 Paddy Moogan's Article 中理解的内容,我将继续在以下示例中,我希望它有助于设计您所需的解决方案:
要求:
假设 搜索引擎 确实发送了一个 机器人 来检查我网站中的 page B
而我不满意人们到达 page B
而不是 page A
。所以这就是我如何向 robot:
阐明我的观点
强制 301
重定向到 page A
:
告诉搜索引擎此页面已永久 移至页面 A。因此请不要向其发送更多人。改为将它们发送到页面 A。
强制 302
重定向到 page A
:
告诉搜索引擎这个页面是临时移动到页面A。所以随心所欲
合适。
打开 page B
(200 状态代码)但插入 Canonical
link元素
指向 page A
:
告诉搜索引擎这个页面工作正常,但对我来说它是一个 次要 页面,我建议将下一个访问者发送到该页面
A 代替.
设计:
因此,基于此,我将如何看待我的规则配置的可能结构:
'rules' => [
[
// by default: 'class' => 'yii\web\UrlRule',
'pattern' => '/',
'route' => 'site/index',
],
[
// the custom class
'class' => 'app\components\SEOUrlRule',
'pattern' => 'about',
'route' => 'site/about',
'permanents' => [
'deprecated-about',
'an-older-deprecated-about'
],
'temporaries' => [
'under-construction-about',
],
'secondaries' => [
'about-page-2'
]
],
[
// different route with own action but canonical should be injected
'class' => 'app\components\SEOUrlRule',
'pattern' => 'experimental-about',
'route' => 'whatever/experimental',
'canonical' => 'about'
],
]
这样我可以链接尽可能多的数组,因为我需要使用 Yii 的默认值 class yii\web\UrlRule,同时我可以在我的应用程序组件文件夹中有一个自定义的数组,专用于 SEO 相关控制器。
在开始编码之前,这是我希望我的网站的行为方式:
- 您访问 /about 页面,您会收到
200
回复(没有
添加规范)。
- 您访问 /deprecated-about 页面,您被重定向到
/about 状态码
301
。
- 您访问 /under-construction-about 页面,您被重定向到
/about 状态码
302
。
- 您访问 /about-page-2 页面,您会收到
200
响应(由 index/about
操作呈现).除了与此类似的标记之外,没有重定向会自动注入到源代码中:
<link href="http://my-website/about" rel="canonical">
- 你访问 /experimental-about 页面你会得到一个
200
响应(由它自己的动作呈现 whatever/experimental
) 但上面注入了相同的规范标签。
代码:
SEOUrlRule 将简单地扩展 \yii\web\UrlRule and override its parseRequest 方法来定义额外的属性,我们将根据这些属性强制进行 HTTP 重定向或在注册后调用 parent::parseRequest()
Yii::$app->view
:
的规范 link 标签
namespace app\components;
use Yii;
class SEOUrlRule extends \yii\web\UrlRule
{
public $permanents = [];
public $temporaries = [];
public $secondaries = [];
public $canonical = null;
public function parseRequest($manager, $request)
{
$pathInfo = $request->getPathInfo();
if(in_array($pathInfo, $this->permanents))
{
$request->setPathInfo($this->name);
Yii::$app->response->redirect($this->name, 301);
}
else if(in_array($pathInfo, $this->temporaries))
{
$request->setPathInfo($this->name);
Yii::$app->response->redirect($this->name, 302);
}
else if($this->canonical or in_array($pathInfo, $this->secondaries))
{
$route = $this->name;
if ($this->canonical === null) $request->setPathInfo($route);
else $route = $this->canonical;
Yii::$app->view->registerLinkTag([
'rel' => 'canonical',
'href' => Yii::$app->urlManager->createAbsoluteUrl($route)
]);
}
return parent::parseRequest($manager, $request);
}
}
这就是它所需要的。请注意,Yii::$app->controller
或其相关操作在解决路线的早期阶段尚不可用,如 lifecycle diagram but it seems that Yii::$app->view
is already initialized and you can use its $params property to set custom parameters (as it is done in this example 所示,这可能对更高级的情况有用更多数据应该共享或填充到最终输出。
我在应用配置中有 urlManager
部分,每个路由有多个 URL:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
'article-a' => 'article/a', // canonic comes first
'article-deprecated-a' => 'article/a',
'article-another-a-is-deprecated' => 'article/a',
'b-annoucement' => 'announcement/b', // canonic comes first
'legacy-b-annoncement' => 'announcement/b',
...
路由的 SEF URLs 作为数组存储在 frontend/config/main.php
中,每个路由有多个 URLs。给定路由的第一个 URL(即 /article-a
)是规范的,其余的是旧版 URL。
为指向同一路由的一组 URL 指定规范 URL 的最自然方法是什么?它可以是 rel="canonical"
在视图中或 301/302 重定向到规范 URL.
Canonical URLs 最好在定义路由的地方指定(在本例中为 frontend/config/main.php
配置文件)。 这里的要求是规范 URL 应该在控制器之外定义,而不是硬编码到控制器。
我认为您在从应用程序创建 URL 到 "article/a" 时会遇到问题。
为什么不使用 htaccess 或 vhost 文件进行 302 重定向到正确的 URL?
如果你想通过 urlManager 处理它,我想你可以只注册规范 link
$this->registerLinkTag(['rel' => 'canonical', 'href' => 'article/a']);
在视图中。 此处的模式详细信息:http://www.yiiframework.com/doc-2.0/yii-helpers-baseurl.html#canonical()-detail
Yii2 提供了一个工具来根据您的规则生成规范 url。
\helpers\Url::canonical()
我们的想法是它将为您提供 url 到 'article-a'。
我不确定您究竟需要如何管理您的规则,所以我会选择一个一般用例,我的回答将基于我从 Paddy Moogan's Article 中理解的内容,我将继续在以下示例中,我希望它有助于设计您所需的解决方案:
要求:
假设 搜索引擎 确实发送了一个 机器人 来检查我网站中的 page B
而我不满意人们到达 page B
而不是 page A
。所以这就是我如何向 robot:
强制
301
重定向到page A
:告诉搜索引擎此页面已永久 移至页面 A。因此请不要向其发送更多人。改为将它们发送到页面 A。
强制
302
重定向到page A
:告诉搜索引擎这个页面是临时移动到页面A。所以随心所欲 合适。
打开
page B
(200 状态代码)但插入 Canonical link元素 指向page A
:告诉搜索引擎这个页面工作正常,但对我来说它是一个 次要 页面,我建议将下一个访问者发送到该页面 A 代替.
设计:
因此,基于此,我将如何看待我的规则配置的可能结构:
'rules' => [
[
// by default: 'class' => 'yii\web\UrlRule',
'pattern' => '/',
'route' => 'site/index',
],
[
// the custom class
'class' => 'app\components\SEOUrlRule',
'pattern' => 'about',
'route' => 'site/about',
'permanents' => [
'deprecated-about',
'an-older-deprecated-about'
],
'temporaries' => [
'under-construction-about',
],
'secondaries' => [
'about-page-2'
]
],
[
// different route with own action but canonical should be injected
'class' => 'app\components\SEOUrlRule',
'pattern' => 'experimental-about',
'route' => 'whatever/experimental',
'canonical' => 'about'
],
]
这样我可以链接尽可能多的数组,因为我需要使用 Yii 的默认值 class yii\web\UrlRule,同时我可以在我的应用程序组件文件夹中有一个自定义的数组,专用于 SEO 相关控制器。
在开始编码之前,这是我希望我的网站的行为方式:
- 您访问 /about 页面,您会收到
200
回复(没有 添加规范)。 - 您访问 /deprecated-about 页面,您被重定向到
/about 状态码
301
。 - 您访问 /under-construction-about 页面,您被重定向到
/about 状态码
302
。 - 您访问 /about-page-2 页面,您会收到
200
响应(由index/about
操作呈现).除了与此类似的标记之外,没有重定向会自动注入到源代码中:<link href="http://my-website/about" rel="canonical">
- 你访问 /experimental-about 页面你会得到一个
200
响应(由它自己的动作呈现whatever/experimental
) 但上面注入了相同的规范标签。
代码:
SEOUrlRule 将简单地扩展 \yii\web\UrlRule and override its parseRequest 方法来定义额外的属性,我们将根据这些属性强制进行 HTTP 重定向或在注册后调用 parent::parseRequest()
Yii::$app->view
:
namespace app\components;
use Yii;
class SEOUrlRule extends \yii\web\UrlRule
{
public $permanents = [];
public $temporaries = [];
public $secondaries = [];
public $canonical = null;
public function parseRequest($manager, $request)
{
$pathInfo = $request->getPathInfo();
if(in_array($pathInfo, $this->permanents))
{
$request->setPathInfo($this->name);
Yii::$app->response->redirect($this->name, 301);
}
else if(in_array($pathInfo, $this->temporaries))
{
$request->setPathInfo($this->name);
Yii::$app->response->redirect($this->name, 302);
}
else if($this->canonical or in_array($pathInfo, $this->secondaries))
{
$route = $this->name;
if ($this->canonical === null) $request->setPathInfo($route);
else $route = $this->canonical;
Yii::$app->view->registerLinkTag([
'rel' => 'canonical',
'href' => Yii::$app->urlManager->createAbsoluteUrl($route)
]);
}
return parent::parseRequest($manager, $request);
}
}
这就是它所需要的。请注意,Yii::$app->controller
或其相关操作在解决路线的早期阶段尚不可用,如 lifecycle diagram but it seems that Yii::$app->view
is already initialized and you can use its $params property to set custom parameters (as it is done in this example 所示,这可能对更高级的情况有用更多数据应该共享或填充到最终输出。