Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updated: Best practices for managing static content in Zend Framework?

I have some questions concerning the Zend Framework. I am attempting to route all static pages through the default controller using the now default displayAction() method. The intention is to have the displayAction() process the request by looking at the page param, determine if the script page exists, if it does render the view otherwise throw a 404 page not found error. Additionally, a test is done to see if a method with the same name as the param exists, if so, call on that action.

Listed here is the routing configuration from the application.ini

resources.router.routes.static-pages.route = /:page
resources.router.routes.static-pages.defaults.module = default
resources.router.routes.static-pages.defaults.controller = index
resources.router.routes.static-pages.defaults.action = display

Here is the controller actions:

public function someAction() {
    // do something
}

public function displayAction() {  
    // extract page param, e.g. 'some'      
    $page = $this->getRequest()->getParam('page');

    // create zend styled action method, e.g. 'someAction'
    $page_action = $page.'Action';

    // if a method within this controller exists, call on it
    if (method_exists($this, $page_action)) {
        $this->$page_action();
    }

    // if nothing was passed in page param, set to 'home'
    if (empty($page)) {
        $page = 'home';
    }

    // if script exists, render, otherwise, throw exception.
    if (file_exists($this->view->getScriptPath(null)."/".$this->getRequest()->getControllerName()."/$page.".$this->viewSuffix)) {
        $this->render($page);
    } else {
        throw new Zend_Controller_Action_Exception('Page not found', 404);
    }
}

Now, here are my questions: Is there a better way of doing this? I'm relatively new to this framework, so are there best practices which apply? Is there a better way of calling on an action from within a controller? I have done A LOT of looking around through the documentation, however, quite a bit of it seems to contradict itself.

Update 1:

After having a think and a read, I've managed to simplify the solution and include a few things which were mentioned. NOTE: I use PagesController as my default static-content controller.

Listed here is the routing configuration from the application.ini. For calls to the home page i.e. "/", I pass "home" as the action param, for all other requests, the user defined / url link param is sent in action.

resources.router.routes.home.route = "/"
resources.router.routes.home.defaults.module = "default"
resources.router.routes.home.defaults.controller = "pages"
resources.router.routes.home.defaults.action = "home"
resources.router.routes.pages.route = "/:action"
resources.router.routes.pages.defaults.module = "default"
resources.router.routes.pages.defaults.controller = "pages"

Here is the controller actions. If user define parameter exists as an action, it will be called, else it falls to the php magic function __call.

public function someAction()
{
    // Do something
}

public function __call($method, $args)
{
    // extract action param, e.g. "home"
    $page = $title = $this->getRequest()->getParam('action'); 

    // test if script exists
    if (file_exists($this->view->getScriptPath(null) . "/" 
        . $this->getRequest()->getControllerName() . "/$page . " . $this->viewSuffix)) 
   {
        // pass title to layout
        $this->view->assign(compact('title'));
        // render script
        $this->render($page);
    } else {
        throw new Zend_Controller_Action_Exception('Page not found', 404);
    }
}

It works. So, here are my questions: Would you consider standardising on using this method to manage static content? If not, why not? How would you improve it? Also, considering this is a GET request, would it be a wise move to use Zend_Filter_input to cleanse input or is that just overkill?

like image 825
Hegemon Avatar asked Jan 20 '12 18:01

Hegemon


2 Answers

Your approach seems reasonable to me. However, perhaps you should take advantage of the __call method instead, which would allow you to more easily route your actions...

Setup your route like this:

resources.router.routes.static-pages.route = /:action
resources.router.routes.static-pages.defaults.module = default
resources.router.routes.static-pages.defaults.controller = index

And your controller like so:

public function someAction() {
    //going to URL /some will now go into this method
}

public function __call($name, $args) {
    //all URLs which don't have a matching action method will go to this one
}
like image 85
Jani Hartikainen Avatar answered Nov 15 '22 01:11

Jani Hartikainen


I think your on the right track however here are some other ideas.

Break up your routing per sections in your INI: ie a blog router, a static page router a forum router etc.. (I think you are already doing this)

Use the various router classes to handle routing per section rather than sending it to a controller.

Static: http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.static

All: http://framework.zend.com/manual/en/zend.controller.router.html

Some links that may help:

  • codeutopia.net/blog/2007/11/16/routing-and-complex-urls-in-zend-framework/
  • www.vayanis.com/2009/03/20/intro-to-zend-framework-routing/
like image 33
Andre Avatar answered Nov 15 '22 01:11

Andre