Symfony - translations stop working after rendering controler in another's view - symfony

I'm building a webiste, where there will be lots of "widgets" displayed on the front page. One of them is the calendar.
I wanted to make a new controller for each this "widget", and then render them all (like the example below), in the Homepage view.
Hovewer - the translations stop working after that. If I visit mywebpage/calendar, they work, but not when I got to mywebpage/home.
This is the code I currently have for my Homepage view.
{% block Calendar %}
{{ render(controller('MyWebsite:Calendar:index')) }}
{% endblock %}
Am I approaching this correctly or not? And why do the translations stop working?
Also - I hope you will understand what the issue is :)
Thanks!

I am surprised that doesn't work, do you have anything else in your app interfering with the Request object?
Maybe passing the locale from the request as an argument to the controller may work (although a bit of a hack)?
{% block Calendar %}
{{ render(controller('MyWebsite:Calendar:index', { _locale: app.request.locale })) }}
{% endblock %}

Related

app.user variable empty (or not available?) in twig custom error message

According to symfony docs, the variable app is available "everywhere" for twig templates. I want to use app.user in a custom error message, but this variable does not actually seem to be available within these templates while in prod mode; it IS available in dev mode.
Example code:
// project/templates/bundles/TwigBundle/Exception/error404.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{{ parent() }}
<div>
<h1>Page not found</h1>
<p>
Hello {{ app.user.name }}, {% <---- DOES NOT WORK %}
The requested page couldn't be located. Checkout for any URL
misspelling.
</p>
</div>
{% endblock %}
This is just a simple example, but illustrates the point. I've also tried to use
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
// do something fancy
{% endif %}
and this also does not work. It also does not matter whether I extend base.html.twig or pull in the parent(), in all cases it does not work. I get no error messages at all. I have cleared by cache.
Any ideas about how to get this information to my template in prod mode?
I found in the documentation that the problem I describe is by design. From the docs:
Security & 404 PagesĀ¶
Due to the order of how routing and security are
loaded, security information will not be available on your 404 pages.
This means that it will appear as if your user is logged out on the
404 page (it will work while testing, but not on production).
The answer is to create my own exception controller (or extend the default ExceptionController).

CollectionType custom prototype via form_theme

