Handling relative links with Zend_View_Helper
It's 4:30 AM, and I'm sitting in an airport lounge waiting for a flight to Brussels after accidentally bumping into Zeev and a couple of other guys (Amnon and Matti) from Zend, on their way to a management meeting in the US. Since they had to board, and I'm left all alone and still have an hour or so to pass, I'm going to share a nifty little thing I found in Zend Framework a couple of days ago: A nice and clean way to generate relative links in view scripts.
Putting links (<a href="..."> tags or <link href="..."> tags for example) is quite easy if you assume your application is always installed on the document root of a virtual host - which is something many MVC applications assume these days. You just link to '/path' and you're done. But what happens if you want to have your application installed, linked or aliased to a subdirectory under your document root - something like 'http://prematureoptimization.org/blog/' ? Then you'd have to dynamically generate the path on every link you create. Here is how I've done it:
First, have some kind of config file (or just define in your bootstrap file) what is the path under your document root your application is - personally, I used Zend_Config to do that - but you don't have to.
Second, when you create your front controller, do the following:
-
<?php
-
// $config->www->baseurl is the base URL of your app.
-
$front = Zend_Controller_Front::getInstance();
-
$front->setBaseUrl($config->www->baseurl);
-
// ... continue the dispatch process
-
?>
Once you set Zend_Controller_Front->setBaseUrl() to point to your base URL, all
redirections will work well when you call Zend_Controller_Action->_redirect() in your
controllers.
But how do you create links in your views? Well, you could put your $config object in a registry and access it - but it's kind of ugly, plus it won't work if you override your $config somehow, or don't have a $config object at all.
Another thing I tried doing is calling Zend_Controller_Front->getBaseUrl() whenever I
needed it - like so:
-
<a href="<?= Zend_Controller_Front::getInstance()
-
->getBaseUrl(); ?>/somepage">click here</a>
But again, this is a bit confusing, and it feels kind of awkward calling the front controller from view
scripts - in my opinion, view scripts should be readable and non-intimidating so that even your
average web designer could work with them (and not break them).
Well, following an advice from Matthew I created a view helper to handle the creation of relative links. It's important to say that Zend Framework already comes with a view helper that creates relative links - Zend_View_Helper_Url - but it's quite complex in a sense that it creates links from predefined routes using a Zend_Controller_Router object from your front controller. I needed something simpler, using static paths, and this is what I came up with:
Now all you have to do is put this class in a file named 'LinkTo.php' in your application/views/helpers directory (naming is important - see the Zend_View manual chapter on helpers for more information) you could just do this from your view scripts to get relative links easily:
-
<a href="<?= echo $this->linkTo('/somepage'); ?>">Some page</a>
Nice, huh?














I'd modify that slightly. View helpers are instantiated only once per view object -- meaning that if you're calling the helper multiple times, why not cache the baseUrl in the object during instantiation?
This will have the benefit of performing faster on subsequent invocations, bringing
the total number of function calls down to basically only the method call.
Yeah, I thought about that - and even better, cache it in a static property - so you're reducing calls from *all* view scripts, not just from each one separately. Something like this:
[...] now I find the solution here: Premature Optimization Handling relative links with Zend_View_Helper uder the title: Handling relative links with [...]
[...] take a look to this to see if it is your solution: Premature Optimization Handling relative links with Zend_View_Helper [...]