New to Symfony I created a login form (make:auth) and installed the translator.
I added in my form template login.html.twig
{% block body %}
<h1>{% trans %}Hello{% endtrans %}</h1>
<form method="post">
...
and defined in translations directory a messages.fr.yml, containing Hello : Bonjour.
That works and when I display my form, hello is well translated to Bonjour
But, all the other labels are not translated (username, password, etc)
which seems to be logical as the entries do not have the {% trans %} {% endtrans %} commands
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputUsername" class="sr-only">Username</label>
question 1 : is there a way to automatically translate all these labels?
question 2 : is there existing translation files containing all the standard used messages / labels?
Thank you for your help
to manage the translation in twig there is the appropriate trans function (example):
<label for="inputUsername" class="sr-only">{{'username' | trans}}</label>
and in your messages.fr.yml add:
username: "Nom d'utilisateur"
The default for form labels is to use a "humanized" version. And that one then may be translated in the messages translation domain.
You can change that by either setting the label on the form (element) directly, either in the builder
->add('fieldName', TextType::class, [
'label' => 'fieldName_translation_key',
])
or in the template:
{{ form_row(form.fieldname, {label: 'fieldname_translation_key'}) }}
{# this also works with form_widget/form_label, depending on the form element #}
If you want to use keyword translations for fields, you can set the label_format on the form itself (in the configure method, as an option) or on all its elements manually (with the placeholders described).
I personally prefer the label_format method because I rarely render the form "manually".
You can also set the translation_domain parameter to change the used translation domain (messages) to something else.
Related
When I have an error in my custom WordPress theme I would like to output the webmaster email address which would be webmaster#mydomainname.com but I am a bit baffled on how to do this in Twig/Timber in the most straightforward way: <p class="text-danger fw-bold">PAGE ERROR - Please contact Webmaster at webmaster#{{ #notsure# }}</p>
webmaster#{{ site.url }} just outputs: webmaster#https://mywordpress.local which obviously won't work.
UPDATED: To get by I am using webmaster#{{ site.url[8 :] }} as that strips away the https:// and outputs webmaster#mywordpress.local but seems there should be a cleaner way somehow?
There are two ways to do this:
You can use Advanced custom field. Make a email field and then print that value inside the twig file. Inside advanced custom field, you can add any email you have no need to extract a domain name. For more information follow this reference: https://timber.github.io/docs/guides/acf-cookbook/
Second method is the way you doing is correct but you need to split domain name from site.url using slice method:
{% set website = "https://mywordpress.local" %} //
//calcualting length of string
{% set lengthOfWebsite = website|length %}
//using length here to split the string accordingly. 8is for split "https://" from actual domain name.
{% set domainName = website|slice(8,lengthOfWebsite) %}
webmaster#{{domainName}}
For the first line of code in your case will be:
{% set website = site.url %}
For the last line
webmaster#{{domainName}}
can also be replaced by:
{% set actualDomainName = 'webmaster#' ~ domainName %}
{{actualDomainName}}
I have a layout included in another one that display my menu. The labels of my menu items need to be dynamic (like the unread messages number of a mailbox). Then I did this :
My orders
(
{{ render(controller('MyController', {'etat':2})) }}
<span style="color:red">with {{ render(controller('MyController', {'etat':2})) }} in late</span>
)
I would like to display labels according to the number that return my controller. I don't know how to get it in a variable.
When rendering your template in your controller
return $this->render('twig_template_name.html.twig', array('variable_name' => $variable);
you pass a variable to the twig template in the array of options as I showed. Your code
{{ path('mypath',{'etat': '2' }) }}
prints a path defined in the routing.yml under the 'mypath' section and ends up adding a GET request variable to the link ('?etat=2'), if 'mypath' showed an absolute route 'www.website.com/yourpath',
{{ path('mypath',{'etat': '2' }) }} would produce 'www.website.com/yourpath?etat=2', which would send your controller for a route /yourpath/{etat} a variable etat with a value of 2 so all you need to do now is change 2 with an actual dynamic value which you receive from another controller.
I am not sure what etat is but lets say it's an article and it has it's id, you have a blog page with lots of articles and the controller that prints them all out sends an array of articles to the twig template, on your twig template you do something like:
{% foreach article in articles %}
{{ article.title }}
{{ article.story }}
read more
{% endforeach %}
And you end up something like:
Catchy Title
Awesome story about code without bugs and where deadlines depend on how creative and well designed and implemented the solutions are
[read more]
and you ofcourse click on "read more" and end up on the url ~/article/2 because the article had an id of 2, your controller for that url receives a variable id in the request, you do a $id = $_GET['id']; and grab the article from the repository and send it to the template.
Hopefully this answered your question, I am very tiered so forgive me if i was confusing which I surely was.
I define a template which built select dropdown inputs for my forms:
<p id="{{key | ucfirst}}">
<span>{{label}} : </span>
<select required disabled>
{% for d in data %}
<option value="{{attribute(d, optionValue)}}" {{(attribute(d, optionValue) == selectedValue)?'selected'}}>{{attribute(d, optionIntitule)}}</option>
{% endfor %}
</select>
<span><em>{{initialValue | default("")}}</em></span>
</p>
Then I just need to include it, and passing it some data:
{% include 'selectForm.twig' with {'label': 'Manager'
, 'key': context.manager.id
, 'initialValue': projet.manager.username
, 'data': users
, 'keyValue': 'id'
, 'keyIntitule': 'username'
, 'selectedValue': projet.manager.id) }
%}
It works fine, but I want to do more. For instance I would like to show a value more usefull for end user into option's label: <option>Username (email)</option> instead of <option>Username</option>
So I think I can't use anymore the attribute function.
I thought I could pass an expression to my template like following:
{% include 'selectForm.twig' with {..., 'keyIntitule': "#{d.username (d.email)}"} %}
But the expression is evaluated with immediate context, not template's one. So it doesn't work.
I also tried with template_from_string but I don't suceed in (I never used this function before...)
Is there a way to pass an expression to another template, and make it evaluate the expression with it's own context?
If you want to block the immediate context you can use include function instead of include tag. Then you can disable context this way (example taken from the documentation) :
{# only the foo variable will be accessible #}
{{ include('template.html', {foo: 'bar'}, with_context = false) }}
I found the solution with Twig's template_from_string function:
{% include 'selectForm.twig' with {..., 'keyIntitule': template_from_string("{{d.username}} ({{d.email}})")} %}
And then I use keyIntitule variable as a template:
<option value="{{attribute(d, optionValue)}}">{% include(keyIntitule) %}</option>
Works also with:
<option value="{{attribute(d, optionValue)}}">{{ include(keyIntitule) }}</option>
If you working with objects you could set keyIntitule to uniqueName and in the user entity define new method:
public function getUniqueName()
{
return sprintf('%s (%s)', $this->getUsername(), $this->getEmail());
}
Twig will call corresponding getter method. In this case uniqueName transforms to getUniqueName()
I'm wondering how to get the current page name, basically 'just' the last parameter in the route (i.e. /news or /about). I'm doing this because I want to be able to have the current page in the navigation highlighted.
Ideally, I'd like to store the current page name in a global variable so that in Twig I can just compare the current page name against the link and add a class accordingly.
I can't figure out how to add the current page name to a global variable though. I've tried using something like this:
$app['twig']->addGlobal('current_page_name', $app['request']->getRequestUri());
at the top of my app.php file, but an 'outside of request scope' error. But I wouldn't like to have to include this in every route.
What's the best way to do this?
If you put it into an app-level before middleware like this, that'll work:
$app->before(function (Request $request) use ($app) {
$app['twig']->addGlobal('current_page_name', $request->getRequestUri());
});
The "page name" part of your question is unclear, are you looking for the current route's name? You can access that via $request->get("_route") even in the before middleware, as it gets called when routing is already done.
You could also generate navigation list directly in stand alone nav twig template. And then import it in to the main template. Then you would only have to get silex to pass to the view the current page identifier. Simplest way... for example from Silex you would have to pass in the "path" variable to your view. Probably it would more convenient to to fetch nav_list from database and pass it in to twig template as global array variable instead. However this example is the simplest you could get to do what you intend.
nav.twig
{% set nav_list = [
["./", "home"],
["./contact", "contact"],
["./about", "about us"]
{# ... #}
] %}
{% set link_active = path|default("") %}
{% for link in nav_list %}
<li><a href="{{ link[0] }}" class="{% if link[0] == link_active %} activeClass {% endif %}" >{{ link[1] }}</a></li>
{% endfor %}
app.php
//...
$app->match('/about', function (Request $request) use ($app) {
return $app['twig']->render('about.twig', array(
'path' => './'.end(explode('/', $request->getRequestUri()))
));
});
//...
I'm displaying some variable retrieved in my database using Twig :
<p>{{ my_variable }}</p>
The thing is this variable may contain html tags, such as "<br />".
Twig seems to automatically call some htmlentities-like function when displaying variables.
Is there any way to disable it so that when I display a variable containing "Hello<br />world !" I get :
Hello
world !
rather than :
Hello<br />world !
Thanks
Use {{ my_variable|raw }} to prevent my_variable from being automatically escaped.
See Twig documentation: http://twig.sensiolabs.org/doc/filters/raw.html
Try using this
{% autoescape false %}{{ my_variable}}{% endautoescape %}
even better: {{ '<br />|raw('html') }} to avoid unescaping other sensible stuff.
If you just want to use linebreaks in the text stored in your database but don't care to use html , you can also use the nl2br filter as in {{ var|nl2br }}. Allows you to use string linebreak character \n in your text. Filter converts it to <br/>