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

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/

Related

Display images in twig using asset in Symfony 3

i have a list of objects which has an image as an attribute(name of the image as a string) , i am looping this list in twig and i try to display the image in an img html tag which takes it's source of image through a symfony 'asset' path .
this the twig part of code :
{% for offre in listeoffres %}
<li>
<img src="{{asset('images/')}} {{ offre.nomImage }}" alt="">
</li>
<li>
{{ offre.titre }}
</li>
{% endfor %}
Notes :
The database contains correct image names and the images already
exist in the correct folder (web/images)
The '{{ offre.nomImage }}' displays correctly the image name that
it's in the database (with the extension)
When i display {{asset('images/')}} {{ offre.nomImage }} it shows:
/myproject/web/images/ image.jpg
While your solution works, Tthe correct way to use the asset function would be to pass the full path of the image to the function call:
{{ asset('images/' ~ offre.nomImage) }}
I have solved it. The problem was the space between the asset and the image name.So the image source should have been like this :
{{asset('images/')}}{{ offre.nomImage}}

save sonata media path into twig variable

I want to store full path of image (sonata media bundle) into variable in twig. Is that possible?
If I write:
{% set pic = path item.image, 'big' %}
it throws me an error: Unexpected token "name" of value "item" ("end of statement block" expected) ...
If I write:
{% set pic = item.image %}
then it works, but it stores only name of the file, not full path.
Why don't you do like this ?
{% set rendered %}{% path item.image, 'big' %}{% endset %}
....
Here is my path {{ rendered }}
There is not such a function available (there is a path() function to generate routes). You have to create your own twig extension with this custom function. Read all about that in the documentation.
Perhaps you can solve with:
<img src="{% path media, 'small' %}" data-href="{% path media, 'big' %}">

Symfony2 dynamic assetic in twig template

I'm trying show image using assetic (symfony2, twig). URL address of image depends on the bundle.
{% image '#'{{ bundleName }}'/Resources/public/images/logo.png' %}
<img src="{{ asset_url }}" />
{% endimage %}
But it does not work.
You need to use the concatenation operator (~) to combine expressions inside twig tags:
{% image '#' ~ bundleName ~ '/Resources/public/images/logo.png' %}
I found a workaround for this. My situation is that I have images stored in a subdirectory under Resources/images. I wanted them there, rather than the web directory, as they will only be used temporarily and I want to just delete the subdirectory when they are no longer needed rather than having to delete images from various subdirectories. So, I couldn't use the asset() function (since the images were in the bundle) and assetic doesn't seem to support dynamic images.
I needed to display one of 2 banner images based on certain criteria. I wound up creating a twig template that would generate each image using assetic (2 images, so 2 templates).
<a href="{{ vm.bannerLinkUrl }}">
{% image '#MyBundle/Resources/public/images/path/to/image/banner.jpg' %}
<img src="{{ asset_url }}">
{% endimage %}
</a>
I created a 'banner' action in my Home controller to render the templates.
public function bannerAction()
{
/* code to load data into a view model object called $vm */
$template = $this->render(
"MyBundle:Home:path/to/banner-template-subdir/{$vm->bannerType}-banner.html.twig",
['vm' => $vm]
);
return $template;
}
Finally, I used the render function to generate the correct banner from the main page template.
<div class='banner'>
{{ render(controller("MyBundle:Home:banner")) }}
</div>

Symfony Twig path() not working when using render

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)

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.

Resources