voskobovich / yii2-seo-toolkit
Yii2 的 SEO 工具
Requires
- php: >=5.4.0
- yiisoft/yii2: ~2.0.0
This package is not auto-updated.
Last update: 2024-09-14 18:20:41 UTC
README
帮助实现系统页面 URL 管理的自动化,类似于 CMS WordPress 的管理方式,可以通过管理面板中的路由表和重定向来管理。
支持
使用方法
-
创建用于存储路由的表(应用迁移)
-
创建自己的 UrlRoute 模型实例
-
配置 UrlManager
-
连接包中的 UrlManager 类
-
连接路由规则类
3. ClearUrlRule 用于清除 URL 中的垃圾信息(双重斜杠、末尾斜杠...)
3. UrlRule 直接负责路由 -
在必要的 AR 模型中
-
实现 SeoModelInterface 接口
-
连接 CreateUrlBehavior 行为
-
连接 ActualityUrlBehavior
-
创建用于管理路由的 CRUD
-
创建表(应用迁移)
php yii migrate/create create_table__url_route
从 \voskobovich\seo\migrations\create_table__url_route 继承创建的迁移类。
例如
class <ClassName> extends \voskobovich\seo\migrations\create_table__url_route { }
应用迁移
php yii migrate
- 创建自己的 UrlRoute 模型实例
Yii2 SEO toolkit 不知道将使用哪些模型和路由。
为了解决这个问题,需要从包中的 UrlRoute 模型继承并实现 UrlRouteInterface 的 2 个方法。
以下是我项目中的一个示例。
class UrlRoute extends \voskobovich\seo\models\UrlRoute { const OBJECT_CATEGORY = 'category'; const OBJECT_POST = 'post'; const OBJECT_TAG = 'tag'; const OBJECT_USER = 'user'; /** * List objects * @return array; */ public static function objectItems() { return [ static::OBJECT_CATEGORY => 'Category', static::OBJECT_POST => 'Post', static::OBJECT_TAG => 'Tag', static::OBJECT_USER => 'User', ]; } /** * Route map for objects * @return array; */ public static function routeMap() { return [ static::OBJECT_CATEGORY => [ static::ACTION_INDEX => 'category/index', static::ACTION_VIEW => 'category/view', ], static::OBJECT_POST => [ static::ACTION_INDEX => 'post/index', static::ACTION_VIEW => 'post/view', ], static::OBJECT_TAG => [ static::ACTION_INDEX => 'tag/index', static::ACTION_VIEW => 'tag/view', ], static::OBJECT_USER => [ static::ACTION_INDEX => 'user/index', static::ACTION_VIEW => 'user/view', ], ]; } }
从示例中可以看出,路由将与 4 个对象一起工作。
为每个对象配置了标准操作列表 "显示所有"(index)和 "显示一个"(view)。
这些操作是为了区分处理路由的逻辑。例如,我们可以这样做
-
路由 /foo 是对象 post 的 index 操作。最终,通过 /foo 我们将获得所有帖子的列表(在 Yii 路由中等于转到 post/index)。
-
路由 /bar 是对象 post 的 view 操作,id=3。最终,通过 /bar 我们将看到 id=5 的记录(在 Yii 路由中等于转到 post/view)。
可以通过在 getActionItems 方法中添加到列表来扩展操作列表。 -
配置 UrlManager
在标准 UrlManager 类中实现了路由缓存,这有助于加快标准 Yii2 路由中链接生成过程。缓存的概念是在没有规则的情况下记住哪些路由,从而避免再次尝试生成该路由的链接。也就是说,如果 post/view 路由没有规则,则不会再次搜索该路由的规则,这是合乎逻辑的。但对我们来说这是一个问题,原因如下。对于路由 post/view id=4 可能存在于路由表中,而对于 post/view id=5 则可能不存在。如果不禁用缓存,则在生成帖子链接时,如果首先生成 post/view id=5 的链接,则 UrlManager 将记住没有规则,并停止处理该路由。最终,我们将无法获得其他帖子的漂亮链接。因此,我们连接包中的 UrlManager 类。
'urlManager' => [ 'class' => 'voskobovich\seo\web\UrlManager', 'cacheable' => false, 'rules' => [ '' => 'post/index', ['class' => '\voskobovich\seo\web\ClearUrlRule'], ['class' => '\voskobovich\seo\web\UrlRule', 'modelClass' => 'app\models\UrlRoute'], // Default '<controller:\w+>/<id:\d+>' => '<controller>/view', '<controller:\w+>/<action:[a-zA-Z-]*>/<id:\d+>' => '<controller>/<action>', '<controller:\w+>/<action:[a-zA-Z-]*>' => '<controller>/<action>', ] ],
ClearUrlRule 规则会
- 将多个斜杠替换为一个
- 删除链接末尾的斜杠
- 将大写字母转换为小写
注意! 为了优化,建议在您的 Web 服务器级别配置这些规则。
UrlRule 负责我们的神奇路由。
在 modelClass 属性中传递之前创建的 UrlRoute 模型。
- 配置 AR 模型
为了使新模型链接自动进入路由表,需要连接 CreateUrlBehavior 并实现 SeoModelInterface 接口。
以下是我项目中的 Post 模型示例。
class Post extends BaseActiveRecord implements SeoModelInterface { // ... /** * @return array */ public function behaviors() { return [ 'createUrlBehavior' => [ 'class' => CreateUrlBehavior::className(), 'modelClass' => UrlRoute::className(), 'objectKey' => UrlRoute::OBJECT_POST ], 'actualityUrlBehavior' => [ 'class' => ActualityUrlBehavior::className(), 'modelClass' => UrlRoute::className(), 'objectKey' => UrlRoute::OBJECT_POST ] ]; } /** * Build Seo Path * @return null|string */ public function getSeoPath() { /** @var Category|TreeInterface $mainCategory */ $mainCategory = $this->mainCategory; if ($mainCategory) { return $mainCategory->path . '/' . $this->slug; } return null; } // ... }
方法 getSeoPath() 应该返回记录帖子的访问路径。
我的这个路由由帖子主分类的路径和帖子短名称组成 (/cat/subcat/post-slug)。
需要将我们的 UrlRoute 模型传递给行为,并使用 UrlRoute 模型中先前创建的常量来指定我们的 AR 模型对象。
- 连接 ActualityUrlBehavior
配置完成后,用户仍然可以通过旧链接访问页面。例如,我们为 /post/view?id=6 创建了一个漂亮的 URL /best-post。但用户仍然可以通过旧链接访问页面,尽管理想情况下应该将其重定向到新的 URL(使用 301 重定向)。
以下是我项目中的一个请求处理器示例。
class PostController extends Controller { // ... public function actionView($id) { /** @var Post $model */ $model = Post::find() ->andWhere(['id' => $id]) ->one(); $model->trigger(ActualityUrlBehavior::EVENT_CHECK_URL); return $this->render('view', [ 'model' => $model ]); } // ... }
首先声明,不需要将行为应用于整个控制器。这个行为只适用于 view 动作。
此行为也需要传递我们创建的 UrlRoute 模型类和常量中的对象名称。
- 创建用于管理路由的 CRUD
在视图中有一些简单的逻辑,所以我提供了项目中的代码示例。
文件 create.php
<?php $form = ActiveForm::begin() ?> <?= $form->field($model, 'path') ?> <?= $form->field($model, 'action_key')->dropDownList($model::getActionItems()) ?> <button type="submit" >Save</button> <?php ActiveForm::end() ?>
文件 update.php
<?php $form = ActiveForm::begin() ?> <?= $form->field($model, 'path') ?> <?php if ($model->checkAction($model::ACTION_INDEX)): ?> <?= $form->field($model, 'object_key')->dropDownList($model::getObjectItems()) ?> <?php elseif ($model->checkAction($model::ACTION_VIEW)): ?> <?= $form->field($model, 'object_key')->dropDownList($model::getObjectItems()) ?> <?= $form->field($model, 'object_id') ?> <?php elseif ($model->checkAction($model::ACTION_REDIRECT)): ?> <?= $form->field($model, 'url_to') ?> <?php endif; ?> <?= $form->field($model, 'http_code') ?> <button type="submit"</button> <?php ActiveForm::end() ?>
文件 index.php
<?= GridView::widget([ 'dataProvider' => $dataProvider, 'filterModel' => $model, 'columns' => [ [ 'attribute' => 'path', 'format' => 'raw', 'value' => function ($model) { /** @var UrlRoute $model */ return Html::a($model->path, ['update', 'id' => $model->id], ['data-pjax' => 0]); } ], [ 'attribute' => 'object_key', 'filter' => $model::getObjectItems(), 'value' => function ($model) { /** @var UrlRoute $model */ return $model->getObject(); }, 'visible' => array_search($action, [UrlRoute::ACTION_INDEX, UrlRoute::ACTION_VIEW]) !== false ], [ 'attribute' => 'object_id', 'visible' => array_search($action, [UrlRoute::ACTION_INDEX, UrlRoute::ACTION_VIEW]) !== false ], [ 'attribute' => 'url_to', 'visible' => $action == UrlRoute::ACTION_REDIRECT ], [ 'attribute' => 'http_code', 'visible' => $action == UrlRoute::ACTION_REDIRECT ], [ 'class' => 'voskobovich\grid\advanced\columns\ActionColumn', 'template' => '{view} {update} {delete}', 'options' => [ 'width' => '160px' ], 'buttons' => [ 'view' => function ($url, $model, $key) { $options = [ 'title' => Yii::t('yii', 'View'), 'aria-label' => Yii::t('yii', 'View'), 'data-pjax' => '0', 'class' => 'btn btn-default btn-xs', 'target' => '_blank', ]; /** @var UrlRoute $model */ $url = $model->viewUrl(); return Html::a(Yii::t('yii', 'View'), $url, $options); } ] ], ], ]) ?>
安装
安装此扩展的最佳方式是通过 composer。
运行以下命令之一:
php composer.phar require --prefer-dist voskobovich/yii2-seo-toolkit "^1.0"
或将以下内容添加到您的 composer.json
文件的 require 部分中:
"voskobovich/yii2-seo-toolkit": "^1.0"
...