Twig Form Blocks - symfony

I know that i can override checkbox_widget in my form_theme file like that
{% block checkbox_widget %}
my Code
{% endblock checkbox_widget %}
The problem is that I have all files loaded globally so in this way I would override all checkbox_widget in application. But i need to override checkbox in one form.
So the question is How i can override checkbox_widget for one specific form or override specific field widget somehow ?
I tried something like this but it doesn't works:
{% block MyFormName_checkbox_widget %}
my Code
{% endblock MyFormName_checkbox_widget %}

You have to use twig macros instead of blocks. Docs here: macro and import.

Related

Symfony/Twig: Extending stylesheet block from an extended bundle

I'd like to extend the stylesheets blocks from inside a bundle I've created to extend FOSUserBundle.
This is how to extend from inside the same bundle, but I want to extend from another bundle that extends a third-party bundle.
This is the code:
{# src/MyNamespace/UserBundle/views/layout.html.twig #}
{% extends '::base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
{% stylesheets filter='scssphp,cssrewrite' output='css/app.css'
'bundles/mynamespace/scss/Profile.scss'
%}
{% endstylesheets %}
{% endblock %}
{% block title %}My title{% endblock %}
{% block body %}
{% block fos_user_content %}{% endblock %}
{% endblock %}
So, basically, I've extended the FOSUserBundle creating another bundle in my src directory as explained here.
The code of my `base.html.twig template is this:
{# app/Resources/views/base.html.twig #}
...
<head>
...
<title>{% block title %}{% endblock %}</title>
<meta name="description" content="{% block metaDescription %}{% endblock %}" />
{% include('::_common/Stylesheets.html.twig') %}
...
And this is the included Stylesheets.html.twig:
{% block stylesheets %}
{% stylesheets filter='scssphp,cssrewrite' output='css/app.css'
'bundles/app/css/bootstrap.css'
...
%}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
The problem is that the CSS from src/MyNamespace/UserBundle/views/layout.html.twig is never included in the page, also if it is installed with app/console asstes:install and then dumped with app/console assetic:dump.
The CSS is generated and put in web/css/app_Profile_1.css but is never included in the pages (not in home page or other AppBundle pages, not in MyNamespaceUserBundle pages.
Also adding the line <link rel="stylesheet" href="{{ asset_url }}" /> to the src/MyNamespace/UserBundle/views/layout.html.twig block, the CSS isn't included.
Obviously, if I include the stylesheet directly from _common/Stylesheets.html.twig the file is correctly included.
So, it seems there is something break.
Anyone can help me?
Without the <link rel="stylesheet"> in the {% block stylesheets %} in layout.html.twig, it's not going to output the link for Profile.scss.
More importantly, though, is that {% include %} and {% block %} do not work quite the way you think they do in the presence of {% extends %}. The combination is a little weird, so some background first.
A {% block %} is simply a named wrapper around some content. In the absence of {% extends %}, a block is immediately output where it is defined. (Think of it as if you defined a function, and then immediately called it.)
When you extend another template, however, block definitions in the "global scope" of the extending template replace the definitions of the block in the extended template. This is a re-definition only; the block is still being called at the same place it was in the parent template.
{% include %} renders another template and inserts the results of the evaluation in-line. While it has access to the current context's variables, it is otherwise it's own separate renderer. Importantly, it does not substitute itself with the template code as you are expecting.
So what is happening is this:
layout.html.twig extends base.html.twig. layout.html.twig defines a stylesheets block (but does not emit it). base.html.twig includes Stylesheets.html.twig, so base.html.twig gains the result of evaluating Stylesheets.html.twig (so you get the contents of the {% stylesheets %} tag, but importantly, not the fact that there was even a block there at all.
Then, because there is no place in base.html.twig where there actually is a {% block stylesheets %}, the block defined in layout.html.twig never gets called.
The solution is to move the {% block stylesheets %} into base.html.twig. If you want to keep the actual stylesheet definitions in the Stylesheets.html.twig, then you can do it like this:
{% block stylesheets %}
{% include('::_common/Stylesheets.html.twig') %}
{% endblock %}
And remove the block tag (but not the stylesheet content itself) from Stylesheets.html.twig. That should give you the desired result.

Drupal 8 include part template

I'm trying to use Drupal 8, with an own theme, due big structure differences for my requirements I have a page--front.twig.html and a page.twig.html, I would like to create template parts as used in phrozn oder in a normal Symfony2 project, for example a footer.html.twig and a header.html.twig. These templates are saved under a subdirectory /parts/
But wenn I call this templates as normal I just receive a string with the name of the template.
For example:
{# in page.html.twig or page--front.html.twig #}
{% include 'parts/footer.html.twig' %}
Returns the file name as string:
parts/footer.html.twig
It's possible to do that with Drupal 8?
You can include any part of your template files like this
{% include directory ~ '/parts/footer.html.twig' %}
or this
{% include '#mytheme/parts/footer.html.twig' %}
I strongly recommend you to create a reusable layout for pages that will give you greater flexibility when dealing with more pages and variants.
{# filename: page-layout.html.twig #}
{% block content%}
{{ page.content }}
{% endblock%}
{% block footer%}
{% include '#mytheme/parts/footer.html.twig' %}
{% endblock%}
So you can do something like this in another page
{# filename: page--front.html.twig #}
{% block footer%}
<div> I want to handle a different footer in here</div>
{% endblock%}
Finally, I found really helpful to dig into suggestions array and see what Drupal is trying to use.
Cheers.
it's possible using the name of the template in the path
{% include '#mytheme/parts/footer.html.twig' %}
thanks to https://drupal.stackexchange.com/questions/141066/drupal-8-include-part-template
Now that https://www.drupal.org/node/2291449 has been committed you can also do:
{% include 'footer.html.twig' %}

FOSUserBundle changing text on page depending on form

I'm very new to symfony2 and twig templating in general.
My question is related to the FOSUserBundle.
I have a base template which has 2 columns, {% block left %} and {% block right %}
I have created a new file: Base5/UserBundle/Resources/views/layout.html.twig
which extends my 2 column layout
{% extends '::base_2col.html.twig' %}
{% block left %}
I want this text to change depending on wether a login form, register form, profile page etc is displayed
{% endblock %}
{% block right %}
{{ block('fos_user_content') }}
{% endblock %}
as the actual form is rendered using {{ block('fos_user_content') }}, how can i change the text in the right panel depending on what form is displayed, ideally i want to use a different include, containing the various descriptions into texts for the diffirent form.
Any pointers would be very much appreciated.
Found out, just a question of duplicating the templates from the fosuserbundle views directory

Twig the same block in different included files

I have problem with included files. In my layout.html.twig I have scripts.js at the end body section before {% block script %}{% endblock %}. When file extending layout and use script block, its ok, but when use this block and include file whose use the same block, then is problem. Rendered page has all javascripts, but in different places.
For example:
page.html.twig
...
There is page.html.twig
{% include 'file.html.twig' with {'something': 'something'} %}
After include file.html.twig
..
{% block script %}
<script src="file1.js"></script>
{% endblock %}
file.html.twig
There is file.html.twig
{% block script %}
<script src="file2.js"></script>
{% endblock %}
Then rendered page look like this:
There is page.html.twig
There is file.html.twig
<script src="file2.js"></script>
After include file.html.twig
<script src="file1.js"></script>
I want have all javascript files in one place, one by one.
I think you should try to 'embed' instead of 'include'.
http://twig.sensiolabs.org/doc/tags/embed.html
With embedded, you can choose blocks to include.
Ps : If you override a block, you can get the parent block content in using parent() :
{% block script %}
{{ parent() }}
{% endblock script %}
The {% block %} tag and the inheritance system work only with layouts and {% extends %}. It is not meant to be used with includes, so the script block in your included file.html.twig does not merge with page.html.twig.
One solution would be to set a an argument to you included file.
file.html.twig
{% if get == 'content' %}
There is file.html.twig
{% endif %}
{% if get == 'script' %}
<script src="file2.js"></script>
{% endif %}
page.html.twig
...
There is page.html.twig
{% include 'file.html.twig' with {'something': 'something', 'get': 'content'} %}
After include file.html.twig
..
{% block script %}
<script src="file1.js"></script>
{% include 'file.html.twig' with {'something': 'something', 'get': 'script'} %}
{% endblock %}
You will need to conform to a standard practice when dealing with included templates and inheritance (you can invent your own standard).
Try to compartmentalize your includes, I usually have a directory called 'partials' for includes, and 'fragments' for renders. Each one belonging to a single collection of controller views.
One way I dealt with a similar problem to what you are having was to use a base template which covered the requirements of a specific set of views, each view template would extend it. It may be somewhat wasteful to include the javascripts and stylesheets for the entire collection of views for a specific controller, but it is a) more efficient that including all assets everywhere and, b) I manage the view specific assets under a single base template.
So long as the views have a dependency on that base template the structure wouldn't break.
Think of Twig templates as PHP classes (they compile to classes anyway). A class can inherit from one chain of parents. What you are trying to do is treat two sub-classes as a single child of a super class, overriding the same method at the same time. Simply can't be done. An include is closer to a child property, with is own rules and properties. The included template is less dependent on the includer than vice-versa, so it is impossible for it to inherit from it conventionally.

One django template not picking CSS, other templates are fine

I have two django templates in my one folder. The template for the url localhost:8000/people picks CSS correctly which is located at /m/css/style.css
The other template for the url localhost:8000/people/some-name in the same folder is trying to retrieve CSS from people/m/css/style.css
Why is this second template not picking CSS like the first one?
My erring second template is like this:
{% extends "base.html" %}
{% block page_title %}{{ entry.name }} | {{ block.super }}{% endblock %}
{% block main %}
<h1>{{ entry.name }}</h1>
{{ entry.body|linebreaks }}
{% endblock main %}
As you can see there's nothing in the template that could cause problem.
It looks to me like your templates are looking for a stylesheet located at ../m/css/style.css. That's why the template in /people works - /people/../m/css/style.css refers to /m/css/style.css. However, /people/some-name/../m/css/style.cssrefers topeople/m/css/style.css`, not the desired address.
Make sure the templates are looking for /m/css/style.css - emphasis on the very first / character.

Resources