Че-то надоело мне мучаться с ссылками в Smarty и я, как говорится, пошел другим путём :) Напишем маленький скриптик который будет для каждого зарегистрированного пути создавать функцию для смарти, которую мы потом сможем вызывать для генерирования полноценного URL:
$routesFunctions = '/some_path_where_you_want_this/smarty.url_plugins.php';
$fileContents = '<?php ' . PHP_EOL;
foreach ($router->getRoutes() as $routeName => $routeParams) {
$methodName = "{$routeName}_url";
$fileContents .= <<<HEREDOC
function smarty_function_{$methodName}(\$params, \$smarty) {
\$params = array_merge(\$params, array('name' => '{$routeName}'));
return smarty_function_url_for(\$params, \$smarty);
}
HEREDOC;
}
file_put_contents( $routesFunctions, $fileContents );
И теперь при условии что у нас вот такой вот простенький список routes...
$routes = array(
'login' => array(
'route' => '/login',
'defaults' => array(
'controller' => 'auth',
'action' => 'login'
)
),
'show_blog_post' => array(
'route' => '/blog/posts/:id/show',
'defaults' => array(
'module' => 'blog',
'controller' => 'posts',
'action' => 'show'
)
)
);
... в шаблоне мы можем сделать следующее:
<a href="{login_url}">Login</a>
либо
<a href={show_blog_post id=$post->id}">Show this blog post</a>
Само собой, при каждом изменении файла с путями прийдётся заново генерировать файлик с функциями, но думается мне, что это не большая проблема. Кстати вот пример того как может выглядеть функция url_for, которая вызывается внутри сгенерированых функций.
function smarty_function_url_for($params, $smarty)
{
// Надо где-то взять urlHelper :)
global $urlHelper;
if (!$routeName = $params['name']) {
throw new Exception('Route name must be given');
}
unset($params['name']);
if (array_key_exists('params', $params)) {
$params = $params['params'];
if (!is_array($params)) {
$params = array();
}
}
$routeDetails = Zend_Controller_Front::getInstance()->getRouter()->getRoute( $routeName );
$routeVars = $routeDetails->getVariables();
// Required vars to generate URL
$urlVars = array();
foreach ($params as $name => $val) {
if (in_array($name, $routeVars)) {
$urlVars[ $name ] = $val;
unset( $params[ $name ] );
}
}
$url = $urlHelper->url($urlVars, $routeName);
if (!count($params)) {
return $url;
}
// Query vars
$queryVars = array();
foreach ($params as $key => $var) {
$queryVars[] = $key. '=' . urlencode($var);
}
$url .= '?' . implode('&', $queryVars);
return $url;
}
И да, главное не забыть где-нибудь в bootstrap.php:
require '/some_path_where_you_want_this/smarty.url_plugins.php';