プログラミング - THIS IS IT !

より良い開発をすべく日々奮闘しているプログラマーです。設計やDDDに興味があります。主にPHPネタを書いてます。 Crocos Inc./日本Symfonyユーザー会

SonataAdminBundleを翻訳してみたよ

(2013/5/26追記)
こちらの情報はインストール手順等が既にに古くなっています。新し目の翻訳情報はこちらにまとめています。
http://okapon-pon.hatenablog.com/entry/2012/12/24/235408
(追記終わり)

(この記事ははてなダイアリーからのインポート記事になります)
おかぽんと申します。本エントリーが初投稿となりますよろしくお願いします。

このエントリーは「Symfony Advent Calendar JP 2011」の23日目の記事になります。
アドベントカレンダーをご存知ない方はこちらをどうぞ。http://gihyo.jp/news/info/2011/12/0101

今回が初ブログでAdvent Calendarに参加するために作ったわけですが、完全にボリュームを見誤り日付が変わってしまいました。1週間ぐらい前から地道に翻訳を始めたのですが・・・

それはさておき、さっそく本題に入りたいと思います。

このエントリーではSymfony2のAdminGeneratorであるSonataAdminBundleのドキュメントを翻訳したのでご紹介していきたいと思います。<2012/12/3追記>
SonataAdminBundleですが、2012/12/3インストール方法が変わっていますのでこの記事のままだと動きません。このあたりの翻訳も時間があるときにやりたいなとは思っています。

そもそもバンドルとは

symfony2をある程度使っている方なら(ましてアドベントカレンダーを楽しみにしている方ならなおさら)説明は不要かと思いますが、symfony2では「バンドル」という機構を利用してサードパーティ製のライブラリーを組み込むことができます。(プラグインのようなものですが、単なるプラグインではないです。そこらへんの説明は省略します。)

既にたくさんのサードパーティ製バンドルが公開されており*1、非常な便利なものがたくさんあります。
(といいつつ僕はほとんど使ったことないのであんまり詳しくないです)

その中でもユーザ認証関連を提供している「FOSUserBundle」やDB管理機能を提供している「SonataAdminBundle」は非常に有名です。

ただ、ここで問題なのがこれらサードパーティ製バンドルのドキュメントはほとんどが英語なんですね。。。僕もそうですが英語が苦手な人はどうもとっつきづらい。。。

じゃあ翻訳してみよう

ということで今回の英語が苦手な方に向けて翻訳にトライしてみました。
翻訳したのはタイトルにもある通りSonataAdminBundleです。

最初に謝っておきますが、まだ翻訳は全部できてません。
そもそも時間が。。 原文自体更新されてるし。。 ごめんなさい。力不足でした。随時更新していきたいと思います。
僕自身英語が苦手なので「この訳が変だ!」とかありましたらご教授いただけますと幸いです。

翻訳文は以下githubで公開しています。(forkして「translation」ブランチ作って翻訳しています)
SonataAdminBundle(翻訳)
SonataDoctrineORMAdminBundle(翻訳)
ただ、日本語を追記しているだけなので非常に見にくいのが現状です。何かいいアイデアがあれば教えてください。
せめてREADMEぐらい置けばよかった。。
<2011/12/25追記>READMEファイル置きました。

はい!翻訳もgithubにアップしたからこれでおしまい!
って終わるのもあれですので、使い方について簡単に説明していきたいと思います。

はじめに

先程も述べたようにAdminBundleは、Symfony2におけるAdminGeneratorになります。DB管理画面に必要な機能をひと通り提供してくれています。

このAdminBundleですが、まだまだ開発途中であり日々アップデートされています。(同様にドキュメントもちょくしょく更新されてますorz.)そのためこのエントリーの記述されている内容は古くなったり、正常に動作しなくなる可能性もあるためご了承ください。

僕が初めてAdminBundleを触りだした10月末頃はAdminBundle単体で動いていたのですがいつの間にか4つのbundleに分かれていました*2
そのため、AdminBundle以外にも別途bundleをインストールしなければ動かすことができません。

例えば、MysqlのDB管理を行いたければ実際にDBと連携するDoctrinORM向けの「SonataDoctrineORMAdminBundle」もインストールする必要があります。

SonataAdminBundleの特徴

メリット
  • DB管理に必要なcreate,update,deleteなど(CRUD)の機能を簡単に作成できる
  • いけてるインターフェースの管理画面がお手軽に構築できる
  • 一括処理(デフォルトで用意されているのは一括削除のみ)ができる
  • DBテーブルの関連性を持たせることができる(例えば、あるカテゴリーに属した商品を登録できる)
  • FOSUserBundleを内包したSonataUserBundleを利用することでAdminユーザの管理ができる(まだ試せてない)
  • simplethings/EntityAudit というbundleを使うことでDBのバージョン管理ができる(まだ試せてない)
