Sign In or Create Account

Huge image

ZF Routes + Smarty

Posted on Nov 03, 2009 by Andrei

Че-то надоело мне мучаться с ссылками в 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';



Tags:

Oops. No tags.


Comments:


Name:
Email: (won't be dispayed anywhere on the site)
URL:
Comment: