2012-11-21 1 views
1

URL lisibles par l'utilisateur avec des catégories imbriquées comme/category/sous-catégorie/n-sous-catégories/article. J'utilise CakePHP 2.2.3 et je ne trouve pas de solution appropriée pour un problème de routage. En utilisant 2 tableaux:Itinéraires SEO pour les catégories imbriquées avec paginateur et articles

  • articles (pourrait aussi être produits ou messages ou ...)
    • ont juste une vue normale "unique"
    • un article appartient à une catégorie
  • catégories
    • imbriquée (comportement Arbre à n niveaux)
    • une catégorie peut avoir de nombreux articles
    • listes catégorie Voir tous les articles, qui sont liés à cette catégorie
    • vue catégorie utilise paginator pour montrer l'article répertorie

Un exemple très courant I deviner. Mais comment dois-je définir le routeur maintenant, pour obtenir des chemins-URL avec les catégories imbriquées comme celui-ci:

/categoryname1           (showing category view) 
/categoryname1/articlename1       (showing article view) 
/categoryname2/articlename2       (showing article view) 
/categoryname2/subcategoryname1      (showing category view) 
/categoryname2/subcategoryname2/articlename4   (showing article view) 
/n-categoryname/././...n-subcategoryname    (showing category view) 
/n-categoryname/././...n-subcategoryname/n-articlename   (article view) 

j'ai essayé de faire tous les itinéraires fixer dans le routes.php, mais ce n'est pas très confortable et Je pense qu'il devrait y avoir une solution dynamique. J'ai également essayé de générer automatiquement toutes les routes hors catégorie et article-alias et les enregistrer dans une table de base de données "itinéraires" séparée - cela a fonctionné, mais je ne pense pas qu'il est vraiment nécessaire de définir des hunderets de routes simples ?!

J'ai aussi essayé simplement de définir toutes les catégories fixer dans le routeur, comme

Router::connect(
    '/any-category-name', 
    array('controller' => 'categories', 'action' => 'view', 1) 
); 

et pour les articles

Router::connect(
    '/any-category-name/:slug', 
    array('controller' => 'articles', 'action' => 'view'), 
    array('pass' => array('slug')) 
); 

Mais avec cette méthode, tous les articles sont disponibles dans toutes les catégories, ce qui n'est pas une bonne solution. Et je pensais à l'aide

Router::connect(
    '/:slug', ... 

mais je ne sais pas comment continuer, parce qu'il ya deux contrôleurs et deux points de vue différents différentes possibles (aussi je ne sais pas si Pagination continue de fonctionner dans ce cas et que se passera-t-il, si je veux aussi utiliser plus de contrôleurs/actions dans l'installation).

Je pense qu'il ne devrait pas être si difficile d'obtenir des URL imbriquées avec deux contrôleurs (catégories et articles) dans Cake ?! Merci pour tout conseil utile!

Répondre

0

Je pense que vous devez vérifier deux choses:

1) Vérifiez le nombre de catégories dans l'URL et
2) Vérifiez si le dernier paramètre est une catégorie ou un article

poignée à la fois les contrôles dans un itinéraire (dynamique) peuvent être très difficiles.Je suggère de créer un seul chemin pour toutes ces demandes et faire les vérifications pour 1) et 2) dans un contrôleur.

L'itinéraire peut être quelque chose comme ceci:

Router::connect(
    '/*', 
    array('controller' => 'outputs', 'action' => 'index') 
); 

J'ai appelé le contrôleur pour cet itinéraire OutputController parce que ce sera le contrôleur qui gère la sortie pour tous ces urls.

class OutputController extends AppController 
{ 
    public $uses = array('Article', 'Category'); 

    public function index() 
    { 
    // Get n parameters from url (1) 
    $args = func_get_args(); 
    $last_arg = $args[count($args) - 1]; 

    // Check if this is an article (2) 
    $article = $this->Article->find('first', array(
     'conditions' => array('Article.slug' => $last_arg 
    )); 
    if (!empty($article)) { 
     $this->set('article', $article); 
     $this->render('article'); 
    } 

    // Check if this is an category (2) 
    $category = $this->Category->find('first', array(
     'conditions' => array('Category.slug' => $last_arg 
    )); 
    if (!empty($category)) { 
     $this->set('category', $category); 
     $this->render('category'); 
    } 

    // Page not found 
    if (empty($article) and empty($category)) { 
     throw new NotFoundException(); 
    } 
    } 

    // ... 

Pour afficher un article, la vue 'Output/article.ctp' est utilisée. Pour une catégorie, CakePHP rend 'Output/category.ctp'. De plus, vous pouvez utiliser les paramètres de $ args pour récupérer toutes les données nécessaires pour vos (sous-) catégories.

+0

Merci beaucoup, je vais devoir essayer de cette façon, mais ça me semble être une bonne solution. Je pense que Category-Slug et Article-Slug doivent être uniques pour que cela fonctionne, mais c'est aussi nécessaire si je stocke des Routes dans une table de base de données ... Merci! –

Questions connexes