Symfony2, Sonata: перевести и показать переведенное имя роли

Первый шаг больше о Symfony2,

У меня разные роли:

role_hierarchy:
    ROLE_INVESTOR: [ROLE_USER]
    ROLE_PROJECT_OWNER: [ROLE_USER]
    ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN]
    ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH, SONATA]

Я хотел бы французский перевод для каждого из них.

Либо используя roles.fr.yml, roles.fr.xml или roles.fr.xliff (не уверен, какой из них нужно использовать).

это мой настоящий yml:

'ROLE_PROJECT_OWNER': Porteur de projet
'ROLE_INVESTOR': Investisseur
'ROLE_USER': Utilisateur

или xliff:

<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="" >
        <body>
            <trans-unit id="ROLE_PROJECT_OWNER">
                <source>ROLE_PROJECT_OWNER</source>
                <target>Porteur de projet</target>
            </trans-unit>
        </body>
    </file>
</xliff>

(Оба не тестировались)

Затем я хотел бы показать их в Sonata Admin, пока это совсем не удобно для пользователя:

Роли

Вот как они «автоматически» перечислены в этой части:

/**
 * {@inheritdoc}
 */
protected function configureListFields(ListMapper $listMapper)
{
    $listMapper
        ->addIdentifier('username')
        ->add('email')
        ->add('enabled', null, array('editable' => true))
        ->add('locked', null, array('editable' => true))
        ->add('roles', null, array('editable' => true))
        ->add('createdAt')
        ->add('_action', 'actions', array(
            'actions' => array(
                'show' => array(),
                'edit' => array(),
                'delete' => array(),
            )
        ))
    ;
}

Так что не очевидно, как добавить их родственные переводы.

Любые идеи, как это сделать?

ОБНОВЛЕНИЕ:

Мне удалось получить что-то более читабельное, но еще не переведенное с использованием пользовательского шаблона (Sonata Doc).

{% block field %}
<div>
    {% for role in object.roles %}
    <strong>{{ role }}</strong> <br/>
    {% endfor %}
</div>
{% endblock %}

person Brieuc    schedule 17.03.2015    source источник


Ответы (2)


Вы также можете установить домен перевода в своем классе администратора, например:

protected function configureListFields(ListMapper $listMapper)
{
    $listMapper
        ->addIdentifier('username')
        ->add('email')
        ->add('enabled', null, array('editable' => true))
        ->add('locked', null, array('editable' => true))
        ->add('roles', null, array('editable' => true), array('translation_domain' => 'roles')))
        ->add('createdAt')
        ->add('_action', 'actions', array(
            'actions' => array(
                'show' => array(),
                'edit' => array(),
                'delete' => array(),
            )
        ))
    ;
}

Если это сработает, вам может даже не понадобиться переопределять шаблон. Подробности в документе администратора Sonata: http://sonata-project.org/bundles/admin/master/doc/reference/translation.html#overriding-the-translation-domain

ОБНОВИТЬ

Чтобы перевести фильтры, вам нужно сделать что-то вроде:

если ваши роли принадлежат организации

protected function configureDatagridFilters(DatagridMapper $filterMapper)
{
    $filterMapper
        ->add('roles', null, array('translation_domain' => 'roles'), 'entity')
    ;
}

если ваши роли принадлежат не организации

protected function configureDatagridFilters(DatagridMapper $filterMapper)
{
    // get all your availables roles
    $roles = array('ROLE_OWNER' => 'ROLE_OWNER');
    $filterMapper
        ->add('roles', 'doctrine_orm_choice', array('translation_domain' => 'roles'), 'choice', array('choices' => $roles))
    ;
}

Я не знаю, будет ли перевод доступен в последнем случае, вам может понадобиться перевести в вашем контроллере значение ролей.

Подробности из документации: http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/filter_field_definition.html

ОБНОВЛЕНИЕ 2

Вот более подробное объяснение для второго случая, вам нужно создать метод, в котором вы переводите значение вашего массива. Например :

class ChallengeManager
{
    public function getStatuses($translate = false)
    {
        $statuses = array(
            ChallengeInterface::STATUS_DRAFT => 'challenge.status.draft',
            ChallengeInterface::STATUS_PUBLISHED => 'challenge.status.published',
            ChallengeInterface::STATUS_PENDING => 'challenge.status.pending',
            ChallengeInterface::STATUS_FINISHED => 'challenge.status.finished',
            ChallengeInterface::STATUS_PUBLISHING => 'challenge.status.publishing'
        );

        if ($translate == true) {
            $statusesTranslated = array();
            foreach ($statuses as $key => $status) {
                $statusesTranslated[$key] = $this->translator->transChoice($status, 0);
            }
            return $statusesTranslated;
        }
        return $statuses;
    }
}

class ChallengeAdmin
{
    protected configureDatagridFilters(DatagridMapper $datagridMapper)
    {
         $statuses = $this->getConfigurationPool()->getContainer()->get('managers.challenge_manager')->getStatuses(true);
         $datagridMapper
             ->add('status',
                    'doctrine_orm_choice',
                    array(),
                    'choice',
                    array('choices' => $statuses))
    }
}

Я использую службу для обработки переводов и получения статусов, и я использую ее в своем администраторе Sonata.

На данный момент не нашел лучшего способа сделать переводы для полей выбора.

person HypeR    schedule 17.03.2015
comment
Звучит идеально, я все равно буду использовать шаблон, так как мне нужно добавить некоторые стили. Но я хотел бы использовать его для части фильтров. Вы знаете, работает ли он так же? В основном мне нужно, чтобы пользователь искал пользователя с переведенным именем роли и замечал с ROLE_XXXXX. - person Brieuc; 17.03.2015
comment
В этом случае вы должны использовать тип выбора, ваше переведенное значение будет отображаться для вашего пользователя, а поле значения для каждого параметра будет ROLE_XXXX. - person HypeR; 17.03.2015
comment
Хорошо, это то, что я пытаюсь сделать прямо сейчас. Кажется, это легко сделать, но я даже не могу добавить тип выбора в $filterMapper. - person Brieuc; 17.03.2015
comment
Спасибо, это действительно работает (за исключением перевода второго метода, но это должно быть легко для этой части), и я могу получить выбор. Но никакого результата не было найдено с помощью этого метода. Я почти уверен, что это правильный путь. Я продолжу копать. - person Brieuc; 17.03.2015
comment
Отлично, я также поищу, если есть простой способ сделать перевод с doctrine_orm_choice. Если узнаешь, мне интересно! - person HypeR; 17.03.2015
comment
Конечно, я обновлю пост, если найду что-нибудь связанное. - person Brieuc; 17.03.2015
comment
Хорошо, также мне удалось заставить поиск возвращать правильное значение, я заменил доктрину_orm_choice на ноль, так как РОЛИ объявлены в моем security.yml. - person Brieuc; 17.03.2015
comment
Я добавил больше деталей о том, как переводить с помощью doctrine_orm_choice, это не самый красивый способ сделать это, но это единственный способ, который я нашел. - person HypeR; 17.03.2015

Хорошо, мне наконец удалось объявить перевод в моем yml.

Напоминаю, что мои переведенные роли объявлены в Resources/translations/roles.fr.yml.

'ROLE_PROJECT_OWNER': Porteur de projet
'ROLE_INVESTOR': Investisseur
'ROLE_USER': Utilisateur

Я использую собственный шаблон из сонаты doc.

Так что я могу сделать веточку и прямо перевести сюда:

{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% trans_default_domain "roles" %}

{% block field %}
    <div>
        {% for role in object.roles %}
        <strong>{{ role|trans }} </strong>
        {% endfor %}
    </div>
{% endblock %}
person Brieuc    schedule 17.03.2015