Different levels of URL with CakePHP routes

老子叫甜甜 提交于 2019-12-06 10:48:44

I used that approach in the web application farm.ba (not more maintained by the owner).

What I did:

  • Create table "nodes" with fields id, slug, model, foreign_key, type, ..
  • Create custom route (1),(2) class that handles Node model
  • After save post, store and cache slug in Node Model
  • After deleting the post, delete the cache and node records

This works much like wordpress routing, allows you to enter custom slug, etc.

EDIT:

Create custom route class in App/Lib/Routing/Router/MultiRoute.php like:

<?php
App::uses('CakeRoute', 'Routing/Route');
/**
* MultiRoute
*/
class MultiRoute extends CakeRoute
{

    public function parse($url)
    {
        // debug($url); '/florida/abc/people/add'

        // Add custom params
        $params = array(
            'location' => null,
            'company' => null,
            'controller' => 'peoples',
        );

        $params += parent::parse($url);
        // debug($params);
        /** 
         * array(
         *  'location' => null,
         *  'company' => null,
         *  'controller' => 'peoples',
         *  'named' => array(),
         *  'pass' => array(
         *      (int) 0 => 'florida', // location
         *      (int) 1 => 'abc', //company
         *      (int) 2 => 'people', // controller
         *      (int) 3 => 'add' // action, default index
         *  ),
         *  'action' => 'index',
         *  'plugin' => null
         * )
         * 
         */

        // reverse passed params
        $pass = array_reverse($params['pass']);
        // debug($pass);
        /**
         *  array(
         *      (int) 0 => 'add',
         *      (int) 1 => 'people',
         *      (int) 2 => 'abc',
         *      (int) 3 => 'florida'
         *  )
         */

        if(isset($pass[3])) { $params['location'] = $pass[3]; }
        if(isset($pass[2])) { $params['company'] = $pass[2]; }
        // if you need load model and find by slug, etc...
        return $params;
    }

    public  function match($url)
    {
        // implement your code
        $params = parent::match($url);
        return $params;
    }
}

in routes.php

App::uses('MultiRoute', 'Lib/Routing/Route');

Router::connect('/admin/*', 
    array('admin' => true),// we set controller name in MultiRoute class
    array('routeClass' => 'MultiRoute')
    );

Router::connect('/*', 
    array(),// we set controller name in MultiRoute class
    array('routeClass' => 'MultiRoute')
    );

In your controller find results using extra request params, like:

$this->request->location;
$this->request->company;

I hope this is helpful.

Creating a route for each case seems the way to go:

Router::connect('/people/add', array('controller' => 'people', 'action' => 'add'));
Router::connect('/:company/people/add', array('controller' => 'people', 'action' => 'add'), array('pass' => array('company'), 'company' => '[a-z]+'));
Router::connect('/:location/:company/people/add', array('controller' => 'people', 'action' => 'add'), array('pass' => array('company', 'location'), 'company' => '[a-z]+', 'location' => '[a-z]+'));

Then the controller can receive these values:

public function add($company = '', $location = '') {
    var_dump($company, $location); exit;
}

Mind the regex in routes and amend to match your incoming data.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!