Use the URL view helper, please
by Naneau
When writing views, some time sooner or later, you’re going to be creating links to your own pages. Because you don’t want to end up writing relative URLs (they will not work, because the browser will add them to the current path), you need to have some kind of a base URL. A lot of people start writing links like:
While they will function perfectly, there’s two problems, both related to manageability of your website. First is that if your base URL changes (the “/my_app/”), you will have to edit all of your views. Second is that if you use custom routes you may end up with outdated routes, or even worse, erroneous routes in your views. Again, this would mean that you’d have to edit your view scripts.
There is a (near-) perfect solution for this, in the form of a view helper. The URL view helper will create URLs for you, based on your custom routes, and using the base URL set in your front controller. So, the first example could be written as:
1 2 3 4 5 6 | <a href="<?php echo $this->url(array( 'controller' => 'user', 'action' => 'edit', 'id' => '123' ));?>">click me!</a> //line endings added for readability |
Say, if you were to add a custom route like so:
1 2 3 4 5 6 7 8 | $route = new Zend_Controller_Router_Route( 'edit/:id', array( 'controller' => 'user', 'action' => 'edit' ) ); $router->addRoute('userEdit', $route); |
The view helper could generate a matching URL for that route. You do however have to tell the helper that you want to use that specific route (which is identified with “userEdit”):
1 2 3 4 | <a href="<?php echo $this->url(array( 'id' => '123' ), 'userEdit');?>">click me!</a> //note the second parameter for the helper |
Static files
Now, this will work for all your actions, but there’s still the matter of static files, like images and javascript. If you want your application to be truly portable, I suggest writing a little view helper for static files. I personally use this one, which does nothing but add the base URL to a filename:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?php /** * StaticFile.php * * @category Naneau * @package Naneau_View_Helper * @copyright Copyright (c) 2007 Maurice Fonk - http://naneau.nl * @version 0.1.1 */ /** * Naneau_View_Helper_StaticFile * * a view helper for static files * * @category Naneau * @package Naneau_View_Helper * @copyright Copyright (c) 2007 Maurice Fonk - http://naneau.nl */ class Naneau_View_Helper_StaticFile { /** * get a link to a static file with the current baseUrl * * @param string $file * @return string */ public function staticFile($file) { $file = trim($file); //trim the file name (just in case) $frontController = Zend_Controller_Front::getInstance(); //front controller $baseUrl = $frontController->getBaseUrl(); //base url for this application return $baseUrl . '/' . $file; //the link to the file, relative to the base url } } |
In your view scripts you could use that helper to create links to static files:
1 | <link rel="stylesheet" type="text/css" href="<?php echo $this->staticFile('blah.css'); ?>" /> |
Alternatively, you can set a variable to your views that holds the base URL. You would then manually create your links. I personally tend to favor the previous approach, because it allows for less repetition, which is always good. You could for instance set such a variable in your bootstrap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); //view renderer (from the helper broker) if (is_null($viewRenderer->view)) { $viewRenderer->init(); //force instantiation of the view } $frontController = Zend_Controller_Front::getInstance(); //frontcontroller //... additional front controller setup goes here ... $frontController->setBaseUrl('/my_app'); //set your base URL here $viewRenderer->view->baseUrl = $frontController->getBaseUrl(); //set baseUrl for views, retrieved from the front controller $response = $frontController->dispatch(); //do... something! |
Comments
class SpotSec_View_Helper_BaseUrl
{
/**
* Returns site base url
*
* $file is appended to the base url for simplicity
*
* @param string $file
* @return string
*/
public function baseUrl($file = null)
{
return Zend_Controller_Front::getInstance()->getBaseUrl() . ‘/’ . trim((string) $file, ‘/\’);
}
}
> Because you don’t want to end up writing relative URLs…
Is there something bad with using in the html head? I think it helps with most of the above.
sorry, it stripped out the html. It should be:
Is there something bad with using “base” in the html head?
$frontController->setBaseUrl(‘/my_app’) -> $frontController->setBaseUrl(‘/my_app’);
Syntax error
Ahhh you are right. I’ve become way too dependent on IDEs
url(array(
‘controller’ => ‘user’,
‘action’ => ‘edit’,
‘id’ => ‘123′
), ‘userEdit’);?>
there are two conceptions including:file—– ‘ UserController’ , method——-’editAction’;
Hi!
I’m using your smarty extension with the zend framework in my application. Unfortunately it seems to be impossible to use the url helper with it. The problem seems to be the array, which isn’t parsed correctly by smarty. I tried it this way:
{$this->url(array(‘username’ => $this->sessionData->name), ‘profileView’)}
The result is a fatal error with the message that there’s an unrecognized tag in the code.
My other idea was to put the url helper in {php} brackets to execute it as normal php code like this:
{php} echo $this->url(array(‘username’ => $this->sessionData->name), ‘profileView’){/php}
That doesn’t work either and responds with the message “Call to undefined method Smarty::url()”.
Does anyone have any ideas how to solve that problem? Maybe I’m doing something wrong, but I can’t see any mistake…
it’s a common problem. Smarty doesn’t have run-time arrays. There’s a whole discussion about how you can get around it in the comments for this post: http://naneau.nl/2007/05/31/using-naneau_view_smarty-with-rc1/
There is a little tricky part.
If you are calling url helper like:
2
3
4
5
'controller' => 'user',
'action' => 'edit',
'id' => '123'
));?>">click me!</a>
from page which has custom route it will produce incorrect urls. To fix that you have to specify ‘default’ as rule. So it should look like:
2
3
4
5
'controller' => 'user',
'action' => 'edit',
'id' => '123'
),'default');?>">click me!</a>
Note the ‘default’ after array of options.
P.S.
I hope my code won’t get striped. Naneau if there are no
tags in comments, you should add them.you are absolutely right about the extra parameters. The url view helper accepts a route name as the second param. Using “default” it will build the url using the assemble method of the default Zend_Controller_Router_Route. The third param is a boolean which when set to true will reset any of the current url parameters.
I’ll look into code highlighting.
well, why do you re-invent the wheel? when there are routes, the most basic concept framework.zend provides for this task? and relative links do not work? they are part of hypertext linking, shure they work with framework.zend. relax, enjoy. lay back. my jamaican guy. The solution would be to define a route for static files instead, like the route “static”, I would suggest. What do you think about this?
Why not use constants? I have done the following for yonks without a problem:
// in bootstrap
$basepath=str_replace(“/index.php”, “”, substr($_SERVER['PHP_SELF'], 0, -10));
define(“BASE_PATH_NO_INDEX”,$basepath);
// in your view
/styles/StylesDocv8.css” TYPE=”text/css” MEDIA=screen>
No helpers, less code.
Somehow the line was truncated in my earlier post. It should have posted:
// in your view
‘/styles/StylesDocv8.css” TYPE=”text/css” MEDIA=screen>’
I hope it works this time.
I give up.
I find the server using “$_SERVER['HTTP_HOST']” . Then I php echo this with the following added ” . BASE_PATH_NO_INDEX” plus the relative link posted above , all within a “
[...] documentation is silent on this basic task. After searching all over the place, I finally found this site, that tells you to use “the url helper”. There is nothing (or at least as far as I can [...]
Interesting web page is, i’ll see you later one more time
I think you’re supposed to use a custom route.
Looking for information and found it at this great site…
The Monitors harmless for surrounding ambiences. The Monitors corresponding to standard ISO.
Buy the monitors online. Free Download drivers, update drivers.
Hello,
I have a question here. I was going throught this post.
I am trying to generate URL like /controllername/actionname/parameter1/value1/parameter2/value2
While I have been able to configure the router in my Bootstrap file as follws :
——————————————————————–
$router = $frontController->getRouter();
$route = new Zend_Controller_Router_Route(’signup/:uid/*’,array(‘module’=>’signup’,
‘controller’=>’signup’,
‘id’ =>null),
array(‘id’=>’(.*)’));
$router->addRoute(’signup’,$route );
——————————————————————–
and from my controller (SignupController.php), I am trying to generate URL as follows :
$URL = $this->url(array(
‘controller’ => ‘user’,
‘action’ => ‘edit’,
‘id’ => ‘123′
));
When I run my application I am getting following error :
exception ‘Zend_Controller_Action_Exception’ with message ‘Method “url” does not exist and was not trapped in __call()’ in E:SoftwaresApache2.2.6htdocszendProjlibraryZendControllerAction.php:481 Stack trace: #0 [internal function]: Zend_Controller_Action->__call(‘url’, Array) #1 E:SoftwaresApache2.2.6htdocszendProjapplicationcontrollersSignupController.php(59): SignupController->url(Array) #2 E:SoftwaresApache2.2.6htdocszendProjlibraryZendControllerAction.php(502): SignupController->indexAction() #3 E:SoftwaresApache2.2.6htdocszendProjlibraryZendControllerDispatcherStandard.php(293): Zend_Controller_Action->dispatch(‘indexAction’) #4 E:SoftwaresApache2.2.6htdocszendProjlibraryZendControllerFront.php(946): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #5 E:SoftwaresApache2.2.6htdocszendProjpublicindex.php(92): Zend_Controller_Front->dispatch() #6 {main}
Can anyone pls help me into this?
Thanks
Jameel
[...] p(92): Zend_Controller_Front->dispatch() #6 {main} I am following Naneau Use the URL view helper, please Thanks [...]
Thinking about a church wedding? Congratulations, we wish you well as you begin
your journey into married life. In this section you will find a number of …
6 dollers a month adult
the html tag “BASE” does exactly that and doesnt need a new api or library, so…
Win!
europe airfare rates
tickets airfares airfares europe
flights airline reservation
travel airlines airlines
charter flight charter flights cheap
air fare cheap air fares cheap
airline tickets cheap airlines
flights from cheap
airline tickets cheapest
airfare discount airfares discount
domestic airfare domestic
flight to flight to orlando
rome flights to tampa free
tickets international airfare
minute flights london flight low air fare
airfares low cost airfare
flights really cheap airfare
airlines london flights
to london compare flights cheep
business class flights
flight deals discount flight
cheap flights from
air tickets plane tickets airways
cheap air tickets discount
Your Site Is Great,
Thanks for the article!
well, your explanations solve my problem of routing. since i thought when defining routers to zend the framework can identify by itself the router needed and executed which is true for hard url if we typed directly into the browser. but for URL inside the view you have to use of course the URL view helper and also which is mandatory of each URL you have to tell zend which router it should
once again thkx