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()
  {
  }
}
&#91;/sourcecode&#93;

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

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

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

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

Листинг 2.2: код для редактирования всех локализированных полей БД в Административной Панели - прекрасно работает с плагинами Behaviors - добавлен в model BlogPost.php
[sourcecode lang="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: ,