CakePHP: Friendly urls using inflector and no id
I have built a simple portfolio using CakePHP and it has urls like: domain.com/portfolio/82/This_is_an_item
What I want to do is remove the ID from the url. How would I do this?
Here is my controller code for the view:
function view ( $id, $slug )
{
$post = $this->Portfolio->read(null, $id));
$this->set(compact('post'));
}
and here is the link generator:
<?php echo $this->Html->link($post['Portfolio']['title'],
array('admin' => false, 'controller' => '开发者_如何学JAVAportfolio', 'action' => 'view', $post['Portfolio']['id'], Inflector::slug($post['Portfolio']['title'])),
array('title' => $post['Portfolio']['title'])); ?>
I'm guessing I need to change the controller method to do some sort of find on the title?
Any help would be much appreciated. Thanks
I would save the slug in the database, along with the title. That way you only have to create it once. Also you may or may not be able to get a unique link from slug to title, so it's best not to try.
For easy processing you can use the Sluggable behaviour, see https://gist.github.com/338096 (or just Google).
Update
If you use the sluggable behaviour from https://gist.github.com/338096 (save as sluggable.php in app/model/behaviors), you would only need to do a few steps:
In your Profile model class add var $actsAs = array('Sluggable');
or
var $actsAs = array(
'Sluggable' => array(
'fields' => 'title',
'scope' => false,
'conditions' => false,
'slugfield' => 'slug',
'separator' => '-',
'overwrite' => false,
'length' => 256,
'lower' => true
)
);
if you want to override settings
In the database, add a column slug
in the profiles table.
When you save a profile, it will automagically add fill in the slug field, you do not need to take any special actions.
You can eliminate the id completely, but you'll have to make sure the slugs are unique (specify inUnique validation rule is a option). When saving the post, use Inflector::slug()
on the 'title' field (you might want to save it to a 'slug' field, if you want to keep the title intact:
$this->data['Portfolio']['slug'] = Inflector::slug($this->data['Portfolio']['title'])
function view ($slug ){ $post = $this->Portfolio->find('first', array('conditions'=>array('Portfolio.slug'=>$slug)))); $this->set(compact('post')); }
and for the link:
<?php echo $this->Html->link($post['Portfolio']['title'], array('admin' => false, 'controller' => 'portfolio', 'action' => 'view', $post['Portfolio']['slug']), array('title' => $post['Portfolio']['title']));
精彩评论