I want to customize the way an entry of a CollectionType in a form will be rendered, that is the way the prototype is generated, I need my own HTML. So I need to do it with the Twig form_theme, but it doesn't work.
I am currently using Symfony 4.1.2.
Here is what I have for now:
In the template that renders the whole form:
{% form_theme form.additionalEmails.vars.prototype 'form/additionalEmail.html.twig' %}
In the form/additionalEmail.html.twig file:
{% block form_row %}
<div style="margin: 10px 0">
{{ form_label(form) }}
{{ form_widget(form.children.value) }}
<div>Recevoir les mails de type : {{ form_row(form.children.isUsedForAdminCommChannel) }}{{ form_row(form.children.isUsedForInfosPratiquesCommChannel) }}{{ form_row(form.children.isUsedForAgendaCommChannel) }}</div>
</div>
{% endblock %}
If I do that I get this error:
Key "value" does not exist as the array is empty.
What is weird is that if I replace the above code by this (by commenting the old one and adding the new line):
{{ dump(form.children) }}
I see that form.children is an array with 4 items and one named "value" so it is clearly broken.
Your help would be much appreciated, as I'm just an amateur dev trying to make a website for a youth movement ^^
Best Regards,
[EDIT]
Here is the form that includes the CollectionType:
https://gist.github.com/MrPOC/a4af94cc5e577a1244dac59de5ea3506
The field is named "additionalEmails"
Just so I understand you correctly. You have a Form which contains a CollectionType and you want to change the prototype of that CollectionType?
If yes could you please post the Form with the CollectionType?
EDIT: Ok so here's how to overwrite the prototype template for a CollectionType.
First we have to find out what your forms unique_block_prefix is. You can find this by going to the page where this form is rendered, you then click in the symfony debug bar on the form icon. Then you have to expand the View variables block and look for unique_block_prefix.
I assume your block prefix could look like this _user_type the name of the block you would overwrite would then be _user_type_additionalEmails_entry_widget (for more details please read the link provided below)
You can replace the widget part with row or label depending on what you want to overwrite (I would suggest trying to overwrite them all to see what exactly changes because I don't know of the top of my head)
In twig you would then take your block prefix and overwrite the prototype field in the same way you would overwrite any other field
{% block '_user_type_additionalEmails_entry_widget' %}
//Content
{% endblock %}
What I wrote down here is what I found out after reading https://github.com/symfony/symfony-docs/issues/6056 (read HeahDude' comment specifically)
I hope this helps!

How to pass user informations to a template using Symfony2 and FosUserBundle

I'm using symfony2, I installed FosUserBundle and I created a bundle UserBundle as indicated in the FosUserBundle online docs. so far so good.
I also created another controller and I'm able to access the logged user information in this way:
$user = $this->container->get('security.context')->getToken()->getUser();
now imagine that in my website, for all the pages/controller, I need to display some user information, even a simple "Welcome MyUser" at the top of the page (so in base.html.twig). I don't want to replicate the line above in all the controllers, so where is the best place to get this information once and pass them to the base template?
For the example you gave, "Welcome MyUser" , you can get this var in twig template with
{% if is_granted("ROLE") %}
Hi {{ app.user.username }}
{% endif %}
This is, if you don't need logic
Also if you didn't knew it you can use heritage in twig, so that you can create a navbar.html.twig with this fosuser var in it, and then in all your templates do
{% extends "AcmeMyBundle::navbar.html.twig" %}
{% block body %}
....
{% endblock %}

Overriding FOSUserBundle layout.html.twig when using a custom app path

I've followed the instructions for overriding the default layout.html.twig, but although my paths seem correct, the replacement template seems to be ignored.
I think this might be because I'm using a custom app path (/app/web) but as everything else appears to be working correctly, it seems strange that this would be the cause.
I have placed my alternate layout at app/web/Resources/FOSUserBundle/views/layout.html.twig
and the source is as follows:
{% extends 'AcmeWebBundle::base.html.twig' %}
{% block content %}
{% block fos_user_content %}{% endblock %}
{% endblock %}
Is there some way I can check which paths are being checked for an alternate template?
Nevermind - I cleared the dev cache and it's now working, doh.

In Symfony2 -> Twig, how to detect if the execution is from CLI mode or through browser?

I am making a Symfony2 console command that will send a e-mail rendering a Twig template.
The e-mail template uses some standard layout that is also included in the e-mails sent from browser requests.
In this template i have some links like this:
{{ url('deal_category_index', {'city':app.session.get('system.user.city'), 'slug':cat.getSlug()}) }}
But if i use the app.session in CLI mode, i get this error:
An exception has been thrown during the rendering of a template ("You cannot create a service ("request") of an inactive scope ("request").")
So i need a way to know if the template is rendered from CLI so i can use a "generic" way to create this link.
Thank you!
Extract the city from the session in the controller and pass it to the render() function. This way, your template should look like:
{{ url('deal_category_index', {'city': city, 'slug':cat.getSlug()}) }}
And in your controller:
$this->render("YourBundle:Yourcontroller:yourView.html.twig', array('city' => $this->get('session')->get('system.user.city'), 'cat' => $category);
When calling the render() in CLI, you should grab the city from database instead of the session.
Wrap the layout part depending on the request context in a block:
{% block foobar_url %}
{{ url('deal_category_index', {'city':app.session.get('system.user.city')}) }}
{% endblock %}
Use this layout in the emails sent from browser context just as you did before.
Override the code block foobar_url in your CLI templates like so:
{% block foobar_url %}
{{ url('deal_category_index', {'city':cityRetrievedFromDatabaseOrElsewhere}) }}
{% endblock %}

Resources