I'm trying to override some fields of bootstrap_4_layout.html.twig, but i found some problems with radio_widget block. I need to change the div element to label, but when I ovverride the block, the radio element is duplicated on view. The div in question is that with class custom-control
{% block radio_widget %}
{% set parent_label_class = parent_label_class|default(label_attr.class|default('')) %}
{% if 'radio-custom' in parent_label_class %}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) %}
<div class="custom-control custom-radio{{ 'radio-inline' in parent_label_class ? ' custom-control-inline' }}">
{{ form_label(form, null, { widget: parent() }) }}
</div>
{% else %}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) %}
<div class="form-check{{ 'radio-inline' in parent_label_class ? ' form-check-inline' }}">
{{ form_label(form, null, { widget: parent() }) }}
</div>
{% endif %}
{% endblock radio_widget %}
Analizyng the dom with the console, I see that are created two element with custom-control class. Why?
I found the solution. I override the block radio_widget and changed the div element with label:
{% block radio_widget %}
{% set parent_label_class = parent_label_class|default(label_attr.class|default('')) %}
{% if 'radio-custom' in parent_label_class %}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) %}
<label class="custom-control custom-radio{{ 'radio-inline' in parent_label_class ? ' custom-control-inline' }}">
{{ form_label(form, null, { widget: parent() }) }}
</label>
{% else %}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) %}
<div class="form-check{{ 'radio-inline' in parent_label_class ? ' form-check-inline' }}">
{{ form_label(form, null, { widget: parent() }) }}
</div>
{% endif %}
{% endblock radio_widget %}
Then I override also the block checkbox_radio_label. Inside it I substituted the base code:
// ...
{{ widget|raw }}
// ...
With:
{% set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) %}
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
For reference about bootstrap 4 twig blocks see this link:
https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
Related
I followed the directions for the second way to tag a product to a blog
This is the website I used https://happypoints.io/shopify-add-products-to-blog-post-c2-stt-66/ This is the code that was entered {% assign my_description = article.content | split: '=== split content ===' %}
{% assign my_description_size = my_description.size | minus: 2 %}
{{ my_description | first}}
<div class="show-product-list">
{% if article.tags.size > 0 %}
{% for tag in article.tags %}
{% paginate collections.all.products by 100 %}
{%- for product in collections.all.products -%}
{% if product.handle == tag %}
<div class="product_item">
{% include 'product-card-list' %}
</div>
{% endif %}
{%- endfor -%}
{% endpaginate %}
{% endfor %}
{% endif %}
</div>
{{ my_description | last}}
after following all the directions I received an error message saying
Liquid error (sections/article-template.liquid line 42): Could not find asset snippets/product-card-list.liquid
I am not sure why the product wont link to the blog using the seo handle. I have copied and pasted this code correctly and still getting this error
Collection code:
{% if collection.title == blank %}
{% assign collection_image = blank %}
{% elsif collection.image %}
{% assign collection_image = collection.image %}
{% else %}
{% assign collection_image = collection.products.first.featured_media.preview_image %}
{% endif %}
{% unless collection.title == blank %}
{% include 'card-image', type: collection_image, grid_style: grid_style %}
{% else %}
<div class="card__image-wrapper">
{% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %}
{{ 'collection-' | append: current | placeholder_svg_tag: 'placeholder-svg' }}
</div>
{% endunless %}
<div class="card__info">
<h3 class="card__name h4">{% if collection.title != blank %}{{ collection.title }}{% else %}{{ 'homepage.onboarding.collection_title' | t }}{% endif %}</h3>
{% if section.settings.show_description and collection.description != blank %}
<div class="rte card__description{% if width == '2' %} card__description--padding{% endif %}">
{{ collection.description | strip_html | truncatewords: 15 }}
</div>
{% endif %}
</div>
You have correctly copy/pasted the code.
The problem is that your theme does not have a file named "product-card-list" in the snippets folder.
This is the file which contains code for the product tiles on the collection pages and the name for this file might differ in the theme that you're using.
You will need to find out the correct file name and replace "product-card-list" with that.
Can help you further if you share the code in your collection.liquid file.
I am working on Symfony 3 and I have some trouble with my form.
When I create a Symfony form with a field not required, here is my code :
I create the form :
$form = $this->createFormBuilder()
->add('prenom' TextType::class, array(
'label' => 'Votre prénom',
'required' => false
)
->getForm();
Here is the code in my view for this field:
{{ form_label(form.prenom) }}
{{ form_errors(form.prenom) }}
{{ form_widget(form.prenom) }}
And this is the HTML I have :
<label class="control-label" for="contact_prenom">Votre prénom</label>
<input type="text" id="contact_prenom" name="contact[prenom]" class="form-control"/>
Now if I do the same without the 'require' => false on my FormBuilder, here is the HTML I get:
<label class="control-label required" for="contact_prenom">Votre prénom</label>
<sup class="required" title="Champ obligatoire">
<i class="fa fa-asterisk"></i>
</sup>
<input type="text" id="contact_prenom" name="contact[prenom]" required="required" class="form-control" />
Is it possible to control the "sup" tag so the asterisk * can be with my label?
I guess I can do it with jQuery, but I'd like to know if it is possible to do it on my form builder or in Twig?
In the doc there is a specific section here http://symfony.com/doc/current/form/form_customization.html#adding-a-required-asterisk-to-field-labels
You can even do with CSS only
label.required:before {
content: "* ";
}
As of Symfony 5.1 you can do the following
->add('name', TextType::class, [
'label' => 'Name <span class="badge badge-danger badge-pill">Required</span>',
'label_html' => true
])
The label_html (bool) property will allow HTML to be injected into the label directly and render on the form output.
Documentation - https://symfony.com/doc/current/reference/forms/types/form.html#label-html
Yes, you could override the twig template or the block that symfony uses to render your widget, have a look at:
http://symfony.com/doc/current/templating/overriding.html
In your case, you're looking for
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
And this would be the block you want to override:
{%- block form_label -%}
{% if label is not same as(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif -%}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif -%}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<label{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}</label>
{%- endif -%}
{%- endblock form_label -%}
I've implemented IvoryCKEditorBundle in my SYMFONY 3.2 project.
I followed the guidelines from here and had an overview of the doc on the official Symfony site.
Now I see the following files exits in the IvoryCKEditorBundle directory:
[my
project]\vendor\egoloen\ckeditor-bundle\Resources\views\Form\ckeditor_widget.html.twig
[my
project]\vendor\egoloen\ckeditor-bundle\Twig\CKEditorExtension.php
And [my
project]\vendor\egoloen\ckeditor-bundle\Resources\views\Form\ckeditor_widget.html.twig defines {% block ckeditor_widget %}.
In my projet I have redefined my own template to render a form, using all the tricks given in the official doc. And under [my project]\src\MyBundle\Resources\views I have a file input_inline_template.html.twig which looks like that:
{% extends 'form_div_layout.html.twig' %}
{% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %}
{% block form_row %}
<div class='col-12' id={{ id ~ '_div_row_id'}}>
{% block form_label %}
<div class='col-4' id={{ id ~ '_div_label_id' }}>
{{ parent() }}
</div>
{% endblock %}
{% if form.vars.block_prefixes.2 == "textarea" %}
{% if (form.vars.block_prefixes.3 is defined) and (form.vars.block_prefixes.3 == "ckeditor") %}
{% block ckeditor_widget %}
<div class='col-8'>
{{ parent() }}
</div>
{% endblock %}
{% else %}
{% block textarea_widget %}
<div class='col-8'>
{{ parent() }}
</div>
{% endblock %}
{% endif %}
{% endif %}
</div>
{% endblock %}
This does not work. It tells me that it cannot find the ckeditor_widget if I don't have the line {% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %} it throws the error:
Block "ckeditor_widget" on template "form_div_layout.html.twig" does not exist in "form_div_layout.html.twig".
And when the line {% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %} is implemented, it throws an error that is:
Unable to find template "CKEditorBundle:Form:ckeditor_widget.html.twig"
It tells me it looks for CKEditorBundle:Form:ckeditor_widget.html.twig in:
[my_symf_project]\app/Resources/views, [my_symf_project]\vendor\symfony\symfony\src\Symfony\Bridge\Twig/Resources/views/Form, [my_symf_project]\vendor\knplabs\knp-menu\src\Knp\Menu/Resources/views.
I don't know how to configure in [my project]\app\config\config.yml that it should look in [my project]\vendor\egoloen\ckeditor-bundle\Resources\views\Form\ to find ckeditor_widget.html.twig.
I found a hint here.
In [my project]\src\MyBundle\Resources\views\input_inline_template.html.twig, I've replaced: {% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %} with: {% use 'IvoryCKEditorBundle:Form:ckeditor_widget.html.twig' %}.
It fixed it.
everybody i'm trying to add a captcha to my form with Gregwar/CaptchaBundle but i face a probleme :
Variable "captcha_code" does not exist when i pay this part of my code :
========================================================================
<div class="col-sm-8 col-sm-offset-2">
{% block captcha_widget %}
{% spaceless %}
<img src="{{ captcha_code }}" title="captcha" width="{{ captcha_width }}" height="{{ captcha_height }}" />
{{ form_row(form.captcha) }}
{% endspaceless %}
{% endblock %}
</div>
Variable form inside of widget block already contains the captcha field (not the whole form), so the correct way is to use form_widget(form) instead of form_row(form.captcha) :
{% block captcha_widget %}
{% spaceless %}
<img src="{{ captcha_code }}" title="captcha" width="{{ captcha_width }}" height="{{ captcha_height }}" />
{{ form_widget(form) }}
{% endspaceless %}
{% endblock %}
thank you but i figured out it by myselfe the best way to solve my problem was to
configure captcha field in my form builder
$builder->add('captcha', 'Gregwar\CaptchaBundle\Type\CaptchaType',array(
'width' => 200,
'height' => 50,
'length' => 6,
'quality' => 90,
'distortion' => true,
'background_color' => [115, 194, 251],
'max_front_lines' => 0,
'max_behind_lines' => 0,
'attr' => array('class' => 'form-control',
'rows'=> "6"
)
));
and in my twig template only call this small part of code :
<div class="col-sm-8 col-sm-offset-2">
{% block captcha_widget %}
{% spaceless %}
{{ form_row(form.captcha) }}
{% endspaceless %}
{% endblock %}
</div>
To validate a form I am using a standard:
{{ form_widget(form.save, {'attr': {'class': 'btn btn-sm btn-danger'}, 'label': 'Submit form'}) }}
I want to insert a fontawsome icon in the button. I tried:
{{ form_widget(form.save, {'attr': {'class': 'btn btn-sm btn-danger'}, 'label': '<i class="fa fa-envelope-o"></i> Submit form'}) }}
But it is not working; obviously
Any idea how to that?
I would define a new form template in the same view (or in a template if you need to reuse the code). More details here
{% extends '::base.html.twig' %}
{% form_theme form _self %}
{%- block submit_widget -%}
{%- set type = type|default('submit') -%}
{%- if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
<i class="fa fa-envelope-o"></i>
{{ label|trans({}, translation_domain) }}
</button>
{%- endblock submit_widget -%}
{% block content %}
{# ... render the form #}
{{ form_row(form.age) }}
{% endblock %}
EDIT
You can also extend ButtonType to allow icon_before and icon_after in order to add icons easily in form definition :
$form->add('submitReportV2Show', SubmitType::class, array(
'label' => 'My test',
'icon_before' => 'fa-refresh',
'icon_after' => 'fa-refresh',
'attr' => array('class' => 'btn btn-sm btn-success'
)));
Create a new class src/bundle/Form/Extension:
namespace YourBundle\ToolBoxBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class IconButtonExtension extends AbstractTypeExtension
{
public function getExtendedType()
{
return ButtonType::class;
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['icon_before'] = $options['icon_before'] ?? '';
$view->vars['icon_after'] = $options['icon_after'] ?? '';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'icon_before' => null,
'icon_after' => null
]);
}
}
Declare it in service src/bundle/Resources/config/service.yml
bundle.tools.form.type_extension.icon_button:
class: YourBundle\ToolBoxBundle\Form\Extension\IconButtonExtension
tags:
- { name: 'form.type_extension', extended_type: 'Symfony\Component\Form\Extension\Core\Type\ButtonType' }
app/Resources/views/Form/fields.html.twig
{%- block button_widget -%}
{%- if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- elseif label is same as(false) -%}
{% set translation_domain = false %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
{% if icon_before is defined and icon_before is not null %}
<i class="fa {{ icon_before }}"></i>
{% endif %}
{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}
{% if icon_after is defined and icon_after is not null %}
<i class="fa {{ icon_after }}"></i>
{% endif %}
</button>
{%- endblock button_widget -%}
sdespont's answer is the correct answer and worthy of being selected. I have, however, extended the functionality of it to include adding the custom fa class icon as well as whether the icon is placed to the left or right of the button text.
Since this functionality accepts variables the best thing to do is to create a template to be reused instead of customising just the view.
Form template: app/Resources/views/form/submit.html.twig
{# app/Resources/views/form/submit.html.twig #}
{% block submit_widget %}
{% set type = type|default('submit') %}
{% if label is empty %}
{% if label_format is not empty %}
{% set label = label_format|replace({
'%name%' : name,
'%id%' : id,
}) %}
{% else %}
{% set label = name|humanize %}
{% endif %}
{% endif %}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
{% if fa is defined %}
{% if left is defined and left %}
<i class="fa {{ fa }}"></i>
{% endif %}
{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}
{% if right is defined and right %}
<i class="fa {{ fa }}"></i>
{% endif %}
{% else %}
{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}
{% endif %}
</button>
{% endblock submit_widget %}
Controller:
$form = $this->createFormBuilder($user)
...
->add('submit', SubmitType::class, array(
'attr'=> array('class'=>'myclass')
))
->getForm();
Twig template:
{{ form_widget(form.submit, {'fa' : 'fa-long-arrow-right','right' : true}) }}
You can set any old fa icon and even sizing like so: fa-long-arrow-right fa-2x
The easiest, you can put your button with html and form vars:
<button type="submit" name="{{ form.send.vars.full_name }}" id="{{ form.send.vars.id }}" class="btn btn-sm btn-danger"><i class="fa fa-envelope-o"></i></button><
You can just add a new custom service css class per icon
/*
* css selector for a class attribute that starts with "btn-fa-" or has " btn-fa-" in it:
*/
[class^="btn-fa-"]:before,
[class*=" btn-fa-"]:before
{
font-family: "Font Awesome 5 Free";
font-weight: bold;
margin: 0 6px 0 2px;
}
/*
* And then only 1 setting per font awesome class
*/
.btn-fa-plus:before {
content: '\f067';
}
And add the class to the ButtonType
->add('Add an item', ButtonType::class, [
'attr' => [
'class' => 'btn btn-primary btn-fa-plus',
]
])
In YourFormType.class -> buildForm
->add('submit', SubmitType::class, [
'attr' => [
'class' => 'main-btn primary-btn',
],
'label' => '<i class="fas fa-search"></i> Search',
'label_html' => true,
])