Is it possible to add attributes to Shopify's {% form %} liquid tag? I want to give all my forms id's so that I don't have to rely on parent elements to target their styles.
Yes you can add attributes.
Example:
{% form 'contact', id: "test" %}
Trying to customize Symfony form rendering, I have the following in my config.yml
twig:
form_themes:
- 'form/fields.html.twig'
The form/fields.html.twig contains a customized number widget:
{%- block number_widget -%}
<input type="text" {{ block('widget_attributes') }} value="{{ value|filter }}" />
{%- endblock number_widget -%}
Everything works fine as long as I use default form layout (div). However, if I want the form to have table layout, I try to add something like this in the template:
{% form_theme 'form_table_layout.html.twig' %}
The form gets displayed as table, but then my customized number_widget is no longer customized!
I have also tried:
{% form_theme 'my_cystom_theme.html.twig' %}
with my_cystom_theme.html.twig containing:
{% use 'form_table_layout.html.twig' %}
Did not help.
Question:
Is there a way to make application wide customization of a widget for both div and table layout forms without duplicating the code?
The solution is to use a custom tempalte with multiple 'use' blocks:
create custom table-layout form, for example form/table_layout.html.twig, such as:
{# original table layout template #}
{% use 'form_table_layout.html.twig' %}
{# our custom field widgets #}
{% use 'form/fields.html.twig' %}
{# define more custom widgets for table layout here #}
In order to render a table layout form with our custom widgets, use this in the template:
{# form_theme 'form/table_layout.html.twig' #}
Do the same for div layout. Custom widgets from form/fields.html.twig will be used in both table and div layouts without duplicating the code.
I've got a symfony2 application with multiple styles. All 3 have their own html + css for rendering.
Something like "frontsite", "user dashboard" and "admin backend".
Now there is a difference in form theme to be used in all 3 subsites, so there is a (slightly) different theme for all of them.
Because of this I can set the theme in the symfony configuration, but for 2 of the 3 subsites it will be wrong.
I can set a theme manually using:
{% form_theme form 'MyUberCoolBundle:Form:theme.html.twig' %}
But I don't really want to do that for every form.
I could set that in a base-template, but then my form would always need to be called "form".
Is there a way to set the theme to be used in a base template so it will be used for all forms?
I was looking for something like that. Something to use a theme for FrontOffice and another one to use in the back office.
I got it. I use a normal configuration in the config.yml as normal for the FrontOffice like that:
twig:
globals:
frontend_form_theme: 'form/fields.html.twig'
And then I use in the main BackOffice themplate like layout.html.twig:
{% if oForm is defined %} {% form_theme oForm 'bootstrap_3_layout.html.twig' %} {% endif %}
So, bootstrap defined for all the forms with the name oForm.
So the other answers here work great when your pages only have one form and it's always named something constant, like form. In my scenario, however, I often have multiple forms with different names, so that approach doesn't work. Instead, what I did was create a custom twig function that applies the desired form theme to all forms passed into to the view:
Inside your WhateverTwigExtension.php: (see here for info on writing twig extensions)
class WhateverTwigExtension extends AbstractExtension
{
private $formRenderer;
public function __construct(FormRendererInterface $formRenderer)
{
$this->formRenderer = $formRenderer;
}
public function getFunctions()
{
return [
new TwigFunction('applyFormThemes', [$this, 'applyFormThemes']),
];
}
public function applyFormThemes(array $context, $themes)
{
foreach ($context as $variable) {
if ($variable instanceof FormView) {
$this->formRenderer->setTheme($variable, $themes);
}
}
}
}
Note that for symfony's autowiring to be able to inject the renderer into this extension, you'll have to alias it, so put something like this in your services.yml:
services:
Symfony\Component\Form\FormRendererInterface: '#twig.form.renderer'
Finally, in the base twig for your subsite, simply add:
{{ applyFormThemes(_context, 'my_form_theme.html.twig') }}
Also works for multiple themes:
{{ applyFormThemes(_context, ['my_form_theme.html.twig', 'other_form_theme.html.twig']) }}
And now all forms passed to that view will have your theme applied!
You can also still use the normal form_theme tag to override specific forms, as long as it comes after the applyFormThemes
to set a theme global for your application you can set it in the config
twig:
form_themes:
# Default:
- form_div_layout.html.twig
# Bootstrap:
- bootstrap_3_layout.html.twig
- bootstrap_3_horizontal_layout.html.twig
# Example:
- MyBundle::form.html.twig
See the full Twig config reference here
After looking around for an answer I came to the conclusion it is not possible to do this only in configuration.
We resorted to the following solution
in config.yml we configured a global twig variable:
twig:
globals:
frontend_form_theme: 'MyUberCoolBundle:Form:theme.html.twig'
Then we set the correct theme on the form itself just prior to rendering using the global variable.
This even allows us to use something different when desired.
{% form_theme form frontend_form_theme %}
{{ form_start(form) }}
This is possible, and works well. It assumes you are consistent with naming your root forms however.
First, setup a default form theme like described in the standard docs.
# twig.yaml
twig:
form_themes: ['form.html.twig'] # Default theme and front-end
Override the form theme for the primary form in your admin layout template.
# admin/layout.html.twig
{% if form is defined %}
{% form_theme form "admin/_form.html.twig" %}
{% endif %}
{% block content %}{% endblock %}
...
Optionally override the admin form theme in your final templates, by setting the form theme in the form block. It won't work if you define form theme outside the block. Your custom form theme should probably extend the admin form theme too.
# admin/user/edit.html.twig
{% extends "admin/layout.html.twig" %}
{% block content %}
{% form_theme form "admin/user/_form.html.twig" %}
{{ form(form) }}
{% endblock %}
In my settings for compressor I'm using SlimIt for most of my javascript:
COMPRESS_JS_FILTERS = ['compressor.filters.jsmin.SlimItFilter', ]
Some of my js files shouldn't go through SlimIt though because the file is already minified, or the javascript throws some error when its minified with other files. My template block ends up looking like this:
{# code that I minify #}
{% block compressed_libs %}
{% compress js %}
<script src="/static/js/compress_this.js"></script>
<script src="/static/js/also_compress_this.js"></script>
...
{% endcompress %}
{% endblock %}
{# code that shouldn't minify #}
{% block non-compressible_libs %}
<script src="/static/js/already.min.js"></script>
<script src="/static/js/breaks-everything.js"></script>
{% endblock %}
Can I set different compress filter rules for different blocks/files so that my "non-compressible" files can still be concatenated together by compressor while skipping SlimIt?
As approxiblue said, it doesn't look there's a way to specify which filters to use per compress block in a template (in Compressor 1.5).
I'll update this answer someone comes up with something.
It seems like this could be solved by adding a parameter to the compress template tag to allow it to return a CompressorNode with a flag to skip the filter in base.py hunks()
I'll see what the Compressor community thinks about this, but let me know if you have any ideas.
I have this :
template edit.html.twig
{% extends "....:...:layout.html.twig" %}
{% block body %}
{{ render(controller('EVeilleurFlowerBundle:Catalogue:add' )) }}
{{ render(controller('EVeilleurFlowerBundle:Catalogue:delete' )) }}
{% endblock %}
And the template "add" is basically a single form.
When the user enters "wrong" data in the add form, it automatically redirects to add.html.twig, displaying a single form ( wtih the error ) without layout, css etc...
Can i change the redirection, or am I building my templates the wrong way ? (pretty much newbie here :) )
Thanks