How to print translatable values in twig ( doctrine extension) - symfony

I am using translatable
It can handle the data directly depending on the current locale setting.
However I want to access each data sometimes with ignoring locale setting.
in contoroller.
I can access each data like this.
$transRepo = $em->getRepository('Gedmo\Translatable\Entity\Translation');
$repo = $transRepo->findTranslations($myEntity);
var_dump($repo['en']['comment']);
Then, is there any way to fetch each language data in twig??
{{comment}} // it shows the comment depending on the locale setting.
{{comment | trancelate(en)}} // I want to ignore the locale setting like this.

How about passing the translations to your Twig template since you need to show them:
$translations = $repository->findTranslations($article);
And then in your Twig template you could do something like:
{{ translations.en.comment }}
{{ translations.de.comment }}
{{ translations.fr.comment }}
The official documentation might help.

Related

symfony createQueryBuilder leftjoin with certain selected fields

I made a query for selecting certain fields together with a leftjoin.
However I cannot get it to work both at the same time (have a leftjoin and certain selected fields).
$query = $em->getRepository(Product::class)
->createQueryBuilder('p')
->select('p, p.slug, p.price, p.title_x AS title, pc')
->leftJoin('p.productimgs', 'pc')
->getQuery();
I call the array with
{% for item in article.productimgs %}
but i get the error: Key "productimgs" for array with keys "0, slug, price, title" does not exist
I also tried to call it with the function
{% for item in article.getProductimgs() %}
but then i get this error : Impossible to invoke a method ("getProductimgs") on an array.
I am not so good with doctrine / query building.
The productimages is a onetomany relation in the product entity.
it's a symfony 5 project
All help appreciated, thank you!
Since you are mixing the entities and specific columns in the select the hydrated results will actually be arrays and not Products. You can see it's structure with
{{ dump(article) }}
If you just want to eager load the related product images in the one query use
$query = $em->getRepository(Product::class)
->createQueryBuilder('p')
->select('p, pc')
->leftJoin('p.productimgs', 'pc')
->getQuery();
This will hydrate the results as Products so you can access its properties by the Twig shorthands or as functions:
{{ article.slug }}
{{ article.getSlug() }}
If you access the Product's images it will not execute a new database query to fetch them since you added them to the select part and they were already hydrated into the result objects:
{{ article.productimgs }}
{{ article.getProductimgs() }}

setValue of a form field on twig template

I try to set the user informations who is logged-in on a twig template but I can't find a way.
In particular, I try to make a comments section and I would like the user to write only the comment text.Doing so, I would like to setAuthor( app.user.username) on the template twig because I cannot get user information on the Controller file.
so on my controller file,in the function show, I put this :
if($form->isSubmitted() && $form->isValid() ){
$comment->setCreatedAt(new \DateTime())
->setExercice($exercice)
//would like to do it but cannot
//->setAuthor(app.user.username);
So I search a way to maybe make something like
{{form_row(commentForm.author,{'attr': {
'value': app.user.username,
'class':hidden
}})}}
Is there a way to do it ?
the error I get is :
Variable "hidden" does not exist.
Your original error, Variable "hidden" does not exist., happens because you've attempted to reference hidden as if it were a variable or constant, rather than a literal string. To use it as a literal string you need to quote it:
{{ form_row(commentForm.author, {attr: {
value: app.user.username,
class: 'hidden'
}}) }}
You do not need to quote the keys of the array (e.g. value: and class:) because non-scalar values cannot be used as keys.
However as #msg pointed out you should not rely on the form on the view to obtain the user details. This opens the form up to manipulation, meaning anyone would be able to impersonate other people in any comment posted. Definitely populate that field of the comment entity directly during the controller. -- If you do this prior to checking if the form is submitted that information will be available to the view also, e.g. exposing $comment to the view would mean {{ comment.username }} would also work.

Checking for defined and boolean value of a number of variables in a Twig if conditional

Is there a more elegant way of checking if a variable in Twig is both defined (safe to reference/use) and also check the boolean value of as I am doing below?
I have a number of Twig templates which have messy logic in it like this and i'd rather it was more readable, however I don't know how this is done in Twig.
{% if primaryMethod is defined and paymentInProgress is defined and transactions is defined and not primaryMethod and not paymentInProgress and not transactions %}
You could write your own test to reduce the amount of Twig code you need.
This is fairly simple to do and just requires 2 steps:
First register your test in twig (either directly or use the method getTests in your twig extension
$twig->addTest(new \Twig_SimpleTest('false', null, [ 'node_class' => '\MyProject\Twig\Node\FalseExpressionNode' ]));
Create the test
<?php
namespace MyProject\Twig\Node;
class FalseExpressionNode extends \Twig_Node_Expression_Test_Defined {
public function compile(\Twig_Compiler $compiler)
{
$compiler->subcompile($this->getNode('node'))
->raw('&& $context[\''.$this->getNode('node')->getAttribute('name').'\'] === false');
}
}
Then you could use your test inside twig
{% if primaryMethod is false and paymentInProgress is false and transactions is false %}
sidenote : The test FalseExpressionNode is extending from Twig_Node_Expression_Test_Defined in order to suppress any undefined variables messages when twig is in debug mode

Twig date difference

I've got an entity with a starting date and an ending date.
Is it possible to get the difference in time between them by using twig?
Since PHP 5.3 There is another option without to write an extension.
This example show how to calc the plural day/days
{# endDate and startDate are strings or DateTime objects #}
{% set difference = date(endDate).diff(date(startDate)) %}
{% set leftDays = difference.days %}
{% if leftDays == 1 %}
1 day
{% else %}
{{ leftDays }} days
{% endif %}
Explanation:
PHP 5.3 DateTime object has diff() method which return a DateInterval object with the result difference between endDate and beginDate
Twig
Twig date function always return a DateTime object so we can call diff method
Finally we can access to the properties of the DateInterval object or format it with the Twig date filter.
Note: There is no need of wrap endDate or startDate with the date function if the variable is already a DateTime object.
Note2: DateTime is used here as a synonym of DateTimeInterface.
There's no built-in function to do that, but you can easily do it yourself, extending twig is easy!
The quick'n'easy way is to do it with twig's simple function class:
$function = new Twig_SimpleFunction('date_difference', function ($start, $end) {
// ... calculate difference and return it
});
// assuming $twig is an instance of Twig_Environment
$twig->addFunction($function);
The reusable way is to create a twig extension (documented on the same link). That's still easy.
Also note there is an existing Date extension from Sensio Labs that offer a time_diff filter.
Then you can use it like this:{{ entity.ending_date|time_diff(entity.starting_date) }}
Please note that this plugin is abandonned and not supported with Twig 3 : https://packagist.org/packages/twig/extensions
For Symfony 5, I recommand using the KnpTimeBundle
it provides the twig function |ago
To install : composer require knplabs/knp-time-bundle

Symfony2 / Twig dealing with getting URL query string values

I'm trying to manipulate the query string values in a URL.
I can get the current URL or route either from the Request object or Twig's functions, but it's the query string I'm struggling with.
I don't need app.request.attributes.get('_route_params') as this gets the query string params that are in the route.
I need to get query string params that are actually in the URL.
I want to be able to do the two things listed below in both Symfony2 (in a PHP controller) and Twig (in a Twig template):
Get all current query string values in the URL and display them
Do 1, but change one of the query string values before displaying them
I can't find anyone who knows how to do this.
You can use app.request.query.all to get your query strings.
If you want to change a param in Twig you can do this
{% set queryParams = app.request.query.all %}
{% set queryParams = queryParams|merge({queryKey: newQueryValue}) %}
To get the query string "https://stackoverflow.com?name=jazz"
{{ app.request.query.get('name') | default('default value if not set'); }}
Into controller
use Symfony\Component\HttpFoundation\Request;
public function fooAction(Request $request)
{
$params = $request->query->all();
}
please, pay attention: $request->query->all(); will return an array with keys named as query parameters
Into twig
As long you pass from controller (read this as always) you can pass your parameters to a view in that way
use Symfony\Component\HttpFoundation\Request;
public function fooAction(Request $request)
{
$params = $request->query->all();
return $this->render('MyFooBundle:Bar:foobar.html.twig', array('params' => $params));
}
Into your twig template foobar.html.twig you can access all query string parameters simply by using the params variable.
e.g with this request URL: http://example.com/?foo=bar&secondfoo=secondbar
{% for paramName, paramValue in params %}
<div>{{ paramName }}: {{ paramValue }}</div>
{% endfor %}
<div>{{ params.secondfoo }}</div>
twig output:
<div>foo: bar</div>
<div>secondfoo: secondbar</div>
<span>secondbar</span>
Another method is to use app.request.query.all in twig, without passing anything to twig from your controller.
Final note
If you want to modify one of those parameters when passing an array to twig from your controller, simply change one of the array values, as you would with normal values (i.e.: $params['id'] = $params['id'] - 1;)
Hi Stephen we have tried ur solution to get the value but it going to default value.
http://localhost:4000/about/investors/key-dates-and-events-details?year=2017#q1
i have used like this on my twig file
{{ app.request.query.get('year') | default('default value if not set'); }} Quareter Q1
Please let me know.

Resources