I'm trying to set flash message from ContactAction then redirect on Homepage, but on it, I can't see my flash message, maybe my session is reset ? Can I have some help, I'm a beginer on Symfony.
CoreController that contain both index and contact functions :
<?php
namespace OC\CoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class CoreController extends Controller
{
public function indexAction()
{
$ServiceAdverts = $this->container->get('oc_core.listAdverts');
$adList = $ServiceAdverts->getListAdverts();
return $this->render("OCCoreBundle:Core:index.html.twig", array(
'listAdverts' => $adList
));
}
public function contactAction()
{
$this->addFlash('info', 'Contact page not ready yet !');
return $this->redirectToRoute('oc_core_homepage');
}
}
Twig template (homepage) :
{% block body %}
<div>
Messages flash :
{% for msg in app.session.flashBag.get('info') %}
<div class="alert alert-success">
{{ msg }}
</div>
{% endfor %}
</div>
<h2>Liste des annonces</h2>
<ul>
{% for advert in listAdverts %}
<li>
<a href="{{ path('oc_platform_view', {'id': advert.id}) }}">
{{ advert.title }}
</a>
par {{ advert.author }},
le {{ advert.date|date('d/m/Y') }}
</li>
{% else %}
<li>Pas (encore !) d'annonces</li>
{% endfor %}
</ul>
Contact
{% endblock %}
Symfony 3.3 made improvements to flash messages so your Twig template should look different. The app.session.flashBag.get() call is now replaced by app.flashes().
So your Twig code would now be:
{% for msg in app.flashes('success') %}
<div class="alert alert-success">
{{ msg }}
</div>
{% endfor %}
Try this, works for me in 3.2 and 3.4
{% for type, flash_messages in app.session.flashBag.all %}
{% for msg in flash_messages %}
<div class="alert alert-{{ type }}">
{{ msg }}
</div>
{% endfor %}
{% endfor %}
Another thing is that once you called the flashBag it turns empty so you can't use it twice. Check your code that it hasn't been called on another page right before a second redirect ...
Related
hi i am using symfony 5.4, and trying to add html code to uniqueentity message:
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
* #ORM\Table(indexes={#ORM\Index(name="user",columns={"id","credential","nickname","email","status"})})
* #UniqueEntity(
* fields={"email"},
* message="este Correo ya esta en Uso; Dirigete a la Activacion de Cuentas! <a href='/account_activation'>Activate</a>"
* )
*/
class User implements UserInterface, PasswordAuthenticatedUserInterface
in this case I want a link to be shown in the error but I don't get it:
this is the twig template:
{% extends 'base.html.twig' %}
{% block body %}
{# display any flash message #}
{% for label, messages in app.flashes %}
{% for message in messages %}
<div class="alert alert-{{ label }} alert-dismissible fade show">
{{ message }}
</div>
{% endfor %}
{% endfor %}
{{ form(registration_form) }}
{% endblock %}
any idea how i can achieve it?
update
i try to add raw error filter:
{% extends 'base.html.twig' %}
{% block body %}
{{ error.message|raw }}
{% for label, messages in app.flashes %}
{% for message in messages %}
<div class="alert alert-{{ label }} alert-dismissible fade show">
{{ message }}
</div>
{% endfor %}
{% endfor %}
{{ form(registration_form) }}
{% endblock %}
but get this error:
How do you display it on the front? If you use Twig, maybe you forgot to use raw filter?
{{ error.message|raw }}
After two weeks of research:
Use the message property that uses uniqueentity in annotation, it is not the correct way (is a bad practice) if you want to implement any element/structure html.
all properties are encoded to avoid xss attacks, there are 2 ways to follow using the controller:
forget about the html tag and use a direct redirect to the desired path instead of a link:
if (count($form['email']->getErrors(true)) > 0) {
return $this->redirectToRoute('account_activation');
}
implement a custom error handler and display the error concatenated to the html tag:
if (count($form['email']->getErrors(true)) > 0) {
$this->addFlash(
'warning',
'your account need to be activated! Click Here!'
);
}
Note: implementing the second option requires adding the Flash Messages output to the form template.
There is another unverified method that the github site gave me but I could not verify its functionality:
https://github.com/symfony/symfony/issues/44755#issuecomment-999156755
{% extends 'base.html.twig' %}
{% form_theme registration_form _self %}
{% block form_errors %}
{%- for error in errors -%}
{{ error.message | raw }}
{%- endfor -%}
{% endblock %}
{% block body %}
{{ form_errors(registration_form) }}
{{ form(registration_form) }}
{% endblock %}
In symfony 4.1
In the controler:
$this->addFlash(
'notice',
'Your changes were saved!'
);
return $this->render(...);
Twig base template:
{% for message in app.flashes('notice') %}
<div class="flash-notice">
{{ message }}
</div>
{% endfor %}
That works fine, but I want to wrap ALL messages in a div. The below does not work:
{% if app.flashes is not empty %}
<div id="messageBox" class="overlay">
<div class="message" onclick="slide(document.querySelector('#messageBox')); this.classList.add('fadeAway');">
{% for label, messages in app.flashes %}
<section class="{{ label }}">
<p><b>{{ label }}</b></p>
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</section>
{% endfor %}
</div>
</div>
{% endif %}
The problem is that the line {% if app.flashes is not empty %} erases the messages, so the following for loops and empty result.
How do I use peekAll() for the if logic?
The correct way to check with peekAll() is {% if app.session.flashbag.peekAll() is not empty %} This will not clear the flashBag as per documentation.
I do not know if this is the best way to do this, but the following is my solution.
In the base.html.twig:
{% set flashes = app.flashes %}
{% if flashes is not empty %}
<div id="messageBox" class="overlay">
<div class="message" onclick="slide(document.querySelector('#messageBox')); this.classList.add('fadeAway');">
{% for label, messages in flashes %}
<section class="{{ label }}">
<p><b>{{ label }}</b></p>
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</section>
{% endfor %}
</div>
</div>
{% endif %}
Basically, set the returned value of app.flashes to flashes and handle that.
I have little problem. My symfony app after bad login doesn't show error mesage in login file ;/ . After typing good login & pasword everthing is ok, im logged & redirected to dashboard.
Sorry for my English:)
here is my controller
class LoginController extends Controller
{
/**
* #Route("/login", name="login")
*
* #Template()
*/
public function loginAction(Request $Request)
{
$Session = $this->get('session');
// Login Form
if($Request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)){
$loginError = $Request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR);
}else{
$loginError = $Session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
}
if(isset($loginError)){
$this->get('session')->getFlashBag()->add('error', $loginError->getMessage());
}
$loginForm = $this->createForm(new LoginType());
return array(
'loginForm' => $loginForm->createView()
);
}
here is block form_errors code in view file form_template.html.twig:
{% block form_errors %}
{% spaceless %}
{% if errors|length > 0 %}
{% for error in errors %}
<div class="alert alert-danger">
<button class="close" data-close="alert"></button>
<span> {{ error.message|trans }} </span>
</div>
{% endfor %}
{% endif %}
{% endspaceless %}
{% endblock %}
Thanks :)
Try this :)
{% block form_errors %}
{% spaceless %}
{% if errors|length > 0 %}
{% for error in app.session.flashbag.get('error') %}
<div class="alert alert-danger">
<button class="close" data-close="alert"></button>
<span> {{ error|trans }} </span>
</div>
{% endfor %}
{% endif %}
{% endspaceless %}
{% endblock %}
im try get flashData in a Twig template. In the controller i set:
$session = $this->getRequest()->getSession();
$session->getFlashBag()->add('ok_menu', true);
$session->getFlashBag()->add('msg_menu', 'Las selecciones del menu fueron guardadas correctamente.');
And in the profiler, are displayed:
In the template i write this:
{% if app.session.get('ok_menu') is defined %}
{% if app.session.get('ok_menu') %}
<div class="alert alert-success">
<strong>Éxito:</strong> {{ app.session.get('msg_menu') }}
</div>
{% endif %}
{% endif %}
But, in the page not reder the flash messages.
Any ideas ?.
You probably need to access the values from the flashbag property.
{% if app.session.flashbag.has('ok_menu') %}
{% if app.session.flashbag.get('ok_menu') %}
<div class="alert alert-success">
<strong>Éxito:</strong> {{ app.session.flashbag.get('msg_menu') }}
</div>
{% endif %}
{% endif %}
Maybe I'm overlooking something, and hopefully this is done very easy.
I have a form and what I want in the end is the following result:
Fields which:
are mandatory/required
have an error currently
have help
should get an extra a-Tag after the label and an extra div, filled with the help and/or the error, if applicable.
What I got to work is, that required fields get the a-Tag by using this:
{% use 'form_div_layout.html.twig' with field_label as base_field_label %}
{% block field_label %}
{{ block('base_field_label') }}
{% if required %}
<span> </span>
{% endif %}
{% endblock %}
So, what I tried already were different versions of this:
{% use 'form_div_layout.html.twig' with field_label as base_field_label %}
{% block field_label %}
{{ block('base_field_label') }}
{% if required or help is defined %}
<span> </span>
{% endif %}
{% endblock %}
{% block field_row %}
{% spaceless %}
<div class="row">
{% if required or help is defined %}
<div>
{{ form_errors(form) }}
{{ help }}
</div>
{% endif %}
{{ form_label(form) }}
{{ form_widget(form, { 'attr': {'class': 'grid_4'} }) }}
</div>
{% endspaceless %}
{% endblock field_row %}
And I can't get this to work.
So my questions are:
Where do I get the help text from, which can also contain HTML? I tried this within the form builder without success - but at least with an exception:
$builder ->add('subject', 'text', array(
'label' => 'Subject',
'help' => 'Can be formatted content with <strong>HTML-Elements</strong>',
));
How can I tell that the current field has an error (to add a class to the row) and if so also display it? {{ form_errors(form) }} did not output anything, no matter where I place it within `field_row˚.
There is no help text, you have to create Form Extension for field and add it to default options.
Example in SF 2.1 Beta 1:
namespace Webility\Bundle\WebilityBundle\Form\Extension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormViewInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class HelpFormTypeExtension extends AbstractTypeExtension
{
public function buildView(FormViewInterface $view, FormInterface $form, array $options){
$view->setVar('help', $options['help']);
}
public function getExtendedType(){
return 'field';
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'help' => null
));
}
}
And register it as a service:
<service id="webility.form.extension.help" class="Webility\Bundle\WebilityBundle\Form\Extension\HelpFormTypeExtension">
<tag name="form.type_extension" alias="field" />
</service>
For the errors question:
Do you have any errors to print? Check that in controller if validation fails:
echo '<pre>'; print_r( $form->getErrorsAsString() ); echo '</pre>'; exit;
To solve it as stated in my question Maciej Pyszyński's anwser was very helpful.
I solved it in this case in another way, which I also want to post here. According to the manual "Adding "help" messages" I build this:
Note This solution won't work together with the formbuilder and needs some tweaking in twig.
To get the help ''-tags (actually they are divs now) …
{% block field_label %}
{{ block('base_field_label') }}
{% if attr.class is defined and '_hint' == attr.class %}
<div>
<a><span class="help">Help Icon</span></a>
<div class="tooltip">
{% if help is defined %}
{{ help|raw }}
{% else %}
Somebody forgot to insert the help message
{% endif %}
</div>
</div>
{% endif %}
{% endblock %}
To get the right class on an error
{% block field_row %}
{% spaceless %}
<div class="row{% if form_errors(form) %} error{% endif %}">
{{ form_label(form) }}
{{ form_widget(form, { 'attr': {'class': 'grid_4'} }) }}
</div>
{% endspaceless %}
{% endblock field_row %}
And the call from the template
<div class="row{% if form_errors(form.url) %} _error{% endif %}">
{{ form_label(form.field, null, { 'attr': {'class': '_hint'}, 'help': 'Help text or variable containing it' }) }}
{{ form_widget(form.field, { 'attr': {'class': 'grid_4'} }) }}
</div>