We want to change the way we do the frontends in symfony and we'd like some level of "reflection":
We want the system to be able to detect "Template displayProduct.html.twig needs xxxx other file, defines yyyy block and uses the zzzz variable".
I would like a command similar to:
php bin/console debug:template displayProduct.html.twig
that responds something like this:
Template: displayProduct.html.twig
Requires: # And tells us what other files are needed
- widgetPrice.html.twig
- widgetAvailability.html.twig
Defines: # And tells us what {% block xxxx %} are defined
- body
- title
- javascripts_own
- javascripts_general
Uses these variables: # <= This is the most important for us now
- productTitle
- price
- stock
- language
We are now visually scanning complex templates for needed variables and it's a killer. We need to automatically tell "this template needs this and that to work".
PD: Functional tests are not the solution, as we want to apply all this to dynamically generated templates stored in databases, to make users able to modify their pages, so we can't write a test for every potential future unknown template that users will write.
Does this already exist somehow?
I have a problem with flash messages in Symfony 4 and translation.
Translation of simple flash messages is working fine:
$this->addFlash('success', 'flashmessage.project_deleted');
But now I want to add some parameters to the flash messages and I have no idea how to handle it. I tried a lot, but nothing is working. I want to show in the flash messages the title of projects after f.e. removing. For example:
$this->addFlash('success', sprintf('flashmessage.project_deleted: %s', $project->getTitle()));
But the translation is not recognized, because the parameter is replaces before translation happens (I think so). And it should also be possible to have parameters in the middle of a string and not only at the end or at the beginning and ideally more than one parameter.
I'm using this in my Controller which extends AbstractController.
Does anybody has a solution for this?
Usually you would pass in the parameters to the translation, so your code snippet should probably look your first example and then in twig you would have something like this:
{% for message in app.flashes('success') %}
<div class="alert alert-success">
{{ message|trans({ 'title': project.title }) }}
</div>
{% endfor %}
The translation then should contain the parameter that is replaced:
flashmessage:
project_created: 'The project "%title%" was created successfully.'
project_deleted: 'You successfully deleted the project "%title%".'
...
Obviously the downside is that you have to dynamically pass in the variables which does not make much sense for flash messages, as not all of them will require these parameters. Also, as you already mentioned, when you deleted the project you will probably not have it available anymore in the template.
Instead I would recommend translating the message before passing it into the flash bag:
$this->addFlash(
'success',
$this->translator->translate(
'flashmessage.project_deleted',
[
'title' => $project->getTitle(),
]
)
);
This will require that you pass in the translator to your controller. You could either create your own base controller similar to Symfony's AbstractController for this and create something like a $this->trans()-method to make it easier to translate things inside your controller. Also, you will still have to make sure that $project->getTitle() will still return a value, so you probably want to call this before you actually delete the entry or have the data in memory.
When you do it this way, then you should not translate the flash messages in the template itself because they are already translated. This will still work because when Symfony tries to translate the already translated message, e.g. You successfully deleted the project "foo". then it will not find a translation and just print the original text instead, but you will get warnings in your logs about missing translations. The solution is to remove the |trans in your template (see first snippet).
A possible solution is to add another flash with serialized parameters.
Then, when you display your flash message, check if that extra flash exists and, if so, deserialize it and use it as argument.
Example follows.
In controller:
$this->addFlash('success', 'flashmessage.project_deleted');
$this->addFlash('_params', serialize(['%project%' => $project->getTitle()]));
In template:
{% flashMessage = app.session.flashbag.get('info') %}
{% if app.session.flashbag.has('_params') %}
{% set flashParams = app.session.flashbag.get('_params')|first|unserialize %}
{{ flashMessage|trans(flashParams) }}
{% else %}
{{ flashMessage|trans }}
{% endif %}
You need to create a Twig extension that defines an unserialize filter (or use a library that provides it)
Since Symfony 5.2 you can use the TranslatableMessage object to achieve this.
https://symfony.com/doc/current/translation.html#translatable-objects
use Symfony\Component\Translation\TranslatableMessage;
$this->addFlash(
'success',
new TranslatableMessage(
'flashmessage.project_deleted',
['%project%' => $project->getTitle()]
)
);
Then in your Twig template you only need to use {{ flashMessage|trans }}.
This works without injecting the Translator service, or messing about with anything in Twig.
Have a look at the ICU Message Format: https://symfony.com/doc/current/translation/message_format.html
I have a Symfony 5 website that uses Twig templates containing messages translated with
{% trans %}some.message.key{% endtrans %}
Is there a way to have Symfony output the message key itself instead of the translation? This can be helpful during development and translation work.
To demonstrate what I want, have a look at https://en.wikipedia.org/wiki/Main_Page?uselang=qqx, which shows such behavior in the MediaWiki software.
I've been able to successfully render Jinja Templates using the function within the BaseOperator, render_template.
My question is does anyone know the requirements to get rendered strings into the UI under the Rendered or Rendered Template tab?
Referring to this tab in the UI:
Any help or guidance here would be appreciated.
If you are using templated fields in an Operator, the created strings out of the templated fields will be shown there. E.g. with a BashOperator:
example_task = BashOperator(
task_id='task_example_task',
bash_command='mycommand --date {{ task_instance.execution_date }}',
dag=dag,
)
then the bash command would get parsed through the template engine (since a Jinja field is included) and later on you could see the result of this parsing in the web UI as you mentioned.
The fields must be templated, though. This can be seen in the code in the field templated_fields. For BashOperator (see code here https://github.com/apache/incubator-airflow/blob/master/airflow/operators/bash_operator.py) this is:
template_fields = ('bash_command', 'env')
Other fields in the BashOperator will not be parsed.
You can use macro commands (see here https://airflow.apache.org/code.html#macros) or information from xcom (see here https://airflow.apache.org/concepts.html?highlight=xcom#xcoms) in templated fields.
Im trying to modify records from my wep page using bolt, for lets say an comment section. If someone posts an answer underneath an news item how do i put that info into an record. And if they want to edit their reaction how would I update it.
So i was trying something at this point with the status. My base status is always published.
{{ record.status == draft }} <-- tried this way
{% set record.status == record.status = draft %} <-- tried SET
{% set record.status == record.status = "draft" %} <-- tried adding ""
After my try and error period I went to all the documentation on bolt and twig. But I cant seem to find out how to do this.
So I hope someone knows how to do this, thank you in advance.
short anwser is - you can't modify database records directly from twig.
Twig it's template system (idea is to show data with it) .
To dwhat you want you need to write all this "stuff" by yourself . It can be done (best way is to learn about creating custom modules - but you need to be quite good with OOPHP , symfony components etc. )