djsipe.com | Web Development

Update: With the release of Zend_Layout, the need to this sort of workaround has diminished.

It’s no secret that I’m a big fan of the Zend Framework. After fumbling around with a primitive MVC application at work, I was instantly won over by the clean, and intuitive way they implement MVC. Round about version 0.9, the ViewRenderer was introduced. ViewRenderer is, I’d say, 90% useful. It makes certain assumptions about the way you’re using the framework. If you color between the lines it’s a great help.

One thing I almost always have to do is override the way it selects and automatically renders templates based on controller and action names. I typically roll with a single template and load elements into that template. Of course, I could just disable ViewRenderer altogether, but it does do a lot of other things that I find helpful, like initializing the View.

My solution: extend the default Zend_Controller_Action class. There’s only a few things to do:

  1. Disable the auto-render functionality of ViewRenderer
  2. Add a new $_template property to hold the template to render
  3. Render a single template in the postDispatch method

Here’s the code:

require_once "Zend/Controller/Action.php";

class Blink_Controller_Action extends Zend_Controller_Action
{
    protected $_template = "defaultTemplate.phtml";

    public function init()
    {
        $this->_helper->viewRenderer->setNoRender(true);
        parent::init();
    }

    public function postDispatch()
    {
        echo $this->view->render($this->_template);
    }
}

With our new controller action, we can then largely forget about rendering the View. All we have to do is assign values to the View:

require_once "Blink/Controller/Action.php";

class MyController extends Blink_Controller_Action
{
    public function IndexAction ()
    {
        $this->view->myValue = "some value";
        // Assign more values...
        // Do business logic...

        // Optionally, select a new template to render
        $this->_template = "differentTemplate.phtml";
    }
}
Posted in php | 1 Comment »

On of the best tools around for helping you speed up your page load times is Yahoo!’s YSlow Firefox extension. I’ve been using it for a while and found it has some interesting insights on page load performance. Its recommendations come from Yahoo!’s “Exceptional Performance Team” 14 recommendations for speeding up page load times. If you’d rather hear it right from the horses mouth, have at, otherwise you can watch the conveniently embedded video below.

Briefly, the 14 recommendations are:

  1. Make fewer HTTP requests
  2. Use a CDN (like Akamai)
  3. Add an “Expires” header
  4. Use GZIP compression
  5. Put CSS at the top
  6. Put JavaScript (JS) at the bottom
  7. Avoid CSS expressions
  8. Make JS and CSS external
  9. Reduce DNS lookups
  10. Minify JS
  11. Avoid redirects
  12. Remove duplicate scripts
  13. Configure ETags
  14. Make AJAX cacheable

Since the video can probably explain each of these points better than I can, I’ll let them speak for themselves for the most part. Lately though, I have been thinking a lot about two of them, namely #1 and #10: Make fewer HTTP requests and Minify JavaScript. Bit by bit, I’ve been trying to get all our JavaScript files at work “minified” but, it’s an uphill battle with so many files being edited semi-frequently by people other than myself. Since minified JavaScript is almost impossible to read without getting a headache, you’d have to keep the un-minified versions on tap somewhere and leave step by step instructions on how to minify them and then get them on the site. Having people then copy and paste the minified versions into a single aggregate file is simply asking for trouble.

Then I found a key part of the solution: a port of Crockford’s JSMin to PHP. This PHP version, allows you to do something very powerful that the original JavaScript version did not. Now you can use aggregate and minify all your JavaScript into a single HTTP request by calling a PHP script in your script tag which gathers and minifies all the JavaScript for the page.

So, say you wanted to aggregate and minify the JavaScript for your menu and rich text editor of choice. In your HTML, you might use a script tag like this:

<script type="text/javascript" src="/jsaggmin.php?features=menu/richtexteditor"></script>

On the server, jsaggmin.php would do look something like this:

require "jsmin.php";

foreach (explode("/", $_GET['features']) as $feature)
{

    switch ($feature)
    {
        case "menu":
            echo JSMin::minify(file_get_contents("menu.js"));
            break;

        case "richtexteditor":
            echo JSMin::minify(file_get_contents("rte.js"));
            break;
    }

}

Granted, this isn’t the complete solution, but it’s a leap in the right direction. What is needed next (in addition to a caching mechanism) is a way to run the equivalent of JSLint on the server before the files are minified. As a rule of thumb, if a JavaScript file can’t pass JSLint, it will blow up when minified. So the PHP script would need to verify the JavaScript, and echo it as is if it fails to validate. Otherwise, you’ve just minified and aggregated all the scripts on your page and can focus on the other 12 recommendations.

Posted in Front End | 1 Comment »

© 2008 Donald J Sipe | Powered by WordPress | RSS Feed