Symfony Twig path() not working when using render - symfony

I have a layout that includes some chuck of code form a controller called "Layout"
In the header section I have:
{% block accessinfo %} {% render "/layout/accessinfo" %} {% endblock %}
It works pretty fine, the view file content is:
{% extends '::layout.html.twig' %}
{% block body %}
{% if( is_logged == 0 ) %}
Welcome, access your <a id="accessAccount" title="Access your account">here</a>.
{% else %}
Hi, <b><em> {{ is_logged_user_name }}</em></b>, <a id="doLogout" href="javascript:void;">(Logout)</a>.
<i class="icon-user"></i> Your Account
{% endif %}
{% endblock %}
As one can figure out, path('account/manage') points to the Route named 'account/manage', but it's not returning the fully qualified URL to my project.
It returns:
http://localhost.project/account/manage
where it should be:
http://localhost.project/web/app_dev.php/account/manage
NOTE: I have path() all around my template files and they work like a charm.
IMPORTANT: I found out that when I call REQUEST URI inside the action method:
$this->get('request')->server->get('REQUEST_URI')
PHP will return the URL called by the render, in this case is:
/layout/accessinfo

Perhaps I'm not fully understanding your issue but it seems like you missunderstood the use of the path() and render() functions.
First of all if you like to render a controller and you follow the documentation here you would do it like this...
{{ render(controller('AcmeArticleBundle:Article:recentArticles') }}
{# with some parameters #}
{{ render(controller('AcmeArticleBundle:Article:recentArticles', {
'max': 3
})) }}
This assumes you're using Symfony >= 2.2. This follows the bundle:controller:action pattern, which is called Controller Naming Pattern
For a normal use of the path() function you would always use the name of the route and not a hardcoded URL (as it seems like you're passing in URLs and not route names?)
Let's say your route is called accountmanager, your routing.yml should look like this example
# app/config/routing.yml
accountmanager:
path: /account/manage
defaults: { _controller:YourBundleName:YourControllerName:ControllerAction }
And with that in your routing.yml in twig the use of path() is simply achieved by writing {{ path('accountmanager') }}
See the documentation on this topic. Using the name of the route and not a URL pattern ensures that you're getting to the right page which also includes your environment settings (like app_dev.php for your dev environment)

Related

get route controllers/action within rendered subcomponent in symfony3

In my base.html.twig I render a component:
{% block header %}
{{ render(controller("AppBundle:Application\\Header:header")) }}
{% endblock %}
Is there a way to get the current route action/controller? i.e. the current url in the browser?
When I do var_dump($request->get('_route'));die; it results in null
If you want get the actual route, in your controller you can get the master request like this:
$this->container->get('request_stack')->getMasterRequest()->get('_route');
As I couldn't answer through a comment, I have to write this as an answer.
As mentionned above, this question might be a duplicate of:
Get current URL in Twig template
To get both the name of the current route and the current URL you can simply render them within your twig template by:
<p><strong>current route name</strong> :{{app.request.attributes.get('_route')}}</p>
<p><strong>current url: </strong> {{ app.request.schemeAndHttpHost ~ app.request.requestUri }}</p>

Indicates if an URL is tight to current controller in Twig

assume you are in Twig template and want to indicate if you are on a controller with any action.
The simple process you can check a single route is
{% if app.request.attributes.get('_route') == 'app_user_list' %}
// code...
{% endif %}
But I need something with a wildcard to determine if the action is under current controller like 'app_user_*' to match also 'app_user_add' or 'app_user_delete'. It is nonsence to if-else all possible routes.
Any thoughts?
Thanks!
You can use the slice Twig filter, from the doc:
The slice filter works as the array_slice PHP function for arrays and
mb_substr for strings with a fallback to substr.
So you can archive as example of matching a group of routing with the prefix of app_user_ (app_user_add, app_user_delete, etc):
{% if app.request.attributes.get('_route')|slice(0,9) == 'app_user_' %}
// code...
{% endif %}
Hope this help

What is the difference between 'url' and 'path' in symfony2.3

The document said
{# src/Acme/ArticleBundle/Resources/views/Article/recentList.html.twig #}
{% for article in articles %}
<a href="{{ path('article_show', {'slug': article.slug}) }}">
{{ article.title }}
</a>
{% endfor %}
also, can use 'url' like this:
Home
it confused me what is the difference between using 'url' and 'path'?
They are very similar.
path()
Generates a relative/absolute path :
path('contact') will generate /contact
url()
Generates a scheme-relative/absolute url, ie domain + path
url('contact') will generate http://example.org/contact
The url() style is useful when using cross-domain ajax or generating emails, because the hostname won't be the same.
Take a look at the code https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php for more information
url Twig function generates absolute path
path Twig function generates / related url
Example we have http://sf2sandbox.local with AcmeDemoBundle
{{ path('_welcome') }} produce /
{{ url('_welcome') }} produce http://sf2sandbox.local/

Extending twig for generate html code

I have to generate something like star rating and I have to generate some html for styling ect.
<div class="star on"><i>*</i></div>
<div class="star on"><i>*</i></div>
<div class="star on"><i>*</i></div>
<div class="star"><i></i></div>
<div class="star"><i></i></div>
I want to render using a twig function passing active stars parameters.
{{ stars(4) }}
Is correct use twig functions for generate html code?
Or maybe should I use {% include ... %}
No need in overengineering for such simple task.
If you generate your array in Controller, then it could look like this:
$stars = array(
true,
true,
true,
false,
false,
);
Then you could render your HTML in Twig:
{% for star in stars %}
<div class="star{{ star ? ' on' }}"<i>{{ star ? '*' }}</i></div>
{% endfor %}
In case if you would like to operate with Twig only, I recommend you to use macro:
{% macro stars(stars, total) %}
{% for item in 1..total %}
{{ item }}<br>
{% if item <= stars %}
<div class="star on"><i>*</i></div>
{% else %}
<div class="star"><i></i></div>
{% endif %}
{% endfor %}
{% endmacro %}
If you've defined your macro in the same template, you should call it via _self, if in another file - just like a function, but not forget to import your file into needed twig. See chapter about macros (linked above).
Following call will produce HTML structure that you described in your question:
{{ _self.stars(3,5) }}
See the Extending Twig section of its docs. According to the table in the first section on that page, using functions for content generation is natural. I create a lot of Twig functions and I suggest you create one to solve your problem.
BTW, your function can render a separate template with HTML code — do not generate the HTML code right in your Twig function's PHP code. To render a separate template from your Twig function, inject the service_container service into it, get the templating service and call the render() method on it:
return $this->container->get('templating')->render($pathToYourCustomTemplate);
Usually, it's best to inject the needed services individually, but if you inject the templating service instead of service_container, you'll get a cyclic dependencies problem. That's why injecting the whole container into Twig extensions is a reasonable exception.

symfony2 - twig - how to render a twig template from inside a twig template

I have a xxx.html.twig file which shows a page, but when I want to refresh the page with different data and just update it with new data, I have a select and a submit button for it.
The thing is that I don't know how do I call an action in the controller which I pass parameters to from my twig and call for new data and then I render the same twig template again with new parameters.
How do I do so?
Here are a few different ways:
{{ render(app.request.baseUrl ~ '/helper/test', {"hostid2": hostid } ) }}
or
{% include 'MyCoreBundle:Helper:test.html.twig' with {"hostid2": hostid } only %}
or
{% render controller("MyCoreBundle:Helper:test", {'hostid2': hostid}) %}
Symfony 2.1:
{% render 'YourBundle:YourController:yourAction' with {'var': value} %}
Symfony 2.6+:
{{ render(controller('YourBundle:YourController:yourAction', {'var': value})) }}
And, of course, read the documentation.
I think some parts are depricated here.
To make the include work in latest Symfony 3.1.10, I solved it like this:
{% extends 'base.html.twig' %}
{% block body %}
{{ include('AppBundle:Default:inner_content.html.twig') }}
{% endblock %}
Note: include() with parentheses.
Then all the variables are included from the parent template. If you like to restrict some variables in the child template, you use with ... only (look over)

Resources