I'm developing a navigation system for Symfony 2. It's working really nicely so far. So far, there is a config file like so:
# The menu name ...
primary:
# An item in the menu ...
Home:
enabled: 1
# Routes where the menu item should be shown as 'active' ...
routes:
- "a_route_name"
# Where the link goes to ... the problem ...
target: "a_route_name"
This layout is working nicely, and the menu works. Apart from in my template, I can only generate links using the target value that correspond to routes within an application; i.e, not an external URL.
The template is as follows for generating the navigation:
{# This is what puts the data for the menu into the page currently ... #}
{% set primary_nav = menu_data('primary') %}
<nav role="navigation" class="primary-nav">
<ul class="clearfix">
{% for key, item in primary_nav if item.enabled is defined and item.enabled %}
{% if item.routes is defined and app.request.attributes.get('_route') in item.routes %}
<li class="active">
{% else %}
<li>
{% endif %}
{% if item.target is defined %}
<a href="{{ path(item.target) }}">{{ key }}</a>
{% else %}
{{ key }}
{% endif %}
</li>
{% endfor %}
</ul>
</nav>
Is there a simple way to allow the path()
function or, something similar to generate URLs from routes, or just simply use a given URL if it validates as one?
I got as far as trying url()
, and looked around the docs but couldn't see anything.
You can create a Twig extension that check if a route exists :
if it exists, the corresponding generated url is returned
else, the url (or other stuff) is returned without any change
In your services.yml, declare your twig extension and inject the router component. Add the following lines and change namespaces :
fuz_tools.twig.path_or_url_extension:
class: 'Fuz\ToolsBundle\Twig\Extension\PathOrUrlExtension'
arguments: ['@router']
tags:
- { name: twig.extension }
Then create a Twig\Extension directory in your bundle, and create PathOrUrlExtension.php :
<?php
namespace Fuz\ToolsBundle\Twig\Extension;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
class PathOrUrlExtension extends \Twig_Extension
{
private $_router;
public function __construct(Router $router)
{
$this->_router = $router;
}
public function getFunctions()
{
return array(
// will call $this->pathOrUrl if pathOrUrl() function is called from twig
'pathOrUrl' => new \Twig_Function_Method($this, 'pathOrUrl')
);
}
public function pathOrUrl($pathOrUrl)
{
// the route collection returns null on undefined routes
$exists = $this->_router->getRouteCollection()->get($pathOrUrl);
if (null !== $exists)
{
return $this->_router->generate($pathOrUrl);
}
return $pathOrUrl;
}
public function getName()
{
return "pathOrUrl";
}
}
You can now use your new function :
{{ pathOrUrl('fuz_home_test') }}
<br/>
{{ pathOrUrl('http://www.google.com') }}
Will display :