Twig - rendering some variables(constant)? - php

I need some variables(constant) in my project:
path_to_root
path_to_images
I would like to make it without php, just Twig, so i create main.twig:
main.twig:
{% set path_to_root = "/some_folder" %}
{% set path_to_images = "/some_images" %}
In second template i extends by main.twig, so
template.twig
{% extends "main.twig" %}
{% block some_block %}
some_text
<img src="{{ path_to_images }}/image.png" />
{% endblock %}
Yes, it works, bu my question:
Is this good way for having main.twig and in child extends with main?
In each file of templates will i must extends with main.twig?
Sorry for my english :(

Not sure about other php files but the images should go in the assets folder which then you can import using
<img src="{{ asset('path/to/folder/image.png') }}" />

Related

Symfony2/Twig - how to set template file contents as variable?

In Symfony 2.8 I've got SharedBundle, where I keep views and other things I share between other bundles, including the whole layout that should be extended by other bundles' views.
That shared layout has some typical blocks, from which sidebar block should be different for different bundles.
Currently I did an ugly workaround:
In SharedBundle sidebar container:
{% if sidebarcontent is defined %}
{{ sidebarcontent|raw }}
{% else %}
SIDEBAR NOT FOUND
{% endif %}
And in other bundles (here: BundleA) in every view that extends the shared main view:
{% extends 'SharedBundle:layout.html.twig' %}
{% block sidebar %}
{% include 'BundleA:_partials:sidebar.html.twig' %}
{% endblock %}
{% set sidebarcontent = block('sidebar') %}
But that doesn't look good, I think. Is there a better way?
I think this is a valid approach. The only simplification I can think of is not using the variable sidebarcontent.
You can use block('sidebar') inside the if statement:
{% if block('sidebar')|length > 0 %}
{{ sidebarcontent|raw }}
{% else %}
SIDEBAR NOT FOUND
{% endif %}
Make sure the block exists before checking it's content, so initialise it with an empty string:
{% block sidebar %}{% endblock %}

Symfony2 extends twig in bundle - no effect

I do my first project in Symfony2. I have problem with template. My main twig file is "index.html.twig". It's located in src/Gogs/CMSBundle/Resources/views/Default/index.html.twig
I try to extends main twig file from content.html.twig -> it's also in the same directory.
In index.html.twig I have {% block body %}{% endblock %}.
My content.html.twig looks like:
{% extends 'GogsCMSBundle:Default:index.html.twig' %}
{% block body %}
Some content
{% endblock %}
I was looking solution on many forums, but nothing working. Symfony doesn't give me any errors - no effect.
When I try to use include in index.html.twig , it's work perfectly. Code below.
{% include "GogsCMSBundle:Default:content.html.twig" %}
I tried to use also another commands:
{% extends 'GogsCMSBundle:Default:index.html.twig' %}
{% extends 'GogsCMSBundle::index.html.twig' %}
{% extends 'GogsCMSBundle:index.html.twig' %}
{% extends '::index.html.twig' %}
{% extends 'index.html.twig' %}
All of them doesn't give any effect - no errors too.
My main controller:
return $this->render('GogsCMSBundle:Default:index.html.twig', array('name' => $page, 'menu' => $menu));
I cleaned Cache many times.
You need move indexd.html.twig in app\Resources\views = this is a base layout of the symfony. Next create in src/YourBundle/Resources/views layout.html.twig -which extend index.html.twig:
{% extends '::index.html.twig' %}
And finally, add in content.html.twig :
{% extends 'GogsCMSBundle::layout.html.twig' %}
More information there
#Artamiel found the answer...
Bug is in Controller. Contoller must indicate a content.html.twig.
So solution:
index.html.twig
{# src/Gogs/CMSBundle/Resources/views/Default/index.html.twig #}
{% block body %}{% endblock %}.
content.html.twig
{# src/Gogs/CMSBundle/Resources/views/Default/content.html.twig #}
{% extends 'GogsCMSBundle:Default:index.html.twig' %}
{% block body %}
Some content
{% endblock %}
Contoller.php
return $this->render('GogsCMSBundle:Default:content.html.twig');

Import content between Twig files

How can I have a Twig file which imports some of it's content from a second Twig file in the same or a sub directory?
I am developing a project where multiple Twig files have content in common and I'm trying to avoid copying and pasting content between Twig files.
So, I want to have a subdirectory containing the shared markup and simply "import" into the relevant sections of the main Twig files.
With import.list.html.twig in the same directory as the main Twig file, I tried the following:
{% extends "::base.html.twig" %}
{% block title %}StockBundle:StockController:index{% endblock %}
{% block body %}
<h1>Welcome to the StockController:List page</h1>
{% for stock in stocks %}
<div class='list'>
<div class='each stock'>
<span class='name'>{{ stock.name }}</span>
<span class='desc'>{{ stock.description }}</span>
<span class='balc'>{{ stock.balance }}</span>
<span class='edit'>
edit
</span>
</div>
</div>
{% endfor %}
{% include 'import.list.html.twig' %}
{% endblock %}
... but I got the following error:
Unable to find template "import.list.html.twig" in ::base.html.twig at line 10.
When you include it needs to know the namespace of where it is located. When you do ::, as in {% extends "::base.html.twig" %}, it comes from the app/Resources/views directory of your application.
See: Template Naming and Locations Symfony documentation
If your import.list.html.twig is in a bundle, you'll have to define that properly. For instance, if you have StockBundle and a Resources/views directory in that bundle with its own base.html.twig template, you would have
{% include 'StockBundle::base.html.twig' %}
If you had, say, a Stock folder inside that bundle (attached to your StockController) and an import.list.html.twig template, you would have
{% include 'StockBundle:Stock:import.list.html.twig' %}
Note via Registered Namespaced Twig Paths that you can also use a namespaced path instead. They're actually faster as well. So the above would instead be
{% include '#Stock/base.html.twig' %}
{% include '#Stock/Stock/import.list.html.twig' %}
Here's another good reference for Symfony template best practices
NOTE
Since Symfony 2.2, you can use the include() function, and this is the preferred way to include templates:
{{ include('#Stock/base.html.twig') }}
{{ include('#Stock/Stock/import.list.html.twig') }}
Try this:
{% include 'StockBundle:Stock:import.list.html.twig' %}
instead of:
{% include 'import.list.html.twig' %}
http://symfony.com/doc/current/book/templating.html#including-templates

Twig block indirect extending and appending

I have splitted my layout and templates to few partials, mostly because of old Symfony1 habits.
file layout.html.twig:
...
<body>
{{ include("ABCBundle:Partials:breadcrumbs.html.twig") }}
{% block body %}{% endblock %}
</body>
...
file breadcrumbs.html.twig
<div class="abc">
{% block breadcrumbs %}
Home
{% endblock %}
</div>
file show.html.twig
{% extends "ABCBundle::layout.html.twig" %}
{% block breadcrumbs %}
{{ parent() }}
abc
{% endblock %}
{% block body %}
(something something)
{% endblock %}
Funny thing is, when I render show.html.twig, I can put data into body block, and everything works fine, but I can't do anything with breadcrumbs block. Whatever I do - write something inside that block or call parent(), nothing happens, only content from breadcrumbs.html.twig is being rendered. There's also no error about calling parent() and any other error related to extending block.
I think you should use {% include "..." %} rather than {{ include("...") }}
According to the twig documentation, the {% include %} tag "includes a template and returns the rendered content of that file into the current namespace" where as the include function "returns the rendered content of a template"
(Meaning the include function just returns the rendered content, where the tag adds the content to the current namespace which would include the blocks you defined)
Found the solution.
It looks like you can't extend block included in layout's include, from template extending this layout:
[partial.html.twig] --- [ layout.html.twig ] --- [ template.html.twig ]
{% block abc %} {% include 'partial.html.twig' %} {% extends layout.html.twig %}
{% block abc%} aaa {%endblock %}
You have to perform a little hack, including adding extra content to layout and replacing original block from partial.html.twig with conditional. More here: Overriding blocks within included Twig templates

Symfony2 : using assets in sub-layout templates

I'm working on a Symfony2 application and I'm trying to import resources (here, css and js) in a specifig twig template, instead of in the layout templates. However, what I've tried doesn't seem to work when I use the extends property. Yet it does work when there is no layout inheritance.
Here's the code I used :
{% block stylesheets %}
{% stylesheets 'bundles/mybundlename/css/style.css'
filter='cssrewrite' %}
<link rel="stylesheet" href="{{ asset_url }}" type="text/css" />
{% endstylesheets %}
{% endblock %}
{% block javascripts %}
{% javascripts 'bundles/mybundlename/js/jquery-1.7.2.min.js'
'bundles/mybundlename/js/jquery-ui-1.8.20.custom.min.js'
%}
<script src='{{ asset_url }}' type='text/javascript'></script>
{% endjavascripts %}
{% endblock %}
{% extends "MyBundle::layout.html.twig" %}
... the rest of my template ...
Bottom line, how would I import those resources in my inheriting template?
Or is it simply better to just import them in the general layout (but then it loads for every page :/) ?
Edit : I have used #MyBundle route types as well, and they are being searched by the engine (if the path is wrong, I get an error), but the resources are not added the the html section.
Second edit : The reason why it was not working is likely that I hadn't declared the {{% blocks %}} in my top level layout. I did and used {{ parent() }} (as a matter of "cleanliness") in my sub layouts and pages, and it works.
{% extends ... %} must come first.
You might also want to use the parent function to append to the stylesheets and javascripts defined in the layout instead of overwriting them.

Categories