Tuesday, November 27, 2012

Re: Routes are confusing me

On Tue, Nov 27, 2012 at 10:16 AM, iFemke <femkevgemert@gmail.com> wrote:
> I'm working on the routes of my CakePHP site. The 'easy' ones I have already
> set like:
> Router::connect('/contact', array('controller' => 'contacts', 'action' =>
> 'index'));
> These are working.
>
> But now I am confused as to how to continue with the more complex routing.
> For example, my url now is /findproducts/compare/1, where he goes to the
> controller findproducts and the action compare and 1 is the category_id. I
> have converted this with my routes to /vinden/vergelijk/1 (dutch
> translations). How do I get the 1 to swap with the category name? So that
> you don't get /vinden/vergelijken/1 but /vinden/vergelijken/food for
> example. Do I have to change all my html links for that? So that my
> controller doens't have the action "public function compare($id = null)"
> but "public function compare($categoryname = null)"? I hope not, because
> that would be a lot of work..


To use the Category name in the route you should take a look at
SluggableBehavior. What this does is create a new field based on the
name that is usable in a URL. eg. translates spaces to hyphens,
accented chars to ASCII, lowercase everything, etc. This occurs when
the record is saved. For existing records you can either create the
slugs yourself or edit each Category to re-save the record.

For a Category model I'm working on now, I'm using both Sluggable and Sortable:

public $actsAs = array(
'Sluggable' => array(
'translation' => 'utf-8',
'separator' => '-',
'label' => 'name',
'length' => 64,
'overwrite' => true
),
'Sortable' => array(
'orderField' => 'sort_order'
)
);

To use the slug in a route is fairly simple, but you need to keep in
mind what other potential routes may arise, so positioning in
routes.php can be important.

Router::connect(
'/findproducts/compare/:slug',
array(
'admin' => 1,
'controller' => 'findproducts',
'action' => 'compare'
),
array(
'slug' => '[-0-9a-z]+',
'pass' => array('slug')
)
);

Your method will then be:

public function compare($slug = null) {}

The you can pass the slug to your model methods and use a condition
$this->alias.slug => $slug

I prefer to use the id for admin methods, though:

Router::connect(
'/admin/categories/edit/:id',
array(
'admin' => 1,
'controller' => 'categories',
'action' => 'edit'
),
array(
'id' => '[0-9]+',
'pass' => array('id')
)
);


To create links is simple. Always fetch the slug when doing a find().
Then you can pass it to Html::link() like this:

foreach ($data as $d) {
echo $this->Html->link(
$d['Category']['name'],
array(
'controller' => 'findproducts',
'action' => 'compare',
'slug' => $d['Category']['slug']
),
array(
'title' => __('compare: ') . $d['Category']['name'],
'escape' => false
)
);
}

--
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com.
To unsubscribe from this group, send email to cake-php+unsubscribe@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php?hl=en.

No comments: