SEO-friendly links with ActiveRecord?


I’m keeping some articles in table like id | title | content. Assuming the title is unique, how can I display an article when given only url-formatted title, not the ID? Should I keep the generated url-friendly title in DB as well?

The formatting doesn’t only remove standard special characters but regional symbols as well …



Yes. Let’s assume the titles are not unique. Than you couldn’t make sure to find the correct article. Also you said that characters are stripped off, that means it can happend that 2 marginal different titles become the same url-friendly title (so called slug).

I suggest to create a “slug” field that holds the url-friendly title. When you want to support non-unique titles, you can check if the slug is already in the db. If that’s the case you just append a “2” (or a “3” and so on if that slug is also taken) to the new slug. You can do all this in beforeSave() method of ActiveRecord.

// A more advanced way would be a single database table for all user-friendly url’s. Because when you change a title, of course the url-friendly title should change as well. But what if your article is linked somewhere? The link wouldn’t work anymore. So you could save those “old” slugs and redirect permanently to the new slug.

Good point! Thank you very much!

May I ask if there’s some Yii function for normalizing url input? Like replacing spaces with “-”, removing special entities and so on?

So far I used to work with Kohana which had this kind of function ;)

Yes, I know it’s easy to write my own, however I’d like to know if it is included in framework?

No not included, you have to write the function yourself.

You can also make urls like:, where 1845 is an article’s id. So there won’t be collisions.

how to easily do that?

a url rule will be smth like that:

'<id:\d+>-<slug:[\w\d\-]+>'=>array('controller/action', 'htmlSuffix'=>'.html')

hope this works

But why I get ‘+’ instead of space? Can I change ‘+’ to ‘-’?

You should avoid using spaces in urls. Replace them with php’s str_replace() function before inserting into DB.