その他

なおデフォルトではログイン機能は提供されていません。
SonataUserBundleがその機能を提供しているみたいなのでそちらを使うことになるかと思います。

もちろんsymfony2のセキュリティーコンポーネントを用いて自分で作るのもありだと思います。僕はFouUserBundleに関して理解できていないので自分でセキュリティエリアを設定して使っています。

また、編集の確認画面がないので必要であれば作る必要があります。海外ではフォーム入力後の確認画面がないと聞きます。(本当か?)そのため日本向けにカスタマイズするのであれば自分でカスタマイズして組み込む必要がありそうですね。

インストール方法

ここではMySQLを使用していることを前提に「SonataAdminBundle」と「SonataDoctrineORMAdminBundle」インストールします。

オプションのEntityAuditは別途DBテーブルを作らないと動かないみたいなので今回はなしで。<2012/12/26追記>詳しくはAuditの翻訳を参照

bundleをインストールするにはdeps ファイルに記述します。

[SonatajQueryBundle]
    git=http://github.com/sonata-project/SonatajQueryBundle.git
    target=/bundles/Sonata/jQueryBundle

[SonataUserBundle]
    git=http://github.com/sonata-project/SonataUserBundle.git
    target=/bundles/Sonata/UserBundle

[SonataAdminBundle]
    git=http://github.com/sonata-project/SonataAdminBundle.git
    target=/bundles/Sonata/AdminBundle

[KnpMenuBundle]
    git=https://github.com/KnpLabs/KnpMenuBundle.git
    target=/bundles/Knp/Bundle/MenuBundle

[KnpMenu]
    git=https://github.com/KnpLabs/KnpMenu.git
    target=/knp/menu

[SonataDoctrineORMAdminBundle]
    git=http://github.com/sonata-project/SonataDoctrineORMAdminBundle.git
    target=/bundles/Sonata/DoctrineORMAdminBundle

そして

bin/vendors install

を実行しadminbundleをインストール!

次に、bundleの登録を行います。
app/AppKernel.phpとapp/autoload.phpファイルに書き足します。

<?php
// app/autoload.php
$loader->registerNamespaces(array(
    // ...
    'Sonata'           => __DIR__.'/../vendor/bundles',
    'Knp\\Bundle'      => __DIR__.'/../vendor/bundles',
    'Knp\\Menu'        => __DIR__.'/../vendor/knp/menu/src',
    )
);
// app/AppKernel.php
public function registerBundles()
{
    return array(
        // ...
        new Sonata\jQueryBundle\SonatajQueryBundle(),
        new Sonata\AdminBundle\SonataAdminBundle(),
        new Knp\Bundle\MenuBundle\KnpMenuBundle(),
        // ...
    );
}

そしてルートを記述します。prefixはそれぞれの環境に合わせて下さい。

# app/config/routing.yml
admin:
    resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
    prefix: /admin

_sonata_admin:
    resource: .
    type: sonata_admin
    prefix: /admin

そしてアセットをインストールします。

app/console assets:install web --symlink

ここまでできたら、「http://yoursite.local/admin/dashboard」にアクセスすることで下のようなダッシュボードが表示されます。

sonata adminの設定

少し表示を変えてみましょう。

# app/config/config.yml
sonata_admin:
    title:      プロジェクト管理画面
    title_logo: /bundles/sonataadmin/logo_title.png #ロゴはデフォルト
    dashboard_groups:
        管理項目1:
            items: ~

タイトルが変更され、ダッシュボードグループができましまた。

※別に「dashboard_groups」設定しなくともAdminaバンドルはデフォルト設定でいい感じに動いてくれます。

adminクラスの作成

エンティティを管理するためには、Adminクラスを作成しサービスに登録する必要があります。

まず管理したいDBテーブルを登録します。
通常プロジェクトを作っている場合、既にエンティティは作成していると思いますが今回は初めから作ります。

以下のようなcategoryテーブルの管理サービスを作成します。

id int(10)
name varchar(20)
created_at datetime
updated_at timestamp

mysqlで以下を実行(symfony2でのコンソールコマンドだとtimestamp型にできないと思われるので。間違ってたらごめんなさい)

# クエリ実行
CREATE TABLE `category` (
 id int NOT NULL  AUTO_INCREMENT PRIMARY KEY,
 name varchar(20)    NOT NULL,
 created_at datetime    NOT NULL,
 updated_at timestamp    NOT NULL
) ENGINE = INNODB DEFAULT CHARSET=utf8;

# Categoryエンティティ作成
app/console generate:doctrine:entity --entity=AcmeDemoBundle:Category --format=yml --fields="name:string(20) created_at:datetime updated_at:datetime"
# yml設定とかは略します。

次にcategoryテーブルを管理するために必要なCategoryAdminコントローラーとCategoryAdminクラスを作成します。

# コントローラー作成
#src/Acme/DemoBundle/Controller/CategoryAdminController.php
<?php
namespace Acme\DemoBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
  
class CategoryAdminController extends Controller
{

}

# CategoryAdminクラス作成
#src/Acme/DemoBundle/Admin/CategoryAdmin.php
<?php
namespace Acme\Demobundle\Admin;
 
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

use Knp\Menu\ItemInterface as MenuItemInterface;
 
#use Application\Sonata\NewsBundle\Entity\Comment;
use Dgtw\DaigakutownBundle\Util\SystemTime;

class CategoryAdmin extends Admin
{
    protected function configureShowField(ShowMapper $showMapper)
    {
        // showアクションで表示したい項目を設定
        $showMapper
            ->add('id')
            ->add('name','string',array('label'=> 'カテゴリー名'))
            ->add('created_at',null, array('label' => '作成日'))
            ->add('updated_at',null, array('label' => '更新日'))
        ;
    }
    protected function configureFormFields(FormMapper $formMapper)
    {
        // editアクションのformで編集したい項目を設定
        // 通常created_atはライフサイクルコールバックで自動登録しそうだがとりあえず設定
        $formMapper
            ->add('name','text',array('label'=> 'カテゴリー名'))
            ->add('created_at',null, array('label' => '作成日'))
            ->add('updated_at',null, array('label' => '更新日'))
            ->end()
        ;
    }
    protected function configureListFields(ListMapper $listMapper)
    {
        // listアクションで一覧に表示したい項目
        $listMapper
            ->addIdentifier('name',null,array('label'=> 'カテゴリー名'))
            ->add('_action', 'actions', array(
                'actions' => array(
                    'view' => array(),
                    'edit' => array(),
                )
            ))
        ;
    }
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        // 検索フィルターを使用する項目を設定
        $datagridMapper
            ->add('name')
        ;
    }
}

Adminクラスを作り終えたらサービスを登録します。

<del># app/config/routing.yml</del> (正しくはconfig.ymlでした。)
# app/config/config.yml
services:
    acme.demobundle.admin.category:
        class: Acme\DemoBundle\Admin\CategoryAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: 管理項目1, label: カテゴリー }
        arguments: [null, Acme\DemoBundle\Entity\Category, AcmeDemoBundle:CategoryAdmin]

↑tags の groupの値を「sonata_admin」のところで設定したdashboard_groupsと値を揃えることでダッシュボードの「管理項目1」にカテゴリーが表示されます(下画像)


日本語化

この状態でもとりあえず動きます。
管理画面として機能しています。ですが、表記が英語のままなのでなんとかしたいですね。
SonataAdminBundleは多国語翻訳されているアプリケーションで、幸いなことに日本語にも翻訳されています。

では、言語を日本語に切り替えてみましょう。

symfony2に詳しい人はご存知でしょうが、symfony2にはロケール設定といものがあります。
以下の様に設定して下さい。

# app/config/parameters.ini
    locale            = ja_JP

# app/config/config.yml
framework:
    #esi:             ~ 
    translator:      { fallback: %locale% } ←デフォルトでコメントアウトされてるのを外す
    ...

更新したら日本語化されると思いきやされない。どうやらセッションが効いているようなのでブラウザ閉じてリロード。
(そういえば昔もはまったような。。。)

「追加」「一覧」と無事日本語化されました。その他のページも「新規作成」など日本語化されています。

これでとりあえずAdminBundleが使えるようになりました。

終わりに

ホントはもう少し詳しく書こうかと思っていましたが、時間の関係上これで今回の記事はこれで終了します。
翻訳や記事の続きはまた書いていく予定ですので暖かく見守ってください。

明日はアドベントカレンダー最後日ですが、24日朝5時時点ではまだ埋まっていませんね。
どなたが書かれるのか期待ですね。

それでは皆様よいクリスマスを〜(*´∀`)

*1:12/23現在 927バンドル登録されています。knpBundlesをご覧下さい。

*2:Admin Bundleの目次に書かれています