Применение CakePHP в переводе поведения после факта - PullRequest
2 голосов
/ 13 апреля 2009

Я медленно изучаю, как применять Перевести Поведение CakePHP, и я думаю, что я понял основы, но я работаю над существующим проектом с существующими данными. Здорово, что Cake будет вставлять новые записи для меня, но мне нужно вручную (я полагаю) вставить несколько переводов для некоторых существующих данных. Мой первый вопрос:

Должен ли я иметь запись в моей таблице i18n для en_us, если это мой язык по умолчанию и язык, который используется в моей основной таблице? Например, если category.name = 'Entertainment', действительно ли мне нужно создать «дублирующую» запись в i18n, чтобы указать, чтобы указать английский перевод «Entertainment»? Эмпирические данные, кажется, говорят «да», но это кажется большой дополнительной работой, поэтому я надеюсь, что кто-то скажет мне, что я что-то упустил.

Во-вторых, есть ли "простой" способ получить записи перевода в базу данных? Поскольку языки добавляются в ходе проекта, будет очень больно возвращаться и создавать записи i18n для устаревших данных.

Спасибо.

Ответы [ 4 ]

3 голосов
/ 04 мая 2012

Я знаю, что это старо, но так как оно осталось без ответа, и у меня возникли проблемы с выяснением этого, вот мои два цента:

сфера, Cakephp 1.3.

во-первых, вам нужна запись i18n для каждого поля -> запись -> модель в вашем приложении, конечно, только модели с поведением Translate и только для указанных полей, так что да, вы получите дублированный контент как в фактических полях модели, так и в таблице i18n.

Кроме того, вам нужны существующие переводы для любого языка, который вы укажете, чтобы методы find возвращали что-либо. Это меня смутило, потому что я также добавил поведение перевода в уже разработанный проект с кучей данных. По сути, я создал метод синхронизации для создания каждого перевода для каждого поля для каждой модели с поведением перевода. Если я добавлю новый язык в будущем, мне придется запустить его снова.

вот код для этого:

$locales = array( 'spa', 'eng', 'por' );
$models = array( 'Event', 'News', 'Promotion', 'Shop', 'ShopCategory' );

foreach ( $models as $model )
{
    $this->loadModel( $model );
    $records = $this->{$model}->find( 'all', array(
                                                  'fields' => array( "*" ),
                                                  'contain' => FALSE
                                             ) );

    $fields = $this->{$model}->actsAs['Translate'];
    foreach ( $records as $record )
    {
        foreach ( $fields as $field )
        {
            foreach ( $locales as $locale )
            {
                $content = mysql_real_escape_string( $record[$model][$field] );
                $this->{$model}->query( "INSERT INTO `i18n` (`locale`, `model`, `foreign_key`, `field`, `content`) VALUES('{$locale}', '{$model}', '{$record[$model]['id']}', '{$field}', '{$content}');" );
            }
        }
    }
}

Совет: создайте уникальный индекс в таблице i18n с ключами locale, model, foreign_key и field.

Итак, теперь, когда мои исходные данные реплицированы на все языки, мне нужно иметь возможность создавать новые записи с использованием языка выдачи. Проблема в том, что, если я создаю новую запись на английском языке, я смогу обновить ее на испанском языке, но, поскольку для испанского языка нет записи i18n, я не могу увидеть эту запись в своей CMS и не могу ее отредактировать. Я решил это путем создания записей i18n для каждого языка при создании новых записей, но редактирование только с текущим языком при редактировании записей.

Я использовал эту модификацию для поведения Переводчика: http://bin.cakephp.org/view/1939852942

Но в большинстве примеров с этой модификацией говорилось, что вы должны создавать входные данные формы в форме: echo $ this-> Form-> input ('name.eng'); echo $ this-> Form-> input ('name.spa'); echo $ this-> Form-> input ('description.eng'); echo $ this-> Form-> input ('description.spa');

Я нахожу это раздражающим, поэтому я в основном сделал вспомогательную функцию в app_controller для преобразования переводимых полей в эту структуру данных:

function _expandLocalizations( $data )
{
    foreach ( $data as $modelName => $modelData )
    {
        if ( !isset( $modelData[$this->{$modelName}->primaryKey] ) )
        {
            foreach ( $this->{$modelName}->actsAs['Translate'] as $field )
            {
                $translations = array();
                foreach ( $this->languages as $language )
                {
                    $translations[$language] = $this->data[$modelName][$field];
                }
                $data[$modelName][$field] = $translations;
            }
        }
    }
    return $data;
}

и в каждом методе добавления:

if ( !empty( $this->data ) )
    {
        $this->News->set( $this->data );
        if ( $this->News->validates() )
        {
            $this->News->create();
            $data = $this->_expandLocalizations( $this->data );
            $saved = $this->News->save( $data );
            if ( $saved )
            {

Таким образом, я могу использовать традиционные формы, и мне не нужно менять представление, если я добавляю новые языки. Мне нужно изменить метод традиционного запеченного добавления, потому что мне нужны отправленные данные для проверки, но измененные данные для сохранения.

Наконец, я следовал этим шагам для изменения языка на сайте / admin: http://nuts -and-bolts-of-cakephp.com / 2008/11/28 / cakephp-url-based-language- переключение-на-i18n-и-l10n-интернационализация и локализация /

Так что в основном это все. 1. Вы создаете переводы для всех данных, которые у вас уже есть в БД, каждый из которых копируется на каждый язык. 2. Создайте каждый перевод для новых записей при создании, все с одинаковой ценностью, конечно. 3. Отредактируйте каждую запись в выбранном переводе.

0 голосов
/ 06 ноября 2012

Использование поведения перевода со многими столбцами значительно замедляет работу вашего сайта. Простейший способ ускорить его - добавить этот индекс. Этот индекс закомментирован в cakephp/app/Config/Schema/i18n.sql, и я понятия не имею, почему.

ALTER TABLE rabotvins_i18n
ADD UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field);
0 голосов
/ 16 мая 2012

Что касается первого вопроса, ответ - нет. Нет необходимости дублировать данные, хотя я тоже так сначала думал.

Я написал в блоге об этом, чтобы помочь вам потерянным там. http://kristofferdarj.se/2012/05/cakephp-how-to-actually-use-i18n/

0 голосов
/ 16 апреля 2009

У меня нет ответа на второй вопрос, но ответ на первый кажется «да». После копания в исходном коде, похоже, что предложение where сгенерированных запросов ограничивает результаты теми, в которых полученное имя поля имеет значение для текущей локали. Это довольно ограничивающее.

Существует существующий билет для этого (или что-то очень похожее на него).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...