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....
}
Related
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.
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...
I have been successfully using XML view files in CakePHP (request the XML output type in headers so CakePHP will use e.g. Orders/xml/create.ctp instead of Order/create.ctp).
However, now i need to add some functionality that requires me to the reformat the XML at the end of most business logic in the controller.
So i tried this in the controller action:
public function createorder() {
$this->autoRender = false; // disable automatic content output
$view = new View($this, false); // setup a new view
{ ... all kinds of controller logic ...}
{ ... usually i would be done here and the XML would be outputted, but the autorender will stop that from happening ... }
{ ... now i want the XML in a string so i can manipulate the xml ... }
$view_output = $view->render('createorder'); // something like this
}
But what this gives me is:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<error>View file "/Users/test/Documents/hosts/mycakeapp/app/View/Orders/createorder.ctp" is missing.</error>
<name>MissingViewException</name>
<code>500</code>
<url>/orders/createorder/</url>
</response>
So i need to tell CakePHP to pickup the xml/createorder.ctp instead of createorder.ctp. How do i do this?
Cheers!
This answers refers to cakephp 2.4
I have been successfully using XML view files in CakePHP (request the XML output
type in headers so CakePHP will use e.g. Orders/xml/create.ctp
instead of Order/create.ctp).
In lib/Cake/View you can see different View files like:
View.php
XmlView.php //This extends View.php
JsonView.php //This extends View.php
So you told cakephp to use the XmlView. When you create a new View you need to use the XmlView instead of View. Or you can create your own custom View and put it inside app/View folder. In your custom View you can set your subdir.
<?php
App::uses('View', 'View');
class CustomView extends View {
public $subDir = 'xml';
public function __construct(Controller $controller = null) {
parent::__construct($controller);
}
public function render($view = null, $layout = null) {
return parent::render($view, $layout);
}
}
So what you need now is to create your custom view $view = new CustomView($this, false);
You can also write in your CustomView functions to handle the data as xml and use it to every action.
Also #Jelle Keizer answer should work. $this->render('/xml/createorder'); points to app/View/xml/createorder. If you need this to point to app/View/Order/xml/create just use $this->render('/Orders/xml/create');.
$this->render('/xml/createorder');
I need to compose a web page of several view templates (the view template rendering page content and a view template rendering sidebar). In my layout.phtml, I have two variable placeholders: $content and $sidebar:
......
<?php echo $this->sidebar; ?>
......
<?php echo $this->content; ?>
......
In my controller's action, I pass the data to these view templates through the ViewModels chained in a tree:
public function indexAction() {
// Preparing my data
// $form = ...
// $menuItems =
// $activeItem =
// Create sidebar view model
$sidebarViewModel = new ViewModel(array('menuItems'=>$menuItems, 'activeItem'=>$activeItem));
// Add it as a child to layout view model
$this->layout()->addChild($sidebarViewModel, 'sidebar');
// Page content view model
$viewModel = new ViewModel(array('form'=>$form));
return $viewModel;
}
But, because I have the sidebar on every page, I will have to copy and paste this code for every action of every controller. Is there any recommended way of reusing the code that populates the ViewModel for sidebar?
One approach would be to achieve this with a controller plugin.
Assuming you have wired it up with appropriate config, and you're in the Application module.
In module/Application/src/Application/Controller/Plugin/AddSidebar.php:
namespace Application\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
class addSidebar extends AbstractPlugin {
public function __invoke($menu, $active) {
// create new view model
$sidebarVM = new ViewModel(array(
'menuItems' => $menu,
'activeItem' => $active
));
// add it to the layout
$this->getController()->layout()->addChild($sidebarVM, 'sidebar');
}
}
Then in each of your controllers:
$this->addSidebar($menuItems, $activeItem);
Another (probably better) option would be to hook into the render MvcEvent and add the sidebar there. You'd have to work out how to generate $menuItems and $activeItem in that context however.
NOTE: UPDATED MY QUESTION
I am using zend.I have the file "stylesettings.php" under css folder. Having the following line to convert php file to css.
header("Content-type: text/css");
stylesetting.php is under application/css/stylesettings.php
Now i want to get the color code from my DB in stylesettings.php.Here i can write basic DB connection code to get values from DB. I guess there might be another way to get all DB values by using zend. How can we connect DB like "Zend_Db_Table_Abstract" in stylesettings file ?
Is it possible to use zend component in that file ? Kindly advice on this.
I hope you understand.
You are breaking the basic separated model assumed in a MVC framework. For such color code, if it's only used in one place, I would suggest that you output the color in the "style="color: <color>"" in-line style in order to keep the dynamic part in HTML and your CSS file static.
If you really want to do this, then you should consider output your dynamic stylesheet in a URL path other than css, and use the controller/views etc to generate the stylesheet.
i am using the following way to apply color settings in layout.phtml
Use below code in bootstrap file
<?php
require_once 'plugins/StyleController.php';
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
protected function _initRouter() {
$front = Zend_Controller_Front::getInstance ();
$front->setControllerDirectory ( dirname ( __FILE__ ) . '/controllers' );
$router = $front->getRouter ();
$front->registerPlugin ( new StyleController ( $router ) );
}
}
Created folder plugins under application and create a new file called stylecontroller.php
<?php
class StyleController extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$layout = Zend_Layout::getMvcInstance();
$view = $layout->getView();
/* code for getting color settings */
$this->settings = new Admin_Model_DbTable_Settings();
$view->colorsettings = $this->settings->getStyleSettings();
//print_obj($view->colorsettings);
}
}
?>
Also to get color code,
<?php
class Admin_Model_DbTable_Settings extends Zend_Db_Table_Abstract
{
public function getStyleSettings()
{
$select = $this->_db->select()
->from('style_settings');
$result = $this->getAdapter()->fetchAll($select);
return $result['0'];
}
}
?>
By using above code i can able to use $this->colorsettings in layout page.
This one fix my dynamic color in layout but not in other template files.