voskobovich/yii2-seo-toolkit

Yii2 的 SEO 工具

安装: 64

依赖: 0

建议者: 0

安全: 0

星标: 13

关注者: 5

分支: 4

开放问题: 0

类型:yii2-toolkit

v1.0.0 2016-01-28 10:19 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:20:41 UTC


README

帮助实现系统页面 URL 管理的自动化,类似于 CMS WordPress 的管理方式,可以通过管理面板中的路由表和重定向来管理。

License Latest Stable Version Latest Unstable Version Total Downloads

支持

GutHub 问题.

使用方法

  1. 创建用于存储路由的表(应用迁移)

  2. 创建自己的 UrlRoute 模型实例

  3. 配置 UrlManager

  4. 连接包中的 UrlManager 类

  5. 连接路由规则类
    3. ClearUrlRule 用于清除 URL 中的垃圾信息(双重斜杠、末尾斜杠...)
    3. UrlRule 直接负责路由

  6. 在必要的 AR 模型中

  7. 实现 SeoModelInterface 接口

  8. 连接 CreateUrlBehavior 行为

  9. 连接 ActualityUrlBehavior

  10. 创建用于管理路由的 CRUD

  11. 创建表(应用迁移)

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
  1. 创建自己的 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)。
这些操作是为了区分处理路由的逻辑。例如,我们可以这样做

  1. 路由 /foo 是对象 postindex 操作。最终,通过 /foo 我们将获得所有帖子的列表(在 Yii 路由中等于转到 post/index)。

  2. 路由 /bar 是对象 postview 操作,id=3。最终,通过 /bar 我们将看到 id=5 的记录(在 Yii 路由中等于转到 post/view)。
    可以通过在 getActionItems 方法中添加到列表来扩展操作列表。

  3. 配置 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 规则会

  1. 将多个斜杠替换为一个
  2. 删除链接末尾的斜杠
  3. 将大写字母转换为小写

注意! 为了优化,建议在您的 Web 服务器级别配置这些规则。

UrlRule 负责我们的神奇路由。
modelClass 属性中传递之前创建的 UrlRoute 模型。

  1. 配置 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 模型对象。

  1. 连接 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 模型类和常量中的对象名称。

  1. 创建用于管理路由的 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"

...