Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Action names, dashed to camelCase #284

Closed
alvassin opened this issue Dec 24, 2012 · 10 comments
Closed

Action names, dashed to camelCase #284

alvassin opened this issue Dec 24, 2012 · 10 comments

Comments

@alvassin
Copy link

Currently if i will action like

class MyController
{
    public function veryLongActionNameAction()
    {

    }
}

it will be accessible only by url

/my/veryLongActionName

I would like to have dashed names, where all words are divided by dashes:

/my/very-long-action-name

Lowercase names for actions looks like better then camelCase in url address bar (just from my point of view).
Is it possible to use dashed names for controller actions in urls? Perhaps there is a global solution to change router logic, to transform all dashed action names into camelCase?

@phalcon
Copy link
Collaborator

phalcon commented Dec 25, 2012

You can add a listener to the dispatcher and transform the action before be dispatched:

$di->set('dispatcher', function(){

    //Create an event manager
    $eventsManager = new Phalcon\Events\Manager();

    //Attach a listener for type "dispatch"
    $eventsManager->attach("dispatch", function($event, $dispatcher) {
        $actionName = Phalcon\Text::camelize($dispatcher->getActionName());
        $dispatcher->setActionName($actionName);
    });

    $dispatcher = new \Phalcon\Mvc\Dispatcher();

    //Bind the eventsManager to the view component
    $dispatcher->setEventsManager($eventsManager);

    return $dispatcher;
}, true);

@alvassin
Copy link
Author

Thank you very much! Continued to be impressed with Phalcon power and flexibility :)

@alvassin
Copy link
Author

Hmm... Found that if i define action name with dash, it is not set in $dispatcher:

$eventsManager->attach('dispatch', function($event, $dispatcher) {
    echo '<pre>';
    var_dump($dispatcher->getActionName());
});
url: /test/action
returns "action"

url: /test/test-action
returns NULL

Perhaps i should also setup additional route or action parsing rules?

@alvassin alvassin reopened this Dec 26, 2012
@phalcon
Copy link
Collaborator

phalcon commented Dec 26, 2012

Yes, you must add routes that allow dashes in the action part:

$router = new Phalcon\Mvc\Router(false);

$router->add('/:controller', array(
    'controller' => 1
));

$router->add('/:controller/([a-zA-Z\-]+)/:params', array(
    'controller' => 1,
    'action' => 2,
    'params' => 3
));

@phalcon
Copy link
Collaborator

phalcon commented Dec 28, 2012

A short and more clean version of this can be achieved in 0.8.0 using a conversor :

$router = new Phalcon\Mvc\Router(false);

$router->add('/:controller', array(
    'controller' => 1
));

$router->add('/:controller/([a-zA-Z\-]+)/:params', array(
    'controller' => 1,
    'action' => 2,
    'params' => 3
))->convert('action', function($action) {
    return Phalcon\Text::camelize($action);
});

@phalcon
Copy link
Collaborator

phalcon commented Dec 29, 2012

Please re-open this if you still have questions about this

@phalcon phalcon closed this as completed Dec 29, 2012
@szepczynski
Copy link

Hi @phalcon I have an issue related to this one. Can you look at it? http://forum.phalconphp.com/discussion/2384/blank-page-on-for-some-actions#C8088

@sszdh
Copy link

sszdh commented Apr 25, 2015

Base on @phalcon answer, use this route setting: (note lcfirst for auto view rendering)

$router->add('/:controller/([a-zA-Z\-]+)/:params', array(
    'controller' => 1,
    'action' => 2,
    'params' => 3
))->convert('action', function($action) {
    return lcfirst(Phalcon\Text::camelize($action));
});

@akudryav
Copy link

I'm using phalcon 2.1.0r. Application based on Invo.
If I try any url which contains dash in action name it redirects to index/index route. This in not good, because there is no 404 error for non-existing routes.
Also there is strange behavior with dashes in controller name.
Example: I have pages controller with admin action, so http://mysite/pages/admin - is working route, but when I try http://mysite/p-ag-es/admin it also gives 200 response code with blank page, not 404 error
and http://vintagemebel/p-ag-es/notexistingaction gives 404 error.

@leowisdompos
Copy link

leowisdompos commented Sep 17, 2019

I'm following this guide.
Im using Phalcon 3.4

my services_web.php

/**
* Set the default namespace for dispatcher
*/
$di->setShared('dispatcher', function () {

    //Create an event manager
    $eventsManager = new Phalcon\Events\Manager();

    //Attach a listener for type "dispatch"
    $eventsManager->attach("dispatch", function($event, $dispatcher) {
        $controllerName = $dispatcher->getControllerName();
        $actionName = $dispatcher->getActionName();
        \Tool::predump($controllerName, false); // <-- print
        \Tool::predump($actionName); // <-- print and exit
        // camelize
        $controllerName = Phalcon\Text::camelize($controllerName);
        $actionName = Phalcon\Text::camelize($actionName);

        $dispatcher->setControllerName($controllerName);
        $dispatcher->setActionName($actionName);
    });

    $dispatcher = new Dispatcher();
    $dispatcher->setDefaultNamespace('Example\Modules\Frontend\Controllers');
    $dispatcher->setEventsManager($eventsManager);
    return $dispatcher;
});

my routes.php

$router = $di->getRouter();
$router->removeExtraSlashes(true); 

$router->add('/rdr{code:[A-Za-z0-9]+}', [
    'module'     => 'frontend',
    'controller' => 'redirect',
    'action'     => 'index',
]);

foreach ($application->getModules() as $key => $module) {
    $namespace = preg_replace('/Module$/', 'Controllers', $module["className"]);
    $router->add('/'.$key.'/:params', [
        'namespace'  => $namespace,
        'module'     => $key,
        'controller' => 'index',
        'action'     => 'index',
        'params'     => 1
    ])->setName($key);
    $router->add('/'.$key.'/:controller/:params', [
        'namespace'  => $namespace,
        'module'     => $key,
        'controller' => 1,
        'action'     => 'index',
        'params'     => 2
    ]);
    $router->add('/'.$key.'/:controller/([a-zA-Z\-]+)/:params', [
        'namespace'  => $namespace,
        'module'     => $key,
        'controller' => 1,
        'action'     => 2,
        'params'     => 3
    ])->convert('action', function($action) {
        return lcfirst(Phalcon\Text::camelize($action));
    });
}

URL TEST:
#1 : localhost/regular-wash-pack/detail
result:
string(17) "regular-wash-pack"
string(6) "detail"
I thought it was good and work

#2 : localhost/regular-wash-pack/detail-submit
string(0) ""
string(0) ""
why even the controller name return an empty string?

#3 : localhost/regular-wash-pack/detailSubmit
string(17) "regular-wash-pack"
string(12) "detailSubmit"
this is work but I dont want like this

Please help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants