This is a simple behavior component.
Installation ¶
Unpack the package and place at /protected/components
Usage ¶
In the model where you'd want to use, declare this behavior via its behvaiors() method, as follows:
public function behaviors() {
return array(
'slugmaker' => array(
'class' => 'PcSimpleSlugBehavior',
// 'sourceIdAttr' => the 'id' attribute name in this model. Default value = 'id'
// 'sourceStringPrepareMethod' => If defined, will be used to get the base slug string text. Use it if you need some small manipulation of data in the model object in order to 'get' the base slug string. For example, if you need to concatenate 'first_name' and 'last_name' fields together.
// 'sourceStringAttr' => the 'main string attribute' from which the slug will be built. Typically 'title', which is the default as well.
// 'maxChars' => Maximum allowed slug total length. resulted slug will be trimmed to this value if longer than this value (*with* the prepended 'id-'...)
// 'avoidIdPrefixing' => Setting this to true (default = false) will enable you to generate and parse URLs without the ID of the model record. WARNING: you need to carefully think before choosing this method as if not well thought, it could be used in an environment where there could be two or more records with same slug!
)
);
}
Then, in the code you can do as follows:
// the following will generat the slug for you:
$model->generateUniqueSlug()
// get id of article from slug
$dummy = MyModel::model();
$id = $dummy->getIdFromSlug($slug_fetched_from_url);
$my_model_obj = MyModel::model()->findByPk($id);
Resources ¶
Change Log ¶
- v1.6 20 March 2012: Added support for 'id-less' slugs. Use with caution! (see comment above)
- v1.5 20 March 2012: Please ignore this version.
- v1.4 16 Aug 2012: bug fix: fixed support for 'base slug generation' (in model class).
- v1.3 12 Aug 2012: Added attribute sourceStringPrepareMethod. See documentation above on how to use it.
- v1.2 7 Aug 2012:
- added createBaseSlug() which is good for creating non-primary-key related slugs. For example, if you want to slug'ify a parameter in the middle of the URL.
- Fixed the lower-casing to handle all strings as UTF8 - mb_strtolower() on an string that contains umlaut within created a bug...
- v1.1 17 July 2012: Added 'lowercaseUrl' option that will makes the created slug all lowercase (MB safe).
How to use "getIdFromSlug"
Hi,
Very useful extension.
But I unable to get attribute "id" via "getIdFromSlug" when 'avoidIdPrefixing' => true;
Please help me...
How to use "getIdFromSlug"
Ya I got it from souce
$id = $dummy->getIdFromSlug($slug_fetched_from_url,**false**);
urlManager rule
Hey, thank you very much for the extension. However, do you have an example of a urlManager rule to make it all work and modify the displayed URL ? Thank you!
@tehmaestro
Yes. Here's an example.
The URL rule in config/main.php:
// edu/schools/<some-nice-slug> is the cool URL. It is mapped to education // 'module' (education is the id of the module. the module class name can be // different), SchoolController controller class, and actionView method in it. 'edu/schools/<slug:.+>' => 'education/school/view',
The actionView method will look as follows (its a real but slightly altered working method):
public function actionView($slug) { $dummy = School::model(); // get id of school from slug $id = $dummy->getIdFromSlug($slug); /* @var School $model */ $model = School::model()->findByPk((int)$id); if ($model === null) { Yii::log("School view requested with slug = $slug but no such school found!", CLogger::LEVEL_INFO, __METHOD__); throw new CHttpException(404, Yii::t("EducationModule.general", 'The requested page does not exist.')); } }
@Boaz
Thank you very much. I managed to figure out the actionView function myself. I'm trying to built a multi language website, so I did some modifications to your script. I needed for it to be able to look into relations, so:
New config parameter "relation". In the model:
public $name; .... ..... 'relation' => 'categoryLang', 'sourceStringAttr' => 'name',
So, in your script, I checked for the relation, which defaults to false:
$relation = false; .... if($this->relation) $this->slug = $this->createBaseSlug($this->owner->{$this->relation}->{$this->sourceStringAttr}); else $this->slug = $this->createBaseSlug($this->owner->{$this->sourceStringAttr});
In order to be able to generate a slug, I found that "hasAttribute" checks whether a model has the attribute column in the database .. which would have failed, because my column is in my relation table categoryLang. So I used :
if (!property_exists($this->owner, $this->sourceStringAttr)) { throw new CException ("requested to prepare a slug for " . get_class($this->owner) . " (id=" . $this->owner->getPrimaryKey() . ") but this model doesn't have an attribute named " . $this->sourceStringAttr . " from which I'm supposed to create the slug. Don't know how to continue. Please fix it!" ); }
I know this might not be perfect but it works. I used this language behavior http://www.yiiframework.com/extension/yii-language-behavior/ , so that's why I need another table, categoryLang, which holds all my language versions of "name", and will hold all the "slug" versions.
Thank you very much, once again.
@tehmaestro
Thanks for sharing.
How to use in create action?
How to use in create action?
not have a primary key value
how to get the primary key before save?
$model->slug = $model->generateUniqueSlug(); if ($model->save()){ }
@Programmer Thailand
You do not have to save the slug in the model. Why should you? Instead, consider:
if ($model->save()) { $this->redirect(array("view", "slug" => $model->generateUniqueSlug())); }
How to use extension?
I have url : http://localhost/yiiLuarpulau/master/jam-kerja
note:
master : module
How do I refer to "jam-kerja" to go to a particular controller "jamkerja".
thanks..
@masdib.banget
I'm not sure I understood you fully but in any case, I think your question is more a general question about clean URLs. Please see this part of the guide for more information. I also advise to ask such questions in the relevant forum.
If the question is still relevant for this extension then please rephrase and I'll do my best to answer here.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.