symfony2 twig form theme for different subsites - forms

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 %}

Related

orocommerce wysiwyg editor - file / image wrong src

I have similar issue that Wysiwyg images not moved to public cache
when I add a file or image in wysiwyg, it displays properly in editor but after saving, it doesn't display in admin nor front.
Generated markup src is incorrect/not properly replaced:
<picture id="irozi"><source srcset="{{ wysiwyg_image('22','d9ffaffc-f286-4707-bd4b-29504628acc2','wysiwyg_original','webp') }}" type="image/webp"><img src="{{ wysiwyg_image('22','0872c470-f50a-4290-8043-96ffd5e205d2','wysiwyg_original','') }}" id="icysf" alt="test picture"></picture>
my-file.csv
My field already exists (in a custom bundle) and "File applications" doesn't show in "Entity Management".
Do I need that conf? How to achieve it with a migration?
What else should I do to have a correct src for files and images?
File applications config is required if you want to display an image that is ACL protected within the application. You can set it using a migration, e.g.:
$queries->addQuery(
new UpdateEntityConfigFieldValueQuery(
'Acme\Demobundle\Entity\FancyFile',
'image',
'attachment',
'file_applications',
['default', 'commerce']
)
);
The issue might also be related to image processing. Please, check the log file for errors.
UPDATE
Also, as a WYSIWYG field has some twig placeholders it has to be rendered with the applied postprocessing.
On the storefront it should be rendered with:
{% if entity.contentStyle|length -%}
{%- apply spaceless -%}
<style type="text/css">{{ entity.contentStyle|render_content }}</style>
{%- endapply -%}
{%- endif %}
{{ entity.content|render_content }}
There are also ready-to-use layout block types: wysiwyg_style and text_with_placeholders.
On the back-office there is a macro
{% import '#OroEntityConfig/macros.html.twig' as entityConfig %}
{{ entityConfig.renderWysiwygContentPreview(entity.content)|raw }}
Where the entity.content is the field path to render.
The team will update the documentation to mention that.

Adding attributes to Shopify's {% form %} liquid tag

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" %}

How to customize both DIV and TABLE form widgets without duplicating code in symfony

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.

Customize form_row for different form types

I want to set different form_row layout for different form type. I found in templates block named "choice_widget_collapsed", but it render only select tag with options.
I cannot find where this block is being used. Actually it seems that it is rendered instead of form_widget block. I suppose there is somewhere switch/if structure which checks form type and renders appropriate block, but i dont know where to find this switch, or dont know how to check input type inside form_row block.
I know that block type can be found inside form.vars.block_prefixes array, but this sux, because its position may change in the future as it was already.
So the question is: how can i make form_row display different thing depending on form field type?
You should override the normal block in a theme of yours. This block should work like this:
{% block form_appropriate_block %}
{% spaceless %}
{% if form.vars.widget = 'myIntendedWidgetType' %}
[yourTemplate]
{% else %}
{{ parent() }}
{% endif %}
{% endspaceless %}
{% endblock form_appropriate_block %}
And then, in your template, activate your theme using:
{% form_theme form 'MyBundle:Form:formTheme.html.twig' %}
In this way, your form theme is used only when needed, and if the type is not the one you want, it falls back to the normal behaviour.

symfony2 twig form registration included from external template

Be patient is my first question and my english is also poor ;P
Btw... im using fos for my website and all work fine, actually my problem is that i have the "pages" template made with twig and it have, at the bottom, a call to action button that slideDown an hidden div where i want to put my registration form.
I setup the hidden div and try to put inside my include:
{% block fos_user_content %}
{% include "FOSUserBundle:Registration:register_content.html.twig" %}
{% endblock fos_user_content %}
obviously it dosn't work:
Variable "form" does not exist in kernel.root_dir/Resources/JuliusUserBundle/views/Registration/register_content.html.twig at line 2
probably for some reasons related to routing or firewall or security?
anyone have a solutions, suggestions or ideas for that?
thanks and cheers!
As error said, you need to define 'form' variable in your action, or you could try to render FOSUser registration action instead of this.
For example:
{% render(controller(FOSUserBundle:Registration:register")) %}
If you need to use include then you have to pass the form variable to your included template. Optionally you can render that template also from its corresponding controller.
So for the first case you have:
{% include("FOSUserBundle:Registration:register_content.html.twig") with {'form':form} %}
Where form here is the variable you pass from your own controller. Your second choice would be to render the FOSUB template like so:
{% render(controller("FOSUserBundle:Registration:register")) %}
Apparently i found a good solution using Edge Side Includes (ESI) includes that give me also additional benefits in cache control:
<esi:include src="http://localhost:8004/login" />