Yii 2 канонический URL в конфигурации urlManager
у меня есть 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 URL для маршрутов хранятся в frontend/config/main.php
как массив, с несколькими URL-адресами на маршрут. Первый URL для данного маршрута (т. е. /article-a
) является каноническим, а остальные устаревшие URL-адреса.
каков наиболее естественный способ указать канонический URL-адрес для группы URL-адресов, указывающих на один и тот же маршрут? Это может быть либо rel="canonical"
in view или 301/302 перенаправление на canonical URL-АДРЕС.
канонические URL-адреса должны быть предпочтительно указаны в месте, где были определены маршруты (frontend/config/main.php
файл конфигурации в этом случае). требование здесь заключается в том, что канонический URL должен быть определен вне контроллера, а не жестко закодирован для контроллера.
3 ответов
я не уверен, как именно вам нужно управлять своими правилами, поэтому я пойду на общий случай использования, и я буду основывать свой ответ на том, что я понял из Пэдди Moogan это который я возобновлю в следующем примере, и я надеюсь, что это поможет при разработке необходимого решения:
требования:
предполагая, что Поисковик направил робот проверить page B
на моем сайте, и я не в порядке с людьми, получающими к page B
вместо page A
. Так вот как я могу прояснить свою точку зрения на робот:
-
принуждение
301
перейти кpage A
:сообщая поисковой системе, что эта страница постоянно перешел на страницу A. Поэтому, пожалуйста, не отправляйте больше людей на него. Отправить их на страницу, а вместо.
-
принуждение
302
перейти кpage A
:говорю поисковик эту страницу временное перешел на страницу A. Так что делайте все, что вы думаете уместно.
-
Открытие
page B
(200 код состояния), но вставить канонический ссылка элемент указывая наpage 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 yii\web\UrlRule в то время как я могу иметь пользовательский в папке компонентов приложения, посвященной контроллерам, связанным с SEO.
прежде чем перейти к коду, вот как я ожидал бы, что мой сайт веди себя прилично:
- посетить /о страница вы получаете
200
ответ (нет canonical added). - посетить /устаревшие-о страница вы попадаете в
/о с
301
код состояния. - посетить /в стадии строительства-около страница вы попадаете в
/о с
302
код состояния. - посетить /о-Страница-2 страница вы получаете
200
ответ (вынесенноеindex/about
действие). Никакие перенаправления, кроме аналогичного тега, автоматически не вводятся в исходный код:<link href="http://my-website/about" rel="canonical">
- посетить /опытно-про страница вы получаете
200
ответ (оказанный своим собственным действиемwhatever/experimental
), но с тем же каноническим тегом выше.
код:
на SEOUrlRule будет просто расширьте \yii\web\UrlRule и переопределить его 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
или связанные с ним действия еще не будут доступны на этом раннем этапе решения маршрутов, как показано в этом схема жизненного цикла но, похоже, это Yii::$app->view
уже проинициализирован, и вы можете использовать его $params свойство для установки пользовательских параметров (как это делается пример), который может быть полезен для более продвинутых случаев, когда больше данных должно быть общим или заполнено до конечного вывода.
Я думаю, у вас будут проблемы при создании 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
коде с Yii2 предоставляет инструмент для создания URL-адресов canonnical на основе ваших правил.
\helpers\Url::canonical()
идея в том, что он предоставит вам url-адрес 'article-a'.