半米/SEO

用于处理模型SEO参数的库

安装次数: 1,519

依赖关系: 0

建议者: 0

安全: 0

星标: 13

关注者: 7

分支: 4

开放问题: 0

类型:yii2-extension

1.2.2 2020-06-26 11:49 UTC

This package is auto-updated.

Last update: 2024-09-26 20:52:22 UTC


README

用于处理模型SEO参数的库

工作原理

您需要在模型中添加2个字段

  • seo_url VARCHAR: 这是唯一的模型名称,例如:http://example.com/post/<seo_url>
  • seo_meta TEXT: 这是一个序列化数组:['title' => 'Post title', 'desc' => 'Post description', 'keys' => 'Post title, other keywords...']

此行为可以帮助您

  • 从模型标题生成seo_url,考虑您的唯一条件。
  • seo_meta的国际化。
  • 通过简单的调用$model->viewUrl获取模型视图URL。 (返回相对URL /post/my-first,甚至可以是/cat1/cat2/awesome-post).
  • 将模型SEO字段(国际化)输出到HTML:<title><meta name="description"><meta name="keywords">
  • seo_url和所有seo_meta以及国际化字段(如有必要)提供表单字段。
  • 您可以(必须)配置seo_meta字段生成器,例如:关键字是:<postTitle>, key1, key2, <postTags>, ...

一些情况的生成seo_url示例

  • http://example.com/first-category/awesome-post - post1, cat1, seo_urlawesome-post
  • http://example.com/other-category/awesome-post - post2, cat2, seo_urlawesome-post也是可能的
  • http://example.com/first-category/awesome-post_ - post3, cat1, seo_urlawesome-post_(如果帖子类别中已使用名称,则在末尾添加下划线)

安装

运行

composer require "demi/seo" "~1.0"

配置

每个视图都应能够访问demi\seo\SeoViewBehavior方法。因此,配置/frontend/config/main.php

return [
    'components' => [
        'view' => [
            'as seo' => [
                'class' => 'demi\seo\SeoViewBehavior',
                // options by default:
                'titleTemplate' => '{title} - {appName}',
                'descriptionTemplate' => '{description}',
                'keywordsTemplate' => '{keywords}',
            ]
        ],
    ],
];

在模型文件中添加SEO模型行为

<?php

public function behaviors()
{
    return [
        'seo' => [
            'class' => 'demi\seo\SeoModelBehavior',
            'seoConfig' => [
                'urlField' => 'seo_url',
                'metaField' => 'seo_meta',
                // attribute name or anonymous function
                'urlProduceField' => 'title',
                // attribute name or anonymous function
                'titleProduceFunc' => 'title',
                // attribute name or anonymous function
                'descriptionProduceFunc' => 'short_desc',
                // attribute name or anonymous function
                'keysProduceFunc' => static function (self $model) {
                    return $model->title . ', tag1, tag2';
                },
                // when user can manage model seo-fields (anonymous function possible) 
                'clientChange' => Yii::$app->has('user') && Yii::$app->user->can(User::ROLE_ADMIN),
                // param for Url::to(<viewRoute>)
                'viewRoute' => '/post/view',
                // param for Url::to(<viewRoute>, ['title' => $model->seo_url])
                'linkTitleParamName' => 'title',
                // only anon-function returns array of additional link params with values
                'additionalLinkParams' => static function (self $model) {
                    // Url::to(<viewRoute>, ['title' => $model->seo_url, 'category' => $model->category->seo_url])
                    return ['category' => $model->category->seo_url];
                },
                // if you model have some unique condition
                'uniqueUrlFilter' => function (\yii\db\ActiveQuery $query) {
                    $query->andWhere(['category_id' => $this->category_id]);
                },
                // if array - seo_meta will have possible to internationalization 
                'languages' => 'en',
                // Optional. All controller actions will added to stop-list for seo_url value.
                // For example: if you create model with seo_url = 'delete' you can't open model by url '/post/delete',
                // if this option enabled, then seo_url will be 'delete_' and url: '/post/delete_' 
                'controllerClassName' => '\frontend\controllers\PostController',
                // @see [\demi\seo\SeoModelBehavior] for more properties
            ],
        ],
    ];
}

模型PHPdoc

/**
 * @property-read  array $seoData
 * @method array getSeoData($lang = null) Metadata for this model
 * @method \demi\seo\SeoModelBehavior getSeoBehavior()
 * @property-read array $viewUrl
 * @method array getViewUrl() URL to material view page
 * @property-read  array $absoluteViewUrl
 * @method array getAbsoluteViewUrl() Absolute URL to material view page
 */

更改/frontend/views/layouts/main.php

<?php
/* @var $this \yii\web\View|\demi\seo\SeoViewBehavior */
?>
<head>
    <!-- Replace default <title> tag -->    
    <title><?= Html::encode($this->title) ?></title>
    <!-- by this line: -->    
    <?php $this->renderMetaTags(); ?>
    ...
</head>

用法

在模型的“view.php”文件中

// set SEO:meta data for current page
$this->setSeoData($model->getSeoBehavior());

// Helper: set <link> tag for "no index" (and optional "no follow") for current page
$this->noIndex($and_no_follow_bool);

或在控制器中

Yii::$app->view->setSeoData($model->getSeoBehavior());
Yii::$app->view->noIndex($and_no_follow_bool);

在'/frontend/config/main.php'中的简单URL规则示例

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
        'post/<action:(index|create|update|delete)>' => 'post/<action>',
        'post/<title:[-\w]+>' => 'post/view',
    ],
],

并更改/frontend/controllers/PostController.php

public function actionView($title)
{
    $model = Post::find()->where(['seo_url' => $title])->one();
    if (!$model) {
        throw new NotFoundHttpException('Post not found');
    }

    return $this->render('view', [
        'model' => $model,
    ]);
}

// And in actionCreate() and actionUpdate() change
return $this->redirect(['view', 'id' => $model->id]);
// to
return $this->redirect($model->viewUrl);

根据行为配置值viewRouteadditionalLinkParams获取模型视图页面的链接

// return url to material view page: '/post/super-post'
$url = $model->getViewUrl();
$url = $model->viewUrl;

// return absolute url to material view page: 'http://example.com/post/super-post'
$abs_url = $model->getAbsoluteViewUrl();
$abs_url = $model->absoluteViewUrl;

// Behind scene (for understanding):
return Url::to([$viewRoute, ['title' => $model->$titleField] + $additionalLinkParams]], $isAbsolute);

在“/frontend/views/post/_form.php”文件中渲染SEO:url和SEO:meta字段

<?php
/* @var $model common\models\Post|demi\seo\SeoModelBehavior */
?>
...
<?php $model->renderFormSeoFields($ActiveForm_or_void); ?>