Problème de Slash dans Cake 3

Par Daniel68, il y a 10 ans


Bonsoir à tous,

Je suis en train de tester rapidement cakePHP 3, et je me retrouve confronté à un problème de slash que je n'arrive pas à résoudre.

// Model/Entity/Post.php public function _getUrl() { $title = Inflector::slug($this->title); return ['action' => 'view', ($this->id.'/'.$title)]; } //Template/Posts/index.ctp $this->Html->link(h($post->title), $post->url);

Pour une raison que j'ignore lorsque je debug $post->url aucun problème l'url est comme je souhaite. Mais dès que je la passe dans le link le slash se transforme en %2F.

Une idée ?
Merci de votre aide

11 réponses

Lartak, il y a 10 ans

Bonjour.
Il faut utiliser le routing pour faire la ré-écriture d'url.
De la manière que tu fais, le slash est utilisé comme un caractère lambda et non comme un séparateur dans l'url.

Daniel68, il y a 10 ans

Merci pour ta réponse si rapide.
J'utilise le routing pour réécrire mes URL.
Mais la je souhaite pouvoir créer une fonction qui me renvoi l'url en tant qu'entité.
Le problème me semble plutôt venir du link, parce que si dans ma vue je place directement mon array j'ai le même problème.
Il doit y'avoir une option dans le link pour spécifier que je ne souhaite pas la convertion html, mais je ne trouve pas.
A moins que tu veuilles dire que directement dans ma fonction _getURL j'utilise Routter:: ?

Lartak, il y a 10 ans

Le helper Link, tout comme le helper Url, utilisent le routing, donc, dans ta fonction _getUrl, il faut que tu mettes ceci par exemple :

return ['action' => 'view', 'id' => $this->id, 'slug' => $title];

Puis dans ton routing :

$routes->connect('/post/:id/:slug', ['controller' => 'Posts', 'action' => 'view'], [ 'pass' => ['id', 'slug'], 'id' => '[0-9]+', 'slug' => '[a-z\-]+' ]);

Si tu ne fais pas ça, les helpers concernés ne pourront pas interpréter tes url.
Par contre, vu que tu ne mets pas le nom du controller, tu ne pourras pas utiliser en dehors de tes vues du controller Posts.

Daniel68, il y a 10 ans

Merci pour ton aide.
Même en fesant cela ça ne marche pas.
Dans routes.php j'ai créé un scope pour repasser les posts en /blog.
Puis dedans j'ai donc connecté ma route comme tu me l'as dit (je l'avais déjà fait avant).
J'ai donc juste modifié ma fonction _getUrl().
Le problème c'est qu'il ne réécrit pas mes urls lorsque je lance la fonction dans ma vue index.ctp
Il retourne : /posts/view?id=1?title=test
Au lieu de : /blog/1/title
Pourtant l'index est bien accessible depuis /blog/

Lartak, il y a 10 ans

Montres le code du routing correspondant au blog s'il te plaît.

Le problème c'est qu'il ne réécrit pas mes urls lorsque je lance la fonction dans ma vue index.ctp

Ce n'est pas ta fonction _getUrl qui va faire la ré-écriture d'url, mais la méthode Link du Helper Html ou le Helper Url.

Daniel68, il y a 10 ans

Merci infiniment pour toute ton aide.
Voici le code de mon fichier routes.php (uniquement pour le blog)

Router::scope('/blog', function($routes) { $routes->connect('/category/:category', ['controller' => 'Posts', 'action' => 'index', 'category' => '[a-z\-]+']); $routes->connect('/', ['controller' => 'Posts', 'action' => 'index']); $routes->connect('/:id/:title', ['controller' => 'Posts', 'action' => 'view'], ['id' => '\d+', 'title' => '[a-z\-]+', 'pass' => ['id', 'title']]); });
Lartak, il y a 10 ans

Et si tu remplaces :

'id' => '\d+'

Par :

'id' => '[0-9]+'

?

Daniel68, il y a 10 ans

Non ça ne change rien (y'a pas de raison...)

Lartak, il y a 10 ans

Donc, la sortie de ta fonction _getUrl, c'est bien :

return ['action' => 'view', 'id' => $this->id, 'title' => $title];

?

Daniel68, il y a 10 ans

C'est:

public function _getUrl() { $title = Inflector::slug($this->title); return ['controller' => 'Posts', 'action' => 'view', 'id' => $this->id, 'title' => $title]; }
Daniel68, il y a 10 ans

Je viens de comprendre mon problème.
Dans ma fonction _getUrl j'ai passé les params dans le premier tableau, alors que dans mes routes j'en ai spécifié 2.
Il faut donc mettre dans routes.php:

$routes->connect('/:id/:title', ['controller' => 'Posts', 'action' => 'view', 'id' => '\d+', 'title' => '[a-z\-]+'], [ 'pass' => ['id', 'title']]); });

A présent tout est ok.
En tout cas merci Lartak pour tout le temps que tu as passé à m'aider.