自动设置一个slug

在web中,slug是一个用于URL中的短文本,用来标识和描述一个资源。slug是URL的一部分,它使用可读的关键词标定一个网页。Sluggable行为是Yii2模型行为,它能为我们生成唯一的slugs。

在本节中,我们将会指导你修改Yii默认URL,修改成一个用户友好和搜索引擎友好的格式。Yii通过一个sluggable行为为这个提供内置支持。

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
  2. 设置数据库连接,并创建一个名为blog_post的表:
  1. DROP TABLE IF EXISTS 'blog_post';
  2. CREATE TABLE IF NOT EXISTS 'blog_post' (
  3. 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4. 'title' VARCHAR(255) NOT NULL,
  5. 'slug' VARCHAR(255) NOT NULL,
  6. 'text' TEXT NOT NULL,
  7. PRIMARY KEY ('id')
  8. );
  1. 使用Gii为帖子表创建一个模型。

如何做…

  1. models/BlogPost.php添加如下behaviors方法:
  1. <?php
  2. namespace app\models;
  3. use Yii;
  4. use yii\db\BaseActiveRecord;
  5. class BlogPost extends \yii\db\ActiveRecord
  6. {
  7. // ..
  8. public function behaviors()
  9. {
  10. return [
  11. [
  12. 'class' => 'yii\behaviors\SluggableBehavior',
  13. 'attribute' => 'title',
  14. 'slugAttribute' => 'slug',
  15. 'immutable'=> false,
  16. 'ensureUnique' => true
  17. ]
  18. ];
  19. }
  20. // ..
  21. }
  1. 创建controllers/TestController.php
  1. <?php
  2. namespace app\controllers;
  3. use app\models\BlogPost;
  4. use Yii;
  5. use yii\helpers\Html;
  6. use yii\helpers\VarDumper;
  7. use yii\web\Controller;
  8. /**
  9. * Class TestController
  10. * @package app\controllers
  11. */
  12. class TestController extends Controller
  13. {
  14. public function actionIndex()
  15. {
  16. $blogPostA = new BlogPost();
  17. $blogPostA->title = 'Super Quote title 1';
  18. $blogPostA->text = 'The price of success is hard work, dedication to the job at hand';
  19. $blogPostA->save();
  20. $blogPostB = new BlogPost();
  21. $blogPostB->title = 'Super Quote title 2';
  22. $blogPostB->text = 'Happiness lies in the joy of achievement...';
  23. $blogPostB->save();
  24. return $this->renderContent(
  25. '<pre>' .
  26. VarDumper::dumpAsString(
  27. $blogPostA->attributes
  28. ).
  29. VarDumper::dumpAsString(
  30. $blogPostB->attributes
  31. ) .
  32. '</pre>'
  33. );
  34. }
  35. }
  1. 结果如下:

自动设置一个slug - 图1

工作原理…

  • Yii为SluggableBehavior提供了一些友好的增强功能。
  • 例如,一旦一个搜索引擎记录了一个slug,你不要再修改页面的URL。
  • 不可变的属性告诉Yii在首次创建后保持slug不变——尽管标题被修改了。
  • 如果用户输入消息覆盖了内容,ensureUnique属性将会自动附加一个唯一的后缀到复件中。这保证了每一个消息都有一个唯一的URL,即时是消息是唯一的。
  • 如果你创建了另一个帖子,和之前有相同的内容,你将会看到它的slug自动增加为hot-update-for-ios-devices-2。

注意

注意:如果你收到了一个关于这个不可变属性的错误,也许是因为你需要运行Composer来更新你的Yii到最新版本。

更多…

  1. 使用Gii为模型app\models\Post生成CRUD和控制器app\controllers\BlogPostController
  2. 添加如下动作到app\controllers\BlogPostController
  1. /**
  2. * @param $slug
  3. *
  4. * @return string
  5. * @throws NotFoundHttpException
  6. */
  7. public function actionSlug($slug)
  8. {
  9. $model = BlogPost::findOne(['slug'=>$slug]);
  10. if ($model === null) {
  11. throw new NotFoundHttpException('The requested page does not exist.');
  12. }
  13. return $this->render('view', [
  14. 'model' => $model,
  15. ]);
  16. }
  1. 如果你使用slug值sluggablebehavior-test运行blogpost/slug,你将会得到如下结果:

自动设置一个slug - 图2

  1. 建议使用一个Post模型的实例完成先前的slug小节。
  2. 为了美化URL,在config/web.php中添加如下urlManager组件:
  1. //..
  2. 'urlManager' => [
  3. 'enablePrettyUrl' => true,
  4. 'rules' => [
  5. 'blog-post' => 'blog-post/index',
  6. 'blog-post/index' => 'blog-post/index',
  7. 'blog-post/create' => 'blog-post/create',
  8. 'blog-post/view/<id:\d+>' => 'blog-post/view',
  9. 'blog-post/update/<id:\d+>' => 'blog-post/update',
  10. 'blog-post/delete/<id:\d+>' => 'blog-post/delete',
  11. 'blog-post/<slug>' => 'blog-post/slug',
  12. 'defaultRoute' => '/site/index',
  13. ],
  14. ]
  15. //..
  1. 注意blog-post/<slug>' => 'blog-post/slug规则。
  2. 如果你使用你的slug URL访问网页,例如index.php/blog-post/super-quote-title-1/,你将会得到类似步骤3中的结果:

自动设置一个slug - 图3

参考

欲了解更多信息,参考: