Skip to content

Instantly share code, notes, and snippets.

@fsuter
Created November 13, 2012 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fsuter/4065082 to your computer and use it in GitHub Desktop.
Save fsuter/4065082 to your computer and use it in GitHub Desktop.
Loading localized labels for JavaScript with TYPO3 Flow/Fluid
<?php
namespace Cobweb\Monitoring\ViewHelpers;
/* *
* This script belongs to the FLOW3 package "Cobweb.Monitoring". *
* *
* It is free software; you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License, either version 3 *
* of the License, or (at your option) any later version. *
* *
* The TYPO3 project - inspiring people to share! *
* */
use TYPO3\FLOW3\Annotations as FLOW3;
/**
* Takes some localized strings and makes them available in JavaScript
*
* IMPORTANT: note that that the string keys must not contain dots (.) or dashes (-)
* as JavaScript will choke on them.
*
* = Examples =
*
* <code title="JavaScript labels">
* <monitoring:javascriptLabels keyList="{0: 'yourFather'}" source="EmpireStrikesBack" package="StarWars"></monitoring:javascriptLabels>
* </code>
* <output>
* <script type="text/javascript">
* var Language = {
* yourFather: 'Luke, I\'m your father.',
* };
* </script>
* </output>
*
* @api
*/
class JavascriptLabelsViewHelper extends \TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @var \TYPO3\FLOW3\I18n\Translator
* @FLOW3\Inject
*/
protected $translator;
/**
* Reads some localized strings and stores them in global JS array
*
* This makes these strings usable from JavaScript
* Much code taken from \TYPO3\Fluid\ViewHelpers\TranslateViewHelper
*
* @param array $keyList List of strings to fetch
* @param string $source Name of file with translations
* @param string $package Target package key. If not set, the current package key will be used
* @param string $locale An identifier of locale to use (NULL for use the default locale)
* @throws \TYPO3\Fluid\Core\ViewHelper\Exception
* @return string A <script> tag containing the localized labels, as properties of a global object
* @api
*/
public function render(array $keyList = array(), $source = 'Main', $package = NULL, $locale = NULL) {
$localeObject = NULL;
if ($locale !== NULL) {
try {
$localeObject = new \TYPO3\FLOW3\I18n\Locale($locale);
} catch (\TYPO3\FLOW3\I18n\Exception\InvalidLocaleIdentifierException $e) {
throw new \TYPO3\Fluid\Core\ViewHelper\Exception('"' . $locale . '" is not a valid locale identifier.' , 1279815885);
}
}
if ($package === NULL) {
$package = $this->controllerContext->getRequest()->getControllerPackageKey();
}
$content = '<script type="text/javascript">';
$content .= 'var Language = {' . "\n";
foreach ($keyList as $key) {
$translation = $this->translator->translateById($key, array(), NULL, $localeObject, $source, $package);
$content .= $key . ': ' . "'" . addslashes($translation) . "',\n";
}
$content .= '};' . "\n";
$content .= '</script>';
return $content;
}
}
?>
@afoeder
Copy link

afoeder commented Nov 13, 2012

a tiny improvement would at least be the use of PHP'S json_encode in order not to "hack" the JavaScript object together. So, lines 74++ could be

$jsObject = array();
foreach ($keyList as $key) {
    $jsObject[$key] = $this->translator->translateById($key, array(), NULL, $localeObject, $source, $package);
}
$content = 'var Language = ' . json_encode($jsObject);

@afoeder
Copy link

afoeder commented Nov 13, 2012

...and maybe you want to make it a TagBasedViewHelper or don'T render the <script> tags at all, meaning to just let the VH Output the actual object (probably even without the assignment; to result in the following fluid (I hope the CDATA stuff is correct ;) :

<script type="text/javascript">
<![CDATA[(function() {
var language = ]]>{acme:translation.getDto()}<![CDATA
})();
]]>
</script>

@pcworld
Copy link

pcworld commented Sep 26, 2019

Btw this code is likely vulnerable to XSS if malicious localizations would be used. The strings could include </script>.
Edit: The addslashes might prevent it, but I wouldn't be sure about it. Better use something safer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment