Skip to content

Commit

Permalink
Adds localePage Twig filter for translating page URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
octoberapp committed Jan 14, 2023
1 parent 4495c0f commit 465d976
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 57 deletions.
9 changes: 9 additions & 0 deletions Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public function registerMarkupTags()
'transRaw' => [$this, 'translateRawString'],
'transRawPlural' => [$this, 'translateRawPlural'],
'localeUrl' => [$this, 'localeUrl'],
'localePage' => [$this, 'localePage'],
]
];
}
Expand Down Expand Up @@ -179,6 +180,14 @@ public function localeUrl($url, $locale)
]);
}

/**
* localePage builds a page URL
*/
public function localePage($name, $locale, $params = [])
{
return Translator::instance()->getPageInLocale($name, $locale, $params);
}

/**
* translateString
*/
Expand Down
39 changes: 14 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,20 @@ The word "Contact" in French is the same so a translated URL is not given, or ne
- /ru/контакт - Page in Russian
- /ru/contact - 404

### Translating URLs in Twig

The `localeUrl` method will replace the route prefix on a URL from one locale to another. For example, converting the current request URL from `en` to `de`.

```twig
{{ this.request.url|localeUrl('de') }}
```

The `localePage` will return a translated URL for a CMS page. It takes a locale (first argument) and page parameters (second argument).

```twig
{{ 'blog/post'|localePage('de', { slug: 'foobar' }) }}
```

## URL Parameter Translation

It's possible to translate URL parameters by listening to the `cms.sitePicker.overrideParams` event, which is fired when discovering language URLs.
Expand Down Expand Up @@ -402,31 +416,6 @@ class Post extends Model

The back-end forms will automatically detect the presence of translatable fields and replace their controls for multilingual equivalents.

#### Messages

Since the Twig filter will not be available all the time, we can pipe them to the native Laravel translation methods instead. This ensures translated messages will always work on the front end.

```php
/**
* registerMarkupTags registers new Twig variables
* @return array
*/
public function registerMarkupTags()
{
// Check the translate plugin is installed
if (!class_exists('RainLab\Translate\Behaviors\TranslatableModel')) {
return;
}

return [
'filters' => [
'_' => ['Lang', 'get'],
'__' => ['Lang', 'choice'],
]
];
}
```

# User Interface

#### Switching Locales
Expand Down
76 changes: 44 additions & 32 deletions classes/Translator.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php namespace RainLab\Translate\Classes;

use App;
use Cms;
use Site;
use Event;
use Config;
use Schema;
use Session;
use Request;
use Cms\Classes\Page as CmsPage;
use RainLab\Translate\Classes\Locale;

/**
Expand Down Expand Up @@ -132,7 +134,7 @@ public function isConfigured()
//

/**
* Returns the current path prefixed with language code.
* getCurrentPathInLocale returns the current path prefixed with language code.
*
* @param string $locale optional language code, default to the system default language
* @return string
Expand All @@ -143,47 +145,57 @@ public function getCurrentPathInLocale($locale = null)
}

/**
* Returns the path prefixed with language code.
* getPathInLocale returns the path prefixed with language code. The path to rewrite,
* can be already translated, with or without locale prefixed.
*
* @param string $path Path to rewrite, already translate, with or without locale prefixed
* @param string $locale optional language code, default to the system default language
* @param boolean $prefixDefaultLocale should we prefix the path when the locale = default locale
* @return string
* @param string $path
* @param string $locale
* @return string|null
*/
public function getPathInLocale($path, $locale = null, $prefixDefaultLocale = null)
public function getPathInLocale($path, $locale = null)
{
$prefixDefaultLocale = (is_null($prefixDefaultLocale))
? Config::get('rainlab.translate::prefixDefaultLocale')
: $prefixDefaultLocale;
if (!$locale || !Locale::isValid($locale)) {
$locale = $this->defaultLocale;
}

$segments = explode('/', $path);
$site = Site::getSiteForLocale($locale);
if (!$site) {
return $path;
}

$newPath = $site->removeRoutePrefix($path);
$newPath = $site->attachRoutePrefix($newPath);

return $newPath;
}

$segments = array_values(array_filter($segments, function ($v) {
return $v != '';
}));
/**
* getPageInLocale
* @return string|null
*/
public function getPageInLocale($name, $locale = null, $params = [])
{
$page = CmsPage::find($name);
if (!$name || !$page) {
return null;
}

if (is_null($locale) || !Locale::isValid($locale)) {
if (!$locale || !Locale::isValid($locale)) {
$locale = $this->defaultLocale;
}

if (count($segments) == 0 || Locale::isValid($segments[0])) {
$segments[0] = $locale;
} else {
array_unshift($segments, $locale);
$site = Site::getSiteForLocale($locale);
if (!$site) {
return null;
}

// If we don't want te default locale to be prefixed
// and the first segment equals the default locale
if (
!$prefixDefaultLocale &&
isset($segments[0]) &&
$segments[0] == $this->defaultLocale
) {
// Remove the default locale
array_shift($segments);
};

return htmlspecialchars(implode('/', $segments), ENT_QUOTES, 'UTF-8');
$router = new \October\Rain\Router\Router;
$urlPattern = array_get($page->attributes, 'viewBag.localeUrl.'.$locale, $page->url);

$newPath = trim($router->urlFromPattern($urlPattern, $params), '/');
$newPath = $site->attachRoutePrefix($newPath);

return Cms::url($newPath);
}

//
Expand Down
1 change: 1 addition & 0 deletions updates/version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ v2.1.0: Adds support for translatable file attachments
v2.1.1: Fixes child menu item translations for pages plugin
v2.1.2: Fixes translatable integration with settings models
v2.1.3: Fixes installation of Translate with other dependencies
v2.2.0: Adds localePage Twig filter for translating page URLs

0 comments on commit 465d976

Please sign in to comment.