Get cookie from Twig template - symfony

I'm trying to access cookies I set in my Drupal website.
I created two cookies on a form submission :
with the Drupal funtion = user_cookie_save(['myfirstcookie' => 'myfirstdata'])
with the classic PHP function = setcookie('mysecondcookie', 'myseconddata', time() + (86400 * 30), "/")
My cookies are set, no problem.
But, I didn't find how to get them (or one of them) from my Twig templates. The app.request.cookies of Symfony seems to not exist.
Do you have any idea ?

Twig has the global app helper context, via which you can access the cookies (among other things). Try this:
{{ dump(app.request.cookies) }}
And ultimately:
{{ app.request.cookies.get('MY_COOKIE_NAME') }}
Remember, cookies is an instance of ParameterBag (API), so you have to access it via get() call.
Hope this helps...

Past Cookie variable from the controller and check it. It works to me.
My code in controller is:
$data['cookie'] = $_COOKIE['postcode'];
postcode is my cookie name and in my twig templete, i write this line of code
{{ cookie }}
and show my cookie value. Thanks.

Related

Translation of flash messages with parameters in Symfony 4

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

Bolt modifying an record from the web page. Using Twig

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. )

Smarty - url function with parameter

I am using smarty in my symfony3 application.
I would like to generate an url with parameters in smarty based on symfony routing-system:
Activate
This part creates a normal url like:
http://example.com/activation
What i would like create:
http://example.com/activation?key=param
Anyone knows how to create these params and pass them to the url?
Thanks and Greetings!
Try:
{{ url('activation', {'key':'param'}) }}

Modify the title given in hook_menu() from another module

How can I change the title given to the /user/[uid] page from Your account to Welcome [user name] for logged-in user, where [user name] is the username for the currently logged-in user?
Use hook_menu_alter.
Alter the data being saved to the {menu_router} table after hook_menu is invoked.
Code sample:
function MYMODULE_menu_alter()
{
global $user;
if($user->uid != 0)
$items['user']['title'] = 'Welcome ' . $user->name;
}
You should be able to accomplish this with the Menu token module:
Menu Token module provides tokens, that could be used in title or in path of menu items (links).
(It requires the popular Token module.)
Note that with Drupal 7.23, the user.module includes a 'title callback' to determine if the user is logged in or not, and respond with a corresponding title.
Code that worked for me (through theme template, instead of a custom module):
function YOURTHEME_menu_alter(&$items) {
$items['user']['title callback'] = 'YOURTHEME_user_menu_title';
}
function YOURTHEME_user_menu_title() {
global $user;
return user_is_logged_in() ? t($user->name) : t('User account');
}
The String Overrides module should make this easy.
In Drupal 7, hook_menu() and hook_menu_alter() are just invoked when the data about routes implemented from modules needs to be refreshed, for example when a module is enabled, disabled, installed, or uninstalled. An implementation of hook_menu_alter() that uses the name of the currently logged-in user in the title would show the same username for different users.
Differently, the title callback associated with a route is called every time the page associated with that route is rendered.
The correct code would be similar to the following one.
function mymodule_menu_alter(&$items) {
$items['user']['title callback'] = 'mymodule_user_profile_title';
}
function mymodule_user_profile_title() {
global $user;
return user_is_logged_in() ? t('Welcome, #name', array('#name' => format_username($user))) : t('User account');
}
Notice that the first argument of t() needs to be a literal string, not a dynamic value as in t($user->name) because the database table containing the string translations would not contain the translation for every username used in a site.
It is also wrong because the shown username is invariant respect the language used on a site: For example, in an Italian site, a username like Albert isn't translated to Alberto, nor Vincent is translated to Vincenzo.
When showing a username in the UI, it is always preferable to use format_username(), which allows to third-party module to change what shown as username. (For example, a module could show the content of a user field, instead of showing the login username.)
If you aren't willing to write custom code, you could use the String Overrides module. If you don't want to use any module just for changing the title of the user profile page, you could add the following code in the settings.php file used for the site.
$conf['locale_custom_strings_en'][''] = array(
'My account' => 'Welcome to my site'
);
Notice that, either using the String Overrides module or adding the $conf['locale_custom_strings_en'][''] array in the settings.php file, you cannot:
Provide a string that changes basing on the logged-in user (which is what the question is asking for)
Provide a string that is used only on specific pages
The latter case could be a pro or a con. If the string that needs to be changed is generic enough, it would be replaced even when it should not.

How to display dateTime relative to the user location?

I am searching how to display the dateTime related to the user timezone using TWIG.
I really want to understand how it works.
Thank you.
There is no easy solution to get the user location in twig templates.
I would :
Try to get the user's timezone with Javascript
Store this value in a session
Then catch it with twig fron the {{ app.session }} object
Good luck ;)

Resources