JavaScript: Реализация аналога url_for() из Symfony на Javascript

Автор OutPunk  // 13.05.2011
Иногда, я бы даже сказал, что почти в каждом более или менее крупном проекте нужно использовать маршруты, прописанные в серверном коде, в javascript на клиенте. В поисках решения данной проблемы на Symfony я наткнулся на одно занимательное решение, хоть и не вполне рабочее для Symfony 1.4.8. После некоторой доработки я остался удовлетворен результатом, которым и решил поделиться. Итак, меньше слов, больше кода!

Реализация

Для начала нам нужно добавить новый маршрут в routing.yml:
routes_js:
url: /js/routes.js
param: { module: routes_js, action: index }

Сгенерируем модуль для приложения:
./symfony generate:module application_name routes_js

В actions.class.php модуля напишем следующее:
// apps/application_name/modules/routes_js/templates/indexSuccess.php
class routes_jsActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$this->setLayout(false);
$this->getResponse()->setContentType('text/javascript');
$this->routes = $this->makeRoutes();
}
 
protected function makeRoutes()
{
$routes = $this->getContext()->getRouting()->getRoutes();
$parsed_routes = array();
 
foreach ($routes as $name => $route)
{
$requirements = $route->getRequirements();
 
$method = 'ANY';
 
if (isset($requirements['sf_method']))
{
if (is_array($requirements['sf_method']))
$method = implode(', ', $requirements['sf_method']);
else
$method = $requirements['sf_method'];
}
 
$method = strtoupper($method);
$pattern = str_replace('.:sf_format', '', $route->getPattern());
$app = $this->getContext()->getConfiguration()->getApplication();
$env = sfConfig::get('sf_environment');
$prefix = $app == 'backend' ? '/backend' : '';
$prefix .= $env == 'dev' ? '_dev.php' : '.php';
 
$parsed_routes[$name] = array(
'pattern' => $prefix . $pattern,
'method' => $method
);
}
 
return $parsed_routes;
}
}

Код шаблона:
// apps/application_name/modules/routes_js/templates/indexSuccess.php
var sf = {
 
url_for: function(route, params)
{
if (typeof sf.routes[route] === 'undefined')
return false;
 
var url = sf.routes[route].pattern;
 
if ($.isArray(params) || $.isPlainObject(params))
{
$.each(params, function(i, v)
{
url = url.replace(':'+i, encodeURIComponent(v));
});
}
 
return url;
},
 
routes: < ?php echo json_encode($sf_data->getRaw('routes')) ?>
};

Использование

Предположим, что у нас есть такой маршрут:
# apps/application_name/config/routing.yml
recipe_show:
url: /recipe/:slug
class: sfDoctrineRoute
options: { model: Recipe, type: object }
param: { module: recipe, action: show }

Ничего сложного, все просто. Используем так:
var slug = 'chicken-salad';
recipe_url = sf.url_for('recipe_show', { slug: slug });
alert(recipe_url);


Share this:


Комментарии (0) Добавить
Только авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста.