Silex: translation not working in Twig - php

Currently, I develop a website by using the PHP micro-framework Silex. Now I try to use "TranslationServiceProvider" to translate my website into different languages. To achieve this, I have set the "locale" parameter :
$app->register(new Silex\Provider\TranslationServiceProvider(), array(
'locale' => 'pt'
));
Then, in my controller, I call the function "setLocale", like this:
$app['translator']->setLocale('it');
Now, if I display, always in my controller, the result of the translation its works fine:
$app['translator']->trans("hello"); // return "Buongiorno"
$app['translator']->getLocale(); // return "it"
But, if I call the same function in my template Twig, translation does not work:
{{ app.translator.trans('hello') }} // return: "Olá"
{{ app.request.locale }} // return: "pt"
So, I don't understand: translation works fine in my controller but when I want access translations in Twig, nothing happens.
Do you have any idea about what's going on?

Finally, I've found a solution to resolve my problem. In my "app.php" file, I have added the following code :
$app->before(function () use ($app) {
if ($locale = $app['request']->get('lang') or $locale = $app['request']->getSession()->get('_locale')) {
$app['locale'] = $locale;
$app['request']->setLocale($locale);
}
});
Then, I've written a function in my controller to change language:
public function changeLanguageAction(Request $request, Application $app, $language)
{
$app['request']->getSession()->set('_locale', $language);
return $app->redirect($app["url_generator"]->generate('index'));
}
Now, when I call "changeLanguage" function, all the translations work fine.
I don't know if this solution is a good practice but it works...

Related

Using a PHP function in Twig

I have a PHP code to add a new class for my Twig template in my common controller in: "opencart\htdocs\catalog\controller\common\cart.php"
The code should check if the Device is Mobile or not.
function onStart()
{
// Anonymous Class only working on PHP7
$this['code'] = new class {
public function MobileDetect() {
return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo
|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i"
, $_SERVER["HTTP_USER_AGENT"]);
}
};
}
But now I don´t know how to address that function correctly from my twig side at:
opencart\htdocs\catalog\view\theme\default\template\common\cart.twig
I tried something like this, but it didn´t seem to work:
{% if code.MobileDetect() is defined %}
If a device is mobile I want to use a completely different HTML construct.
What you need to do is create your own Twig function:
https://twig.symfony.com/doc/3.x/advanced.html#functions
So using their examples you should be able to do something like
$function = new \Twig\TwigFunction('MobileDetect', function () {
return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo
|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i"
, $_SERVER["HTTP_USER_AGENT"]);
});
$twig->addFunction($filter);
Then call it like
{% if MobileDetect() %}

EasyAdmin3 / Symfony / Twig - url generator with route name and params in Twig template

I'm trying to generate EasyAdmin3 url inside my template with some params, but for some reason they are not present in a controller.
Twig template:
xxx
yyy
Error with missing EA context:
zzz
Controller:
/**
* #Route("/admin/something/{id}", name="rounte_name")
*/
public function xyz($id = null, Request $request, AdminContext $context)
{
dd($_GET['id'], $request->request->all(), $context->getRequest()->request->all());
...
}
The $_GET['id'] works, but request and context are empty [].
Any idea how to generate route by name with params?
Thanks
I don't think you need the ea_url() helper function if you are just generating regular named routes in twig. You should be able to use the path() twig extension provided by Symfony.
{{ path(route_name, route_parameters = [], relative = false) }}
If you are trying to create a link to an EasyAdmin controller action, then you can use the ea_url() helper, but you have to specify the controller and action as well. Try something like:
{% set url = ea_url()
.setController('App\\Controller\\Admin\\FoobarCrudController')
.setAction('customFooAction')
.setEntityId(entity.instance.id)
.set('myParam', 'baz') %}
Custom Foobar Action
Then in your controller, everything should be available as per usual via the $context variable...
public function customFooAction(AdminContext $context)
{
$entity = $context->getEntity()->getInstance();
$myParam = $context->getRequest()->get('myParam');
}
This works for me, I hope it helps. 🙂

Slim 2 Render Direct HTML

I have an old project I'm working on using Slim version 2. I can not upgrade to 3.
I'm trying to integrate twig into slim 2 while also keeping the old default slim2 renderer.
Currently I have this.
class TwigView extends \Slim\View
{
public function rendertwig($template,$data = array()){
global $twig;
$twigResults = $twig->render($template,array('test' => '1'));
$data = array_merge($this->data->all(), $data);
return $this->render($twigResults, $data);
}
}
$view = new TwigView();
$config['view'] = $view; //#JA - This command overides the default render method.
//#JA - Intialize Slim
$app = new \Slim\Slim($config);
The idea is that I would call this saying $app->view->rendertwig('file.twig') when I need to render the twig templates and use $app->render('template.php') for all the other templates that use the default slim2 method of templating.
However, I get an error because in my rendertwig function $this->render() function requires a template name for the first parameter. Is there a way I can render directly the results from twig into the slim engine without needing a template file?
I'm aware this is bad form to have two templating engines but eventually I will switch everything to Twig but I need this as a temporary solution till I can patch everything over.
When I inspected slim's view object it has this defined as its render method which will explain the issue.
protected function render($template, $data = null)
{
$templatePathname = $this->getTemplatePathname($template);
if (!is_file($templatePathname)) {
throw new \RuntimeException("View cannot render `$template` because the template does not exist");
}
$data = array_merge($this->data->all(), (array) $data);
extract($data);
ob_start();
require $templatePathname;
return ob_get_clean();
}
I don't know if this is bad form but I did this as a temporary solution.
class TwigView extends \Slim\View
{
public function rendertwig($template,$data = array()){
global $twig;
$twigResults = $twig->render($template,array('test' => '1'));
echo $twigResults;
}
}
I saw that all the render method did was just require the template so I figured its safe to just echo the results from the twig templating engine? This seemed to work from my test.

Twig translate whole text of rendered view

Using Twig I render a particular view. I need this view to be translated into a language I choose. I display the view using:
return $this->setup->twig->display($view, $params);
Where $view is the name of the *.html.twig template and $params is an array with the parameters I need to pass.
However, if I want to translate the template before displaying it, how I have to do it?
Currently I have included .yml files for different languages and I have also replaced the text inside the views with the appropriate corresponding values from the yml file.
Apart from everything else, I have also loaded the Twig translator in a file separate from the rest of the project. It has the following code:
require dirname(__DIR__) . '/vendor/autoload.php';
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\ArrayLoader;
class Translation
{
public $translator;
public function translator()
{
$this->translator = new Translator('fr_FR');
$this->translator->addLoader('array', new ArrayLoader());
$this->translator->addResource('array', array(
'Symfony is great!' => 'J\'aime Symfony!',
), 'fr_FR');
var_dump($this->translator->trans('Symfony is great!'));
}
}
$show = new Translation;
$show->translator();
And it really displays the translation.
Still, I have no idea how to connect everything together....
Did you try to set the locale before rendering your twig view?
public function exampleAction(Request $request) {
$locale = 'de'; // Set the language
$request->setLocale($locale);
$content = $this->renderView($view, $params);
// Maybe return to default locale....
}

output printer ESC codes from twig in Symfony

I have a system that uses Symfony, and is connected to a (citizen ct-s2000) POS printer.
What I currently do is render the string to send to the printer, using the twig service:
$this->templatingService->render('SamPosBundle:Ticket:template1.html.twig', array('order' => $order))
and send this to the printer using fwrite, after that I feed the paper 1 line and cut the paper using:
fwrite($handle, chr(hexdec('0A')));
fwrite($handle, chr(hexdec('1B')).chr(hexdec('69')));
This all works like a charm, however.
Now I am looking for a way to send the escape codes from WITHIN the twig template
so that I can use the codes to underline etc., and finally cut the paper, from inside the twig template.
I'm sure this would involve a twig extension to create an additional filter, which I know how to make, I just don't know WHAT EXACTLY it should do or how to go about the conversion from twig to escape code which would be picked up by fwrite
I've been looking for 2 days, and I really can't seem to figure this out on my own, so any help would be greatly appreciated.
Configure your twig extension:
services:
your.twig.pos_printer_extension:
class: Your\CustomBundle\Twig\POSPrinterExtension
tags:
- { name: twig.extension }
Create your extension:
<?php
namespace Your\CustomBundle\Twig;
class POSPrinterExtension extends \Twig_Extension
{
public function getGlobals()
{
return [
'some_constant' => chr(hexdec('0A'))
];
}
public function getFilters()
{
return [
'bold' => new \Twig_Filter_Method($this, 'bold')
];
}
public function bold($text)
{
return chr(hexdec('0B')) . $text . chr(hexdec('0A'));
}
}
And finally use it in your twig templates:
{{ some_constant }}
{{ receipt.amount | bold }}
You can apply filters to an entire block too:
{% filter bold %}
Dear {{ name }},
{% endfilter %}
Obviously I don't know the correct escaped chars but you got the idea right?
UPDATE (I'm writing this to avoid downvotes)
My example is using Twig_Filter_Method which is deprecated since 1.12 (to be removed in 2.0), you should be using Twig_SimpleFilter instead.
Its alive, just the syntax for the getFilters() was slightly different:
public function getGlobals()
{
return [
'ticket_cut' => chr(hexdec('1B')).chr(hexdec('69'))
];
}
public function getFilters()
{
return array(
new \Twig_SimpleFilter('ticketBold', array($this, 'ticketBold')),
);
}
public function ticketBold($string)
{
return chr(hexdec('1B')).chr(hexdec('45'))."1".$string.chr(hexdec('1B')).chr(hexdec('45'))."0";
}
Thx for pointing me in the right direction!

Categories