I would like to have URLs like
http://localhost/staticcontroller/dynamic-actions-with-hypens
In version 3.0.x I could extend Kohana_Request to achieve desired result
request.php
<?php defined('SYSPATH') or die('No direct script access.');
class Request extends Kohana_Request
{
public function execute()
{
$this->action = str_replace('-', '_', $this->action);
return parent::execute();
}
}
How could I achieve same result with Kohana version 3.1 ?
Is lambda routes solution for this? Is there a good example how to do this?
One working solution is:
route.php
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Route extends Kohana_Route
{
public function matches($uri)
{
$matches = parent::matches($uri);
if (isset($matches['action']))
{
$matches['action'] = str_replace('-', '_', $matches['action']);
}
return $matches;
}
}
But is there better way to do this?
I use this..
class Request extends Kohana_Request
{
public function __construct($uri)
{
parent::__construct($uri);
$this->_controller = str_replace('-', '_', $this->_controller);
$this->_action = str_replace('-', '_', $this->_action);
}
}
Dynamic actions? What does that mean?
If the actions come from a database you can fetch them and create routes for those actions.
foreach($model->actions() as $action)
{
Route::set('hypens-'.$action,'staticcontroller/'.$action)
->defaults(array(
'controller'=>'staticcontroller',
'action'=>str_replace('-','_',$action),
));
}
@xwero I meant that action-part of uri is changing and the controller part stays static
eg.
http://localhost/ctrl/differentaction
http://localhost/ctrl/someaction
http://localhost/ctrl/anotheraction
@nickobrien Wouldn't it be better extend Kohana_Route than Kohana_Request ?
The reason I asked is when I see dynamic I think variables, fetched from elsewhere, generated.
I think your getting too soon in the 'extend framework' mindset while the framework has a solution for this problem, routes. You suggested it's only for that controller so you let the exception become the rule.
Can you give a real world example of the actions you use hypens in. I'm wondering if you couldn't write them as action/parameter.
@samsoir I'll ensure that there isn't double content via 301 Moved Permanently -redirects.
Can you give a real world example of the actions you use hypens in. I'm wondering if you couldn't write them as action/parameter.
I'm quite sure this is possible to route with lambda routes, I just don't know how to do it.
Here's example...
Route
Route::set('test', 'test/<action>', array(
'action' => '([a-z\-]+)',
))
->defaults(array(
'controller' => 'test',
'action' => 'method_one',
));
Controller
class Controller_Test extends Controller {
public function action_method_one()
{
/* ... */
}
public function action_method_two()
{
/* ... */
}
public function action_method_three()
{
/* ... */
}
}
URLs
http://localhost/test/method-one
http://localhost/test/method-two
http://localhost/test/method-three
I'm quite sure this is possible to route with lambda routes, I just don't know how to do it.
Pretty simply;
Route::set('test', function ($uri) {
if (list($controller, $action) = explode('/', $uri, 2) AND $controller === 'test')
{
return array(
'controller' => $controller,
'action' => str_replace('-', '_', $action)
)
}
},
'test/<action>');
@matino, I wasn't handling the duplicate endpoint situation with the example above. Amended version below.
Route::set('test', function ($uri) {
if (list($controller, $action) = explode('/', $uri, 2) AND $controller === 'test' AND strpos($action, '_') === FALSE)
{
return array(
'controller' => $controller,
'action' => str_replace('-', '_', $action)
)
}
},
'test/<action>');
I would even go a step further.
Route::set('test', function ($uri) {
$actions = array('method-one','method-two','method-three');
list($controller, $action) = explode('/', $uri, 2);
if ($controller === 'test' AND in_array($action,$actions))
{
return array(
'controller' => $controller,
'action' => str_replace('-', '_', $action)
)
}
},
'test/<action>');
First of all thanks to samsoir for sharing!
Below my tweaked version:
- underscore is replaced in both controller and action
- default controller and action is set
- allow only fixed controllers
Route::set('modules', function ($uri) {
@list($controller, $action) = explode('/', $uri, 2);
// Disbaled 2 valid URL's to the same recourse
if (strpos($controller . $action, '_'))
return;
// Set default values for action and controller
if (empty($controller))
{
$controller = 'index';
}
if (empty($action))
{
$action = 'home';
}
// Only accept below controllers
$controllers = array('controller1', 'controller2', 'index');
if (in_array($controller, $controllers))
{
return array(
'controller' => str_replace('-', '_', $controller),
'action' => str_replace('-', '_', $action)
);
}
},
'<controller>(/<action>(/<id>))');
It looks like you're new here. If you want to get involved, click one of these buttons!