Skip to content

Commit

Permalink
feat: add support for translations in LATTE files
Browse files Browse the repository at this point in the history
  • Loading branch information
BernhardBaumrock committed Feb 22, 2023
1 parent 12fa350 commit 5656765
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 45 deletions.
33 changes: 19 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,26 +423,31 @@ Please see https://github.com/baumrock/RockFrontend/blob/main/profiles/rock/file

## LATTE and translatable strings

Unfortunately you can't use ProcessWire's translation system in LATTE files. You can either use an MVC approach and move your translatable strings into the controller file (custom page class) or you can use RockFrontend's translation helper:
Since version 2.24.0 RockFrontend supports translatable strings in LATTE files!! 馃槑馃コ

This are the three versions that you can use to translate strings in your LATTE files - choose whatever you prefer.

```php
// define translations, eg in /site/init.php
/** @var RockFrontend $rf */
$rf = $this->wire->modules->get('RockFrontend');
$rf->x([
'status_loggedin' => __('You are now logged in'),
'status_loggedout' => __('Pleas log in'),
'logout' => __('Logout'),
'login' => __('Login'),
]);
```
<p>{=__('Das ist ein Test')}</p>
<p>{=_x('foo bar', 'context')}</p>
<p>{=_n('Found one item', 'Found multiple items', 1)}</p>
<p>{=_n('Found one item', 'Found multiple items', 2)}</p>

In your LATTE files you can output translations like this:
<p>{$rf->_('Das ist ein Test')}</p>
<p>{$rf->_x('foo bar', 'context')}</p>
<p>{$rf->_n('Found one item', 'Found multiple items', 1)}</p>
<p>{$rf->_n('Found one item', 'Found multiple items', 2)}</p>

```html
<button>{$user->isLoggedin() ? x('logout') : x('login')}</button>
<p>{$rockfrontend->_('Das ist ein Test')}</p>
<p>{$rockfrontend->_x('foo bar', 'context')}</p>
<p>{$rockfrontend->_n('Found one item', 'Found multiple items', 1)}</p>
<p>{$rockfrontend->_n('Found one item', 'Found multiple items', 2)}</p>
```

Note that when using the function-syntax you must prepend the function call with an equal sign! While the translation will - in theory - also work without the equal sign you will not be able to translate the string in the backend, because the regex will not find it!

In case you have an older version of RockFrontend [here](https://github.com/baumrock/RockFrontend/tree/12fa350b69873054bb529e985f01c2dcdeef594f#latte-and-translatable-strings) is the link to the outdated workaround.

## Adding assets to your site (JS or CSS)

While you can always add custom `<script>` or `<link>` tags to your site's markup it is recommended that you use RockFrontend's `AssetsArray` feature:
Expand Down
69 changes: 38 additions & 31 deletions RockFrontend.module.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public static function getModuleInfo()
{
return [
'title' => 'RockFrontend',
'version' => '2.23.0',
'version' => '2.24.0',
'summary' => 'Module for easy frontend development',
'autoload' => true,
'singular' => true,
Expand Down Expand Up @@ -207,36 +207,6 @@ public function ready()
$this->addAssets();
}


/**
* Helper function to support translatable strings in latte/twig files
*
* Usage:
* <a href=...>{$rf->_('login')}</a>
* <a href=...>{$rf->_('logout')}</a>
*
* See https://github.com/processwire/processwire-requests/issues/480
*/
public function _($str)
{
$trace = Debug::backtrace();
foreach ($trace as $item) {
$call = $item['call'];
// renderFile[Latte|Twig]
if (strpos($call, '$rockfrontend->renderFile') !== 0) continue;
preg_match("/(.*)\"(.*)\"(.*)/", $call, $matches);
// path to file that was rendered (eg main.latte)
$path = $matches[2];
break;
}
$url = str_replace(
$this->wire->config->paths->root,
$this->wire->config->urls->root,
$path
);
return \ProcessWire\__($str, $url);
}

/**
* Add assets to the html markup
* @return void
Expand Down Expand Up @@ -1518,6 +1488,7 @@ protected function renderFileLatte($file, $vars)
$latte = $this->latte;
if (!$latte) {
try {
require_once __DIR__ . "/translate.php";
require_once $this->path . "vendor/autoload.php";
$latte = new Engine();
if ($this->modules->isInstalled("TracyDebugger")) {
Expand Down Expand Up @@ -1751,6 +1722,42 @@ public function svg($filename, $replacements = [])
return $this->html($svg);
}

/** translation support in LATTE files */

public function _($str)
{
return \ProcessWire\__($str, $this->textdomain());
}

public function _x($str, $context)
{
return \ProcessWire\_x($str, $context, $this->textdomain());
}

public function _n($textsingular, $textplural, $count)
{
return \ProcessWire\_n($textsingular, $textplural, $count, $this->textdomain());
}

/**
* Method to find the correct textdomain file for translations in latte files
*/
public function textdomain()
{
$trace = Debug::backtrace();
foreach ($trace as $item) {
$call = $item['call'];
// renderFile[Latte|Twig]
if (strpos($call, '$rockfrontend->renderFile') !== 0) continue;
preg_match("/(.*)\"(.*)\"(.*)/", $call, $matches);
// path to file that was rendered (eg main.latte)
return $this->url($matches[2], false);
}
return false;
}

/** END translation support in LATTE files */

/**
* Make sure that the given file/directory path is absolute
* This will NOT check if the directory or path exists!
Expand Down
27 changes: 27 additions & 0 deletions translate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php // no namespace!

/**
* Add global translation functions to LATTE files
* In LATTE files use this syntax to add translations:
* {=__('your string')}
* {=_x('your string', 'context)}
* {=_n('found one item', 'fount multiple items', $num)}
*/

use function ProcessWire\wire;

function __($str)
{
$rf = wire()->modules->get('RockFrontend');
return \ProcessWire\__($str, $rf->textdomain());
}
function _x($str, $context)
{
$rf = wire()->modules->get('RockFrontend');
return \ProcessWire\_x($str, $context, $rf->textdomain());
}
function _n($textsingular, $textplural, $count)
{
$rf = wire()->modules->get('RockFrontend');
return \ProcessWire\_n($textsingular, $textplural, $count, $rf->textdomain());
}

0 comments on commit 5656765

Please sign in to comment.