Set language of TYPO3 StandaloneView in CommandController - php

I'm using the TYPO3\CMS\Fluid\View\StandaloneView in a CommandController to send emails to my fe_user.
The part where im building the template looks like this:
/* #var \TYPO3\CMS\Fluid\View\StandaloneView $emailView */
$emailView = $this->objectManager->get( 'TYPO3\\CMS\\Fluid\\View\\StandaloneView' );
// pass extension name to standaloneView for translations
$extensionName = $this->request->getControllerExtensionName();
$emailView->getRequest()->setControllerExtensionName( $extensionName );
$extensionPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath( 'my_extension' );
$templatePathAndFilename = $extensionPath . 'Resources/Private/Templates/Email/' . $templateFile . '.html';
$emailView->setLayoutRootPath( $extensionPath . 'Resources/Private/Layouts/Email/' );
//$emailView->setPartialRootPath($ressourcePath . 'Partials/');
$emailView->setTemplatePathAndFilename( $templatePathAndFilename );
return $emailView->render();
Nothing special i think.
In the html-Template i'm using the normal translate ViewHelper of Fluid:
<f:translate key="LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:mail.text" />
This all works well in the standard language, but i've no idea how i can tell the View/CommandController which language to use.
I'm not quite sure if this is a StandaloneView or a CommandController problem...
Edit:
The posted snippet is called from the CommandController (Scheduler) - so there is no current frontend user (we are in backend environment). I get the user from a repository so i've to save the selected language in there. But then i've to set the language for the StandaloneView

Generally you can set the language in a CommandController by doing this:
$GLOBALS['BE_USER']->uc['lang'] = 'de';
The problem is that the LocalizationUtility creates a cache for the extension after it's been called once to ::translate() something. There is no available function to reset that cache, but you can add this little utility function in your extension to enable you to do just that:
namespace Vendor\Extension\Utility;
class LocalizationUtility extends \TYPO3\CMS\Extbase\Utility\LocalizationUtility
{
public static function resetExtensionLangCache($extensionName){
unset(static::$LOCAL_LANG[$extensionName]);
}
}
If you have the case where you have to switch the full language context in your CommandController you can now call this right after switching the language for the BE_USER:
\Vendor\Extension\Utility\LocalizationUtility::resetExtensionLangCache('<extensionname>');
This will reset the cache and LocalizationUtility will have to initialize its entry for your extension until you switch and call it again.

To control the language used in a Fluid StandaloneView from the backend context, just set the language as shown below (I set the language to german).
$GLOBALS['BE_USER']->uc['lang'] = 'de';
This should be set before you call the $emailView->render() method.

I assume, that you want to send an email in language currently used by user, in that case, you should create language config for the additional languages, like described in TYPO3 docs.
When configured properly and non-default language is used, all your views (also these standalone) will be translated to the current language.
AFAUK, there's no way to force translate VH to use some language ie. by giving it's uid.

Related

Typo3 with extbase - get translation for specific language

I wrote a backend hook so that I can write notification E-mails as soon as an item is set to hidden = 0 in typo3. I managed to access LocalizationUtility to access my translation files, like this:
$localization = $objectManager->get('\TYPO3\CMS\Extbase\Utility\LocalizationUtility');
$localization::translate('tx_extplugin_domain_model_item.email.text1', 'ExtPlugin')
But how do I define which language to use? It doesn't seem like the translation function takes a language parameter, so how do I get the text in a different language?
Thanks in advance!
You can use the readLLfile Method to get specific translation by languagekey. This will return a array of all translated strings in $file.
$fd = GeneralUtility::readLLfile($file, $langKey);
You can't use the Typo3 translation in this way - Typo3 will always translate to the current language scope.
As per this answer I think the only way you could do it would to hold your translations outside of Typo3 (in an array or similar), and then do your own translation, rather than using the Typo3 built in one.

Codeigniter HMVC asset managment

I am trying to give a shot to HMVC in Codeigniter. Here is my folder structure.
-ROOT
--APPLICATION
---MODULES
----Module_Email
-----Controllers
-----Models
-----Views
-----Assets
------JS
------CSS
------IMG
To render the Module i have to use
Module::run('Module_Email');
This method will output the rendered output, an example is given below
<script type="text/javascript" src="PATH/TO/EMAIL_MODULE/JS/JS_FILE.JS"></script>
<div data-module-name="Module_Email" class="Email_wrapper">
//RENDERED HTML CONTENT
</div>
Now here my problem start. Normally i would like to put all my resources to header. So when i call any module, its dependence need to be added in header instead of from where its get called.
I searched a lot but i couldn't find any good methods.
Please help.
Update
Currently i have a function on my header called get_assets() which will output predefined resources to header. But i cant say which modules is going to use in pages, so the system need to check which modules are used in this page, and if its used then its dependencies need to be added on header.
Seems like your main problem then is trying to figure out what modules were used.
Unfortunately as far as I can tell with the default Wiredesignz modular extension there is no way to access the module name unless you write some sort of hack to get at that data. The module being used is stored in the protected variable $module in the MX_Router class, however, there is no public method to allow you to get access to it. So your only choice would be to extend the class and create a public function.
Alternatively you could use a forked version of Wiredesignz implementation which I did which provides numerous other features including a public function to get at the $module variable. Using the forked version I wrote you could then use code such as this:
<?php $module_name = $this->router->fetch_module(); ?>
However, that will only record the last module you loaded, so you would still need to do work to store all the modules, and then have your function use this information to determine what assets to load. If I were doing something like you I would probably fork my version and then create an additional data structure to store every module that was loaded that you could then later get access to.
I don't think this is exactly what you were hoping for, but might be something to get you on the right track to finding a solution.
I added an array to the Module class to store the assets and two functions to store/retrieve the items. Here is the source (updated Modules.php)
# Register your assets
public static function register_asset( $asset )
{
if( in_array($asset,self::$assets) === FALSE )
{
self::$assets[] = $asset;
}
}
public static function assets()
{
return self::$assets;
}
and now you can register your assets like this inside your module
Modules::register_asset('myslider.js');
You can retrieve all your assets using
Modules:assets();
Which will return an array of assets that can be processed depending up on the situation.

Changing the behaviour of view in Codeigniter

I am using codeigniter for a project that is used by a variety of companies.
The default version of our software is up and running and works fine - however some of our customers want slightly different view files for their instance of the system.
Ideally what I would like to do is set a variable (for example VIEW_SUFFIX) and whenever a view file is loaded it would first check if there was a suffix version available if there was use that instead.
For example if the system had a standard view file called 'my_view.php' but one client had a VIEW_SUFFIX of 'client_1' - whenever I called $this->load->view('my_view') if the VIEW_SUFFIX was set it would first check if my_view_client_1 existed (and if it did use that) or if not use the default my_view.php.
I hope that my question is clear enough... If anyone has done this before or can think of a way to do it I would really appreciate it.
EDIT:
Ideally I would like a solution that works without me changing every place that I am calling the view files. Firstly because there are a few files that may want different client versions and also because the view files are called from a lot of controllers
I had a similar requirement for which I created a helper function. Among other things, this function can check for a suffix before loading the specified view file. This function can check for the suffix and check if the file exists before loading it.
Unfortunately, the file checking logic would be a bit brittle. As an alternative, you can implement a MY_Loader class that will override the basic CI_Loader class.
Something like this in your application/core/MY_Loader.php:
class MY_Loader extends CI_Loader {
protected function _ci_load($_ci_data)
{
// Copy paste code from CI with your modifications to check prefix.
}
}
Could you not do this
// some method of creating $client
// probably created at login
$_SESSION['client'] = 'client_1';
$client = (isset($_SESSION['client'])) ? $_SESSION['client'] : '';
$this->load->view("your_view{$client}", $data);

CodeIgniter 2.1 internationalization i18n - Override default language if user data exists

I am running CI version 2.1 and I have recently installed the CodeIgniter 2.1 internationalization i18n (Original Author: Jérôme Jaglale). The code instructions are here: http://codeigniter.com/wiki/URI_Language_Identifier/
It runs fine but I would like to override the default language if the user set his language preference in a previous visit to the website (this would be stored in a table in the database).
My question is, how do you do this?
I believe MY_Lang.php (where default language is loaded) is actually loaded BEFORE the CodeIgniter MY_Controller so I am unable to load the database to find if a user has a preferred language.
The default language is configured in MY_Lang.php here:
function default_lang()
{
$browser_lang = !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? strtok(strip_tags($_SERVER['HTTP_ACCEPT_LANGUAGE']), ',') : '';
$browser_lang = substr($browser_lang, 0,2);
$default_lang = array_splice(array_keys($this->languages), 0,1);
return (array_key_exists($browser_lang, $this->languages)) ? $browser_lang : $default_lang[0];
}
However, I am unable to override it because here I have no access to my $this->session->userdata('language')
Thanks in advance!
ANSWER HERE:
Found out that you can use native PHP cookies to read the cookie inside MY_Lang.php file. If you try to use the cookie helper it won't work, so make sure you use $_COOKIE instead and run the appropriate filters before getting the content.
Then, in MY_Lang.php just change this:
return (array_key_exists($browser_lang, $this->languages)) ? $browser_lang : $default_lang[0];
To this:
if($_COOKIE['int_lang']) {
$preferred_lang = filter_var($_COOKIE['int_lang'], FILTER_SANITIZE_STRING);
return (array_key_exists($preferred_lang, $this->languages)) ? $preferred_lang : $default_lang[0];
}
else
{
return (array_key_exists($browser_lang, $this->languages)) ? $browser_lang : $default_lang[0];
}
If it was me, I'd use cookies for that instead of storing this in a database. It'll be faster and easier to manage.
Most users don't erase cookies, at least not all that often. It would solve your problem: "I am unable to load the database to find if a user has a preferred language".
If you need the database storage, you could try using a Hook:
http://codeigniter.com/user_guide/general/hooks.html
In a "post_controller_constructor" hook, load you Database Model used for language storage, get the language set by the user and load the language file that you want.

Basics of I18n For Yii Framework

Yii's I18n topic isn't enough for me.
My source lang is Turkish , target lang is English (for example)
My test controller's index action :
public function actionIndex()
{
Yii::app()->language='en';
$this->render("index");
}
This is my view file's content :
echo Yii::t('test', 'Deneme');
And lastly, this is my protected/messages/en/test.php file's content:
return array(
'Deneme' => 'Example',
);
Everything OK, it's returning Example . But as you can see, i'm setting language manually on my index action. How can i do it automatically ? Must i add Yii::app()->language='en'; to all actions? How you are using l18n on your projects ?
Note : I'm Yii and l18n noob, so please describe step by step .
Thank you.
You should set the target language in CWebApplication:beginRequest()
in protected/config/main.php, add:
'onBeginRequest' => array('MyApp', 'beginRequest')
In protected/components, create a file MyApp.php, and add this class:
class MyApp {
public static function beginRequest(CEvent $event) {
//set your language, theme, etc here
}
}
Remember to declare beginRequest() as static, or you will encounter errors like this:
https://github.com/yiisoft/yii/issues/794
it's fairly simple. You do all language translations as you said. Then, in the parent controller, in the init method, yo can check the desired language and set the current language. That way, you don't have to do that in every action, just once.
in the Yii's tutorials there is an article that has explained it very good.
in this way you have 3 file: one, your language selector, one, language selector's widget and one is an behavior for handling your language selector file.
read here and use it...
Manage (Target) Language in Multilingual Applications + A Language Selector Widget (i18n)

Categories