Nov 11 2008

Symfony: интернационализация (I18n) / часть 2 – редактирование данных в административной панели

Category: Symfonyingvar @ 00:33

Часть 2: интернационализация (I18n) – редактирование данных в административной панели

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

Исходный код к статье — demo-i18n_part2.zip (source code). Код написан на Symfony 1.2, Propel 1.3.

Рисунок 2.1: Пример Frontend (Example Frontend)

Рисунок 2.2: Пример Backend — список записей (Example Backend — List of blog_post)

Рисунок 2.3: Пример Backend — редактирование записи (Example Backend — Edit of blog_post) — там не перевод, статьи взяты с Google News отдельно для каждого из языков

Описание реализации

Шаги описывают все по примеру, ссылка на который указана выше.

1) Изменить путь к фреймворку Symfony в файле конфигурации:
Листинг 2.1: файл конфигурации /config/ProjectConfiguration.class.php

<?php
require_once 'D:homesymfonyvendorssymfony-1.2lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
  }
}

2) Изменить доступ к БД: propel.ini (user, password, dbname, …), databases.yml

3) Выполнить ряд команд, чтобы создать таблицы и внести тестовые значения
• php symfony propel:insert-sql
• php symfony propel:data-load

4) Заходим по ссылке http://demo-i18n/, предварительно настроив хост в Apache :)

С FrontEnd полагаю все понятно. Для реализации в админке возможности редактировать на одной странице данных для всех языков использовались наработки How To Handle i18n Db Fields With the Admin Generator Method 2. Код немного модифицировался, т.к. были проблемы при использовании plugins c Behaviors (propel.ini: propel.builder.addBehaviors = true), что приводило к тому, что Behaviors не срабатывали.

Листинг 2.2: код для редактирования всех локализированных полей БД в Административной Панели — прекрасно работает с плагинами Behaviors — добавлен в model BlogPost.php

  /**
   * Handle I18n DB fields in Admin Generator
   *
   * @author Igor Brovchenko 
   * @param string $method
   * @param mixed $arguments
   * @return mixed
   */
  public function __call($method, $arguments)
  {
    $data = split('I18n', $method, 2);

    if( count($data) != 2 )
    {
      // original call for support sfPropelBehavior
      return parent::__call($method, $arguments);
    }

    list( $method, $culture ) = $data;

    if (4 == strlen($culture))
    {
      $culture = strtolower(substr($culture, 0, 2)) . '_' . strtoupper(substr($culture, 2, 2));
    }
    else
    {
      $culture = strtolower($culture);
    }

    $this->setCulture( $culture );

    return call_user_func_array(array($this, $method), $arguments);
  }

Листинг 2.3: пример файла generator.yml для редактирования локализированных данных

generator:
  class:              sfPropelAdminGenerator
  param:
    model_class:      BlogPost
    theme:            default

    list:
      peer_method:    doSelectWithI18n
      max_per_page:   50
      display:        [ =id, =title ]
      sort:           [ id, desc ]

    edit:
      display:
        "NONE":       [ created_at ]
        "EN":
          - title_i18n_en
          - announce_i18n_en
          - body_i18n_en
        "RU":
          - title_i18n_ru
          - announce_i18n_ru
          - body_i18n_ru

      fields:
        title_i18n_en:
          name:       Title
          params:     disabled=false maxlength=255 style="width:80%"

        announce_i18n_en:
          name:       Announce
          type:       textarea_tag
          params:     disabled=false size=150x6

        body_i18n_en:
          name:       Body
          type:       textarea_tag
          params:     disabled=false size=150x6

        title_i18n_ru:
          name:       Title
          params:     disabled=false maxlength=255 style="width:80%"

        announce_i18n_ru:
          name:       Announce
          type:       textarea_tag
          params:     disabled=false size=150x6

        body_i18n_ru:
          name:       Body
          type:       textarea_tag
          params:     disabled=false size=150x6

Принцип таков: нужно описать все поля, которые мы хотим редактировать с суффиксами языков (title_i18n_en, title_i18n_ru). Т.е. если хотим ещё редактировать французскую версию, то надо добавить следующий код.

Листинг 2.4: добавляем поддержку французского языка в файл generator.yml

generator:
...

    edit:
      display:
        "NONE":       [ created_at ]
        "EN":
          - title_i18n_en
          - announce_i18n_en
          - body_i18n_en
        "RU":
          - title_i18n_ru
          - announce_i18n_ru
          - body_i18n_ru
        "FR":
          - title_i18n_fr
          - announce_i18n_fr
          - body_i18n_fr

      fields:
...
        title_i18n_fr:
          name:       Title
          params:     disabled=false maxlength=255 style="width:80%"

        announce_i18n_fr:
          name:       Announce
          type:       textarea_tag
          params:     disabled=false size=150x6

        body_i18n_fr:
          name:       Body
          type:       textarea_tag
          params:     disabled=false size=150x6

Вот в принципе и все. Просто и удобно. Единственное, что плохо это то, что если БД очень большая, то количество полей огромно, и если потребуется отредактировать какие-то поля, а их много, что как следствие приводит к ошибкам (copy past). Поэтому, был написан Task, который позволяет упростить процесс редактирования и главное добавление новых языков, но это уже будет описано в следующей статье.

Ссылки по теме:
Symfony: интернационализация (I18n) / часть 1 — введение

Tags: ,

5 Responses to “Symfony: интернационализация (I18n) / часть 2 – редактирование данных в административной панели”

  1. ilya says:

    а если языки создаются динамическим путём, то такой ведь вариант не подойдет.

  2. ingvar says:

    Подходит, т.к. я использую свой Task, который на основе списка массива языков, генерует это самый файл generator.yml. Пару комманд и получаем поддеркжу новых языков.

  3. Aleks says:

    В 1.2 новый генератор делает это автоматом
    достаточно указать
    $this->embedI18n(array(‘ru’, ‘en’));
    в форме
    (проверял на Doctrine, хотя думаю что и Propel тоже)

  4. ingvar says:

    Спасибо за наводку, проверю.

Leave a Reply