我在应用配置中获得urlManager
部分,每条路线有多个网址:
'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 URL作为数组存储在frontend/config/main.php
中,每个路由有多个URL。给定路由的第一个URL(即/article-a
)是规范的,其余是遗留URL。
为指向同一路由的一组网址指定规范网址的最自然方式是什么?它可以是rel="canonical"
视图中的,也可以是301/302重定向到规范网址。
规范URL最好在定义路由的地方指定(在这种情况下为frontend/config/main.php
配置文件)。 这里的要求是规范URL应该在控制器之外定义,而不是硬编码到控制器。
答案 0 :(得分:4)
我认为从应用程序创建URL到“article / a”时会遇到问题。
为什么不使用htaccess或vhost文件进行302重定向到正确的URL?
如果你想通过urlManager来处理它,我想你可以只注册规范链接
$this->registerLinkTag(['rel' => 'canonical', 'href' => 'article/a']);
在视图中。 此处的模式详细信息:http://www.yiiframework.com/doc-2.0/yii-helpers-baseurl.html#canonical()-detail
答案 1 :(得分:4)
我不确定您究竟需要如何管理规则,因此我会选择一般用例,并根据Paddy Moogan's Article的理解来确定我的答案。我将在以下示例中恢复,我希望它有助于设计您所需的解决方案:
假设搜索引擎确实发送了一个机器人来检查我网站上的page B
,并且我对访问{{1而不是page B
。这就是我如何澄清我对机器人的看法:
强制page A
重定向到301
:
告诉搜索引擎此页面永久已移至第A页。因此请不要向其发送更多人。请将它们发送到第A页。
强制page A
重定向到302
:
告诉搜索引擎此页面临时已移至第A页。所以做任何你认为的事情 是合适的。
打开page A
( 200状态代码)但插入Canonical
link element
指向page B
:
告诉搜索引擎这个页面工作正常,但对我来说是一个次要页面,我建议将下一个访问者发送到页面 相反。
基于此,我将看到规则配置的可能结构:
page A
这样我可以使用Yii的默认类yii\web\UrlRule链接尽可能多的数组,而我可以在我的应用程序组件文件夹中有一个专用于SEO相关控制器的自定义数组。
在开始编码之前,我希望我的网站能够表现出来:
'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'
],
]
响应(否)
canonical added)。200
状态代码的 / about 。301
状态代码的 / about 。302
响应(由200
操作呈现)。除了与此类似的标记之外,没有重定向会自动注入源代码:
index/about
<link href="http://my-website/about" rel="canonical">
响应(通过自己的操作200
呈现),但同样注入上面的规范标签。 SEOUrlRule 只会扩展\yii\web\UrlRule并覆盖其parseRequest方法以定义额外属性,我们将根据这些属性强制进行HTTP重定向或调用whatever/experimental
将规范链接标记注册到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);
}
}
或其相关操作在解决路线的早期阶段仍然无法使用,如lifecycle diagram所示,但似乎Yii::$app->controller
已初始化,您可以使用其$params属性设置自定义参数(在此example 中完成),这对于应该共享或填充更多数据的更多广告情况可能很有用到最终输出。
答案 2 :(得分:1)
Yii2提供了一个根据您的规则生成canonnical网址的工具。
\helpers\Url::canonical()
这个想法是它会为你提供一个'article-a'的网址。