Skip to content

Commit

Permalink
feature EasyCorp#1464 Translated interface to Arabic and allowed RTL …
Browse files Browse the repository at this point in the history
…languages (badr el ghailani, javiereguiluz)

This PR was merged into the master branch.

Discussion
----------

Translated interface to Arabic and allowed RTL languages

Commits
-------

6187a6f Fixed the Markdown syntax
12a19be Tweaked the documentation
684b96c Added tests
7117a01 Tweaks
a9a935d Added Arabic translation for interface (RTL) Right-to-Left Language Support
  • Loading branch information
javiereguiluz committed Jan 11, 2017
2 parents 6a2598d + 6187a6f commit 1a1fea8
Show file tree
Hide file tree
Showing 12 changed files with 340 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Configuration/ConfigManager.php
Expand Up @@ -183,7 +183,7 @@ private function doProcessConfig($backendConfig)
{
$configPasses = array(
new NormalizerConfigPass($this->container),
new DesignConfigPass($this->container->get('twig'), $this->container->getParameter('kernel.debug')),
new DesignConfigPass($this->container->get('twig'), $this->container->getParameter('kernel.debug'), $this->container->getParameter('locale')),
new MenuConfigPass(),
new ActionConfigPass(),
new MetadataConfigPass($this->container->get('doctrine')),
Expand Down
21 changes: 19 additions & 2 deletions Configuration/DesignConfigPass.php
Expand Up @@ -21,20 +21,37 @@ class DesignConfigPass implements ConfigPassInterface
{
private $twig;
private $kernelDebug;
private $locale;

public function __construct(\Twig_Environment $twig, $kernelDebug)
public function __construct(\Twig_Environment $twig, $kernelDebug, $locale)
{
$this->kernelDebug = $kernelDebug;
$this->twig = $twig;
$this->kernelDebug = $kernelDebug;
$this->locale = $locale;
}

public function process(array $backendConfig)
{
$backendConfig = $this->processRtlLanguages($backendConfig);
$backendConfig = $this->processCustomCss($backendConfig);

return $backendConfig;
}

private function processRtlLanguages(array $backendConfig)
{
if (!isset($backendConfig['design']['rtl'])) {
// ar = Arabic, fa = Persian, he = Hebrew
if (in_array(substr($this->locale, 0, 2), array('ar', 'fa', 'he'))) {
$backendConfig['design']['rtl'] = true;
} else {
$backendConfig['design']['rtl'] = false;
}
}

return $backendConfig;
}

private function processCustomCss(array $backendConfig)
{
$customCssContent = $this->twig->render('@EasyAdmin/css/easyadmin.css.twig', array(
Expand Down
4 changes: 4 additions & 0 deletions DependencyInjection/Configuration.php
Expand Up @@ -242,6 +242,10 @@ private function addDesignSection(ArrayNodeDefinition $rootNode)
->treatNullLike('dark')
->end()

->booleanNode('rtl')
->info('If true, the interface uses RTL (right-to-left) writing (needed for Arabic, Hebrew and Persian).')
->end()

->scalarNode('brand_color')
->info('The color used in the backend design to highlight important elements.')
->defaultValue('#205081')
Expand Down
15 changes: 15 additions & 0 deletions Resources/doc/book/2-design-configuration.md
Expand Up @@ -156,6 +156,21 @@ easy_admin:
# ...
```

Enabling RTL Support
--------------------

The RTL writing support is enabled automatically in the interface when the
locale of the application is `ar` (Arabic), `fa` (Persian) or `he` (Hebrew). If
you need a more precise control over this setting, configure the `rtl` boolean
option:

```yaml
easy_admin:
design:
rtl: true
# ...
```

-------------------------------------------------------------------------------

← [Chapter 1. Basic Configuration](1-basic-configuration.md) | [Chapter 3. List, Search and Show Views Configuration](3-list-search-show-configuration.md) →
Expand Down
9 changes: 9 additions & 0 deletions Resources/public/stylesheet/adminlte-rtl.min.css

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions Resources/public/stylesheet/bootstrap-rtl.min.css

Large diffs are not rendered by default.

152 changes: 152 additions & 0 deletions Resources/translations/EasyAdminBundle.ar.xlf
@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" target-language="ar" datatype="plaintext" original="file.ext">
<body>
<!-- page titles -->
<trans-unit id="new.page_title">
<source>new.page_title</source>
<target>"%entity_name%" جديد</target>
</trans-unit>
<trans-unit id="show.page_title">
<source>show.page_title</source>
<target>(#%entity_id%) %entity_name%</target>
</trans-unit>
<trans-unit id="edit.page_title">
<source>edit.page_title</source>
<target>(#%entity_id%) %entity_name% تعديل</target>
</trans-unit>
<trans-unit id="list.page_title">
<source>list.page_title</source>
<target>%entity_name%</target>
</trans-unit>
<trans-unit id="search.page_title">
<source>search.page_title</source>
<target><![CDATA[{0} لا توجد اي نتائج |{1} العثور على نتيجة وحيدة|]1,Inf] العثور على <strong>%count%</strong> نتيجة ]]></target>
</trans-unit>

<!-- 'search' view -->
<trans-unit id="search.no_results">
<source>search.no_results</source>
<target>لا توجد اي نتائج</target>
</trans-unit>

<!-- 'list' view -->
<trans-unit id="list.row_actions">
<source>list.row_actions</source>
<target>إجراءات</target>
</trans-unit>

<!-- paginator -->
<trans-unit id="paginator.first">
<source>paginator.first</source>
<target>الأول</target>
</trans-unit>
<trans-unit id="paginator.previous">
<source>paginator.previous</source>
<target>السابق</target>
</trans-unit>
<trans-unit id="paginator.next">
<source>paginator.next</source>
<target>التالي</target>
</trans-unit>
<trans-unit id="paginator.last">
<source>paginator.last</source>
<target>الأخير</target>
</trans-unit>
<trans-unit id="paginator.counter">
<source>paginator.counter</source>
<target><![CDATA[<strong>%results%</strong> / <strong>%end%</strong> - <strong>%start%</strong>]]></target>
</trans-unit>

<!-- labels -->
<trans-unit id="label.true">
<source>label.true</source>
<target>نعم</target>
</trans-unit>
<trans-unit id="label.false">
<source>label.false</source>
<target>لا</target>
</trans-unit>
<trans-unit id="label.empty">
<source>label.empty</source>
<target>فارغ</target>
</trans-unit>
<trans-unit id="label.null">
<source>label.null</source>
<target>لا شيء</target>
</trans-unit>
<trans-unit id="label.nullable_field">
<source>label.nullable_field</source>
<target>اتركه فارغ</target>
</trans-unit>
<trans-unit id="label.object">
<source>label.object</source>
<target>Objet PHP</target>
</trans-unit>
<trans-unit id="label.inaccessible">
<source>label.inaccessible</source>
<target>لا يمكن الوصول إليها</target>
</trans-unit>
<trans-unit id="label.inaccessible.explanation">
<source>label.inaccessible.explanation</source>
<target>لا يوجد وصف الوصول لهذه الخاصية أو أنها ليست عامة.</target>
</trans-unit>

<!-- user -->
<trans-unit id="user.logged_in_as">
<source>user.logged_in_as</source>
<target>تسجيل الدخول باسم</target>
</trans-unit>
<trans-unit id="user.unnamed">
<source>user.unnamed</source>
<target>مستخدم بدون اسم</target>
</trans-unit>
<trans-unit id="user.anonymous">
<source>user.anonymous</source>
<target>مستخدم مجهول</target>
</trans-unit>

<!-- misc. elements -->
<trans-unit id="toggle_navigation">
<source>toggle_navigation</source>
<target>اتاحة أو تعطيل التصفح</target>
</trans-unit>
<trans-unit id="delete_modal.title">
<source>delete_modal.title</source>
<target>هل تريد حذف هذا العنصر؟</target>
</trans-unit>
<trans-unit id="delete_modal.content">
<source>delete_modal.content</source>
<target>هذا الإجراء غير قابل للالغاء.</target>
</trans-unit>
<trans-unit id="delete_modal.action">
<source>delete_modal.action</source>
<target>حذف</target>
</trans-unit>
<trans-unit id="action.add_new_item">
<source>action.add_new_item</source>
<target>إضافة عنصر جديد</target>
</trans-unit>
<trans-unit id="action.add_another_item">
<source>action.add_another_item</source>
<target>إضافة عنصر آخر</target>
</trans-unit>
<trans-unit id="action.remove_item">
<source>action.remove_item</source>
<target>حذف العنصر</target>
</trans-unit>
<trans-unit id="errors">
<source>errors</source>
<target>خطأ | أخطاء</target>
</trans-unit>
<trans-unit id="form.are_you_sure">
<source>form.are_you_sure</source>
<target>لم يتم حفظه التغييرات.</target>
</trans-unit>
<trans-unit id="show.remaining_items">
<source>show.remaining_items</source>
<target><![CDATA[{1} هناك عنصر آخر لم يتم عرضه في هذه القائمة|]1,Inf] عنصر آخر لم يتم عرضه في هذه القائمة %count% ]]></target>
</trans-unit>
</body>
</file>
</xliff>
51 changes: 51 additions & 0 deletions Resources/translations/messages.ar.xlf
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" target-language="ar" datatype="plaintext" original="file.ext">
<body>
<!-- generic actions displayed on buttons and links -->
<trans-unit id="action.new">
<source>action.new</source>
<target>%entity_name% جديد</target>
</trans-unit>
<trans-unit id="action.show">
<source>action.show</source>
<target>إطلاع</target>
</trans-unit>
<trans-unit id="action.edit">
<source>action.edit</source>
<target>تعديل</target>
</trans-unit>
<trans-unit id="action.search">
<source>action.search</source>
<target>بحث</target>
</trans-unit>
<trans-unit id="action.delete">
<source>action.delete</source>
<target>حذف</target>
</trans-unit>
<trans-unit id="action.save">
<source>action.save</source>
<target>حفظ</target>
</trans-unit>
<trans-unit id="action.cancel">
<source>action.cancel</source>
<target>الغاء</target>
</trans-unit>
<trans-unit id="action.list">
<source>action.list</source>
<target>رجوع إلى القائمة</target>
</trans-unit>
<trans-unit id="label.form.empty_value">
<source>label.form.empty_value</source>
<target>لا شيء</target>
</trans-unit>

<!-- forms -->
<trans-unit id="form.label.collections">
<!-- don't change this "translation" -->
<source>__name__label__</source>
<target>__name__label__</target>
</trans-unit>
</body>
</file>
</xliff>
5 changes: 5 additions & 0 deletions Resources/views/default/layout.html.twig
Expand Up @@ -43,6 +43,11 @@
<script src="{{ asset('bundles/easyadmin/javascript/easyadmin-all.min.js') }}"></script>
{% endblock head_javascript %}

{% if easyadmin_config('design.rtl') %}
<link rel="stylesheet" href="{{ asset('bundles/easyadmin/stylesheet/bootstrap-rtl.min.css') }}">
<link rel="stylesheet" href="{{ asset('bundles/easyadmin/stylesheet/adminlte-rtl.min.css') }}">
{% endif %}

<!--[if lt IE 9]>
<script src="{{ asset('bundles/easyadmin/stylesheet/html5shiv.min.css') }}"></script>
<script src="{{ asset('bundles/easyadmin/stylesheet/respond.min.css') }}"></script>
Expand Down
11 changes: 11 additions & 0 deletions Tests/Controller/DefaultBackendTest.php
Expand Up @@ -42,6 +42,17 @@ public function testLanguageDefinedByLayout()
$this->assertSame('en', trim($crawler->filter('html')->attr('lang')));
}

public function testRtlIsDisabledByDefault()
{
$crawler = $this->getBackendHomepage();

$backendConfig = $this->client->getContainer()->get('easyadmin.config.manager')->getBackendConfig();
$this->assertFalse($backendConfig['design']['rtl'], 'RTL is disabled by default.');

$this->assertNotContains('bootstrap-rtl.min.css', $crawler->filter('head')->text());
$this->assertNotContains('adminlte-rtl.min.css', $crawler->filter('head')->text());
}

public function testDefaultCssStylesAreLinked()
{
$crawler = $this->getBackendHomepage();
Expand Down
52 changes: 52 additions & 0 deletions Tests/Controller/RtlTest.php
@@ -0,0 +1,52 @@
<?php

/*
* This file is part of the EasyAdminBundle.
*
* (c) Javier Eguiluz <javier.eguiluz@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JavierEguiluz\Bundle\EasyAdminBundle\Tests\Controller;

use JavierEguiluz\Bundle\EasyAdminBundle\Tests\Fixtures\AbstractTestCase;

class RtlTest extends AbstractTestCase
{
public function setUp()
{
parent::setUp();

$this->initClient(array('environment' => 'rtl'));
}

public function testRtlAutodetection()
{
$this->getBackendHomepage();

$backendConfig = $this->client->getContainer()->get('easyadmin.config.manager')->getBackendConfig();
$this->assertTrue($backendConfig['design']['rtl'], 'RTL is enabled automatically for the "ar" locale.');
}

public function testRtlWebAssets()
{
$crawler = $this->getBackendHomepage();

$this->assertSame(
'/bundles/easyadmin/stylesheet/easyadmin-all.min.css',
$crawler->filter('link[rel="stylesheet"]')->eq(0)->attr('href')
);

$this->assertSame(
'/bundles/easyadmin/stylesheet/bootstrap-rtl.min.css',
$crawler->filter('link[rel="stylesheet"]')->eq(1)->attr('href')
);

$this->assertSame(
'/bundles/easyadmin/stylesheet/adminlte-rtl.min.css',
$crawler->filter('link[rel="stylesheet"]')->eq(2)->attr('href')
);
}
}
12 changes: 12 additions & 0 deletions Tests/Fixtures/App/config/config_rtl.yml
@@ -0,0 +1,12 @@
imports:
- { resource: config.yml }

# use 'ar' (Arabic) as the locale of the app to force the detection of RTL languages
parameters:
locale: ar
framework:
default_locale: ar

easy_admin:
entities:
Category: AppTestBundle\Entity\FunctionalTests\Category

0 comments on commit 1a1fea8

Please sign in to comment.