I need help in including in a twig file, another twig file
For example, I have:
_cdn/widgets/filter/filter.php
_cdn/widgets/filter/view/filter.twig
And:
themes/tema02/view/search.twig
themes/tema02/search.php
I need to include the filter.twig in the search.twig
But when I use include, it does not render the filter.php
And it gets a lot of 'Undefined variable:'
So how do I do this?
First of all show your code . It's always easier to give right anwser when you see the code.
Use {% include %} for including twig in twig
https://twig.symfony.com/doc/2.x/tags/include.html
Based on your description you need to pass requred variables to included twig , something like this
{% include 'filter.twig' with {'foo': 'bar'} %}
OR
In filter twig you can put if ... is defined where you try to access variable
{% if foo is defined %}
code where you doing something with foo variable
{% endif %}
Related
I need to load a page, that will be "inserted" in a template - as I read it, Volt's Template Inheritance should do the trick and it does... kinda. Hardcoded values, as shown in the examples, work fine - the following example works:
<!-- Template -->
<div id="site_content">
{% block test %}
{% endblock %}
</div>
and the page, that inherits the template:
{% extends "../../templates/de/index.volt" %}
{% block test %}
{{ content() }} {# this is a registered volt function that outputs the generated content #}
{% endblock %}
However, the same page might need to inherit a different template and that must be decided on runtime, so the name of the template must be generated dynamically. Two options occurred to me:
Set the template name to a variable and use it when extending - the problem here is that I don't see a way to use it afterwards. That guy seems to have had the same problem, but there is neither an answer of how to do it, nor a confirmation that it isn't possible at all.
Register another function to generate the complete string (e.g. {% extends "../../templates/de/index.volt" %}) and then compile it, e.g.
$compiler->addFunction('get_template',
function ($resolvedArgs, $exprArgs) use ($volt) {
return $volt->getCompiler()
->compileString('{% extends "../../templates/de/index.volt" %}');
});
and then use that function in the page, e.g.
{{ get_template() }}
{% block test %}
{{ content() }}
{% endblock %}
However, using that approach does not parse the page content (e.g. the content returned by the registered content() function is not shown). I'm also open to other solutions (using Twig instead of Volt is only a last resort, for performance issues), advices of what I'm doing wrong or pointers of useful articles on the topic. Thanks in advance!
Try using partials as documented in the Phalcon doc: Using Partials
I'm working on the frontend of a project using Symfony2. I'm stock with something that must be simple, but it's costing me a lot of time.
layout.html.twig is located at /FrontBundle/Resources/views with the following lines
{% include 'SitewebFrontBundle::sidemenu.html.twig' %}
{% block sidemenu %}{% endblock %}
sidemenu.html.twig is also located at /FrontBundle/Resources/views.
Side menu has different content depending on the page been viewed. The urls are:
address.com/menu1/...
address.com/menu2/...
address.com/menu3/...
What I want to do is to create a statement on sidemenu.html.twig following a logic like:
if {{ app.request.requesturi }} has /menu1/
show menu1
else if {{ app.request.requesturi }} has /menu2/
show menu2
else
show menu3
Any ideas on how to accomplish this?
Also you can use KnpMenuBundle. then create merge all your menus under a single root.e.g: make a menu like
Menu
menu1
foo
menu2
...
then make a twig extension, inject the request into it, and find which branch (menu) you have to display:
//in your extension class:
findBranch(){
$path = $this->request->getPathInfo();
$path = trim($path, '/');
$parts = explode('/', $path);
$branch = $parts[0];
return $branch;
}
then in your template find the active branch using the extension and render it with using the built-in method
Generate your sidemenut.html.twig by a passed parameter:
# sidemenu.html.twig
{% if requestUri is not defined %}
{% set requestUri = 'menu3' %}
{% endif %}
# render your routes here like so:
Route 1
# ...
And now include the sidemenu.html.twig with parameters:
# this will result in the requestUri variable to be menu1:
{% include 'SitewebFrontBundle::sidemenu.html.twig' with {includeUri: 'menu1'} %}
# use the request uri as a parameter:
{% include 'SitewebFrontBundle::sidemenu.html.twig' with {includeUri: app.request.requesturi} %}
# this will fallback to 'menu3':
{% include 'SitewebFrontBundle::sidemenu.html.twig' %}
For more questions check out:
The docs about including templates
An evaluation about include vs. render
Why can't you just put all menus into one twig and include them with a variable to determine what menu should be used? Or you can send required name to template from your controller. Because putting such logic into twig usually is a bad idea
Instead of doing this rendering of each slide in my TWIG like this (see line 6):
{# loop out the slides #}
{% for c in contents %}
{% set i=i+1 %} {# increase slide number #}
<div id="slide{{ i }}" class="slide" style="z-index:{{ i }};">
{# the slide itself, rendered by it's own template #}
{% include 'BizTVArchiveBundle:ContentTemplate:'~c.template~'/view.html.twig' with {'contents': c, 'ordernumber': i} %}
</div>
{% endfor %}
...Instead I would like to keep all of that logic in the controller, to just deliver to the view an array of ready slides. How can I do something like this (see line 9):
//do stuff...
foreach ($container->getContent() as $c) {
$content[$i]['title'] = $c->getTitle();
$content[$i]['sort'] = $c->getSortOrder();
$content[$i]['data'] = $c->getData();
$content[$i]['template'] = $c->getTemplate()->getId();
$content[$i]['duration'] = $this->extract_seconds($c);
$content[$i]['html'] = $this->render('BizTVArchiveBundle:ContentTemplate:'.$content[$i]['template'].'/view.html.twig', array(
'contents'=> $content[$i],
'ordernumber' => 99,
));
}
All it gives me at the moment (the contents of $content[$i]['html']) is
{"headers":{}}
Within a twig template, you can set the value of a printed variable like this:
{% set rendered %}
{{ var_to_print }}
{% endset %}
You can get content form rendered object like this:
$this->render('BizTVArchiveBundle:ContentTemplate:Some.html.twig', array())->getContent();
It's better if you include the template in the template, this way you keep the templating rendering in the view layer and the logic in the controller layer.
But well, if you really want it...
You can use 2 services to do that: twig is using the Twig_Environment or templating.engine.twig which is a templating layer build in Symfony2 for Twig, this can be easily switched ot templating.engine.php.
If you use the twig service, you can see the twig docs on how to use it:
$template = $this->get('twig')->render('/full/path/to/Resources/views/'.$content[$i]['template'].'/view.html.twig', array(...));
If you use the templating.engine.twig service, see the templating docs on how to use it, which is almost exact the same as the Twig_Environment.
That is because $this->render() returns a Response object.
Instead of $this->render(), use $this->renderView().
Is there a way with Symfony2 and Twig to always make files available which just contain blocks.
For example, if I wanted to make a block named 'cookie' always available in any template in my system, without having to always include or extend it in the template I'm using.
Any ideas?
Clarification
Say I have a generic block which can do something, like:
{% block myBlock %}
ABC Examples
{% endblock %}
I have a class which knows it wants to be rendered with this block. My template itself doesn't necessarily know this though.
{{ block(myObj.blockName) }}
I would then like to have it so my controller/services/etc. could register the file which contains that block, without my template actually needing to know about it directly (so I could have multiple files like that, each working with some common interface).
Similar to registering custom Twig functions with a TwigExtension. My template doesn't need to explicitly know it's there, it just has to be available at run-time.
Does that make sense?
To clarify a bit further, I'm essentially looking to do something just like how there are default Twig blocks for rendering Forms in Symfony2. I don't have to include the default form file every time, just when I want to change something.
I went digging around in the Symfony source code to try and find my answer. It looks like there isn't some fancy, neat way to embed it from a configuration file or controller directly, which is a bit disappointing, but not a huge deal.
So, to solve my situation, I'll be using the "use" keyword to include my block file in my base template, so it will then be available to everything else.
{# widget_blocks.html.twig #}
{# Widgets #}
{% block my_widget %}
ABC Cookies
{% endblock %}
{# base.html.twig #}
{% use widget_blocks.html.twig %}
{{ block(my_widget.block) }}
Not exactly what I wanted, but sufficiently close.
{% render 'MyMainBundle:Default:credits' with {'arg1': $myObj } %}
Thats what I say. What's the difference between the line above or
{{ block(myObj.blockName) }}
You can register a custom filter but as far as I know it returns only string value. http://twig.sensiolabs.org/doc/advanced.html#id2
I want to use few php string functions in twig. For e.g.
How to write below code in twing?
if (!empty($message) && substr_count($message, 'blabla')) {
....
....
}
You can't, and that's the whole point of twig.
Template should only take care of displaying data.
In that specific case, you could create a TWIG variable, and simply pass TRUE or FALSE, so that you twig code would look like:
{% if display_message %}
...
{% enfif %}
You can look at the list of expressions that are available in the twig template, strstr_count is not part of them :( http://twig.sensiolabs.org/doc/templates.html#expressions
Use filters:
{% if message is not empty and ... %}
...
{% endif %}
I think there is not a substr_count equivalent for twig, you can either make the test and pass the result to the template or create a twig extension and implement it yourself
http://twig.sensiolabs.org/documentation