2011-02-24 12 views
5

Estoy usando CakePHP 1.3. Tengo un modelo de Producto. en la tabla DB, entre otros, hay campos id y slug.CakePHP - ¿Cómo hacer el enrutamiento inverso con slug?

Si tengo un producto que es id:37 y slug:My-Product-Title Quiero la dirección URL para que el producto sea:

productos/37/Mi-Producto-Título

En lugar de la norma:

productos/view/37

creé una ruta que tiene este aspecto:

Router::connect(
    '/products/:id/:slug', 
    array('controller' => 'products', 'action' => 'view'), 
    array('pass' => array('id'), 'id' => '[0-9]+') 
); 

Ahora puedo ir a http://server/products/37/My-Product-Title y me lleva al lugar correcto.

¿Pero cómo obtengo el enrutamiento inverso para construir automáticamente la URL correcta en $HtmlHelper->link?

Cuando uso:

echo $html->link(
    'Product 37', 
    array('controller'=>'products', 'action' => 'view', 37) 
); 

Todavía emite la norma products/view/37 url.

+0

Sé que esto no es directamente relevante, pero sugiero echar un vistazo a la sección sobre las babosas en el libro cakephp del pseudocodificador (http://www.pseudocoder.com/archives/free-cakephp-e- book-super-awesome-advanced-cakephp-tips) si no lo ha visto. – Tomba

Respuesta

5

No creo que se pueda hacer de manera auto-mágica. El ayudante es solo un "ayudante" que construye el enlace a partir de los parámetros dados.

lo tanto, el método más sencillo es añadir otro parámetro en su enlace de este modo:

echo $html->link(
    'Product 37', 
    array('controller'=>'products', 'action' => 'view', 37, $slug) 
); 

donde el $ slug es los datos del campo babosa.

Probablemente se podría hacer su idea, pero hay que romper el patrón MVC muy mal :)

Editar:

La lectura de su pregunta de nuevo lo entendí bien. Vea cómo se debe hacer:

en su router.php añadir la siguiente regla:

Router::connect(
    '/product/*', 
    array('controller' => 'products', 'action' => 'view') 
); 

Tenga en cuenta que es/producto/* en lugar de/productos/*

Su enlace se debe hacer de esta manera:

echo $html->link(
    'Product 37', 
    array('controller'=>'products', 'action' => 'view', 37, 'my-product-title') 
); 

y el vínculo se vería así:

http://yourdomain.com/product/37/my-product-title 

Para mí, hacer su sugerencia es una mala práctica. Además, no creo que sea bueno desde el punto de vista de SEO, redirigiendo siempre al usuario.

+0

Desafortunadamente, esto construye la URL como '/ products/view/37/my-product-title' No quiero la * vista * allí. Funciona si paso 'array ('controller' => 'products', 'action' => 37, 'my-product-title')' pero se siente mal. –

+0

He actualizado mi publicación. Échale un vistazo. –

0

Debería consultar la siguiente publicación sobre clases de rutas personalizadas.

Los datos slug no necesitan estar relacionados con la base de datos en absoluto: el campo es un campo falso utilizado para simplificar la lógica y las búsquedas. Esta solución le permite invertir babosas de ruta, sin necesidad de un campo de babosas en la tabla de modelos.

http://42pixels.com/blog/slugs-ugly-bugs-pretty-urls

+0

estuvo de acuerdo con usted en que si las URL están en el formato utilizado anteriormente, la babosa es solo para SEO. –

+0

Y es lo suficientemente flexible como para usarlo como base si desea un formato diferente. La cuestión es que una babosa siempre es un campo calculado y, como tal, no necesita almacenarse, ya que puede calcularse sobre la marcha. –

-1

No estoy seguro de lo malo que es, pero con el código siguiente en el ProductsController:

function view($id) 
{ 
    if(isset($_SERVER) && stristr($_SERVER["REQUEST_URI"],'view/')) 
    { 
     $this->Product->id = $id; 
     $slug = $this->Product->field('slug'); 
     $this->redirect($id.'/'.$slug); 
    } 
    $data = $this->Product->find('first', array('conditions' => array('Product.id' => $id))); 
    $this->set("data", $data); 
} 

Si la página está accesos a través de /view/id que las redirecciona automáticamente a la página actual mediante /id/slug

Ahora solo puedo usar el esquema de enlace predeterminado:

echo $html->link(
    'Product 37', 
    array('controller'=>'products', 'action' => 'view', 37) 
); 

y se les redirigirá a la dirección URL correcta.

El único problema es que no estoy seguro de lo malo que es tener una redirección cada vez que un usuario visita una página de producto?

3

Para enrutamiento:

Router::connect(
    '/products/:id/:slug', 
    array('controller' => 'products', 'action' => 'view'), 
    array('pass' => array('id'), 'id' => '[0-9]+') 
); 

Sus enlaces deben tener este aspecto:

echo $html->link(
    'Product 37', 
    array('controller'=>'products', 'action' => 'view', 'id' => 37, 'slug' => 'my-product-title') 
); 

Usted tiene que agregar adicional (clave => valor) a la matriz para cada uno: param en su enrutamiento . Entonces la magia funcionará

+0

En realidad, no estoy seguro de si esa es la respuesta a la pregunta, pero al menos es exactamente lo que estaba buscando =) ¡Gracias! – flo

Cuestiones relacionadas