Quickstartの拡張

tg-admin quickstart を実行すると、TurboGearsは内部でpasteを使います。これは既存のテンプレートを拡張し、独自のものを生成するための標準的なやり方を提供してくれます。

何故独自のものを作ろうとするのでしょう?もちろん、アプリケーションに便利なものが必要になればTurboGearsプロジェクトにそういったドキュメンテーションテンプレートや、テストフレームワークや、その他いろいろを追加するというのは一つのやり方です。

また、すでにプロジェクトをスタートしていても、もう一度 tg-admin quickstart を行うことができます(新しいテンプレートがあればそれも付いてきます!)。現在のプロジェクトがどう変わるのかを見ることができますし、いくつかの変更を適用することもできるかもしれません。

新しいテンプレートを作成する

それでは先へ進んで独自のテンプレートを作成してみましょう!ここでは自分の好きなカスタムCSSファイル、 default.css だけを含むテンプレートを作成することにします。これをインストール可能なパッケージとして作りましょう(すばらしいテンプレートを再配布したいでしょうから)。このようなテンプレートを作るためにはテンプレートをスクラッチから作成します。

ディレクトリ構造は最終的に以下のようになるでしょう:

mytemplate/
mytemplate/setup.py
mytemplate/mytemplate/__init__.py
mytemplate/mytemplate/setup.py_tmpl
mytemplate/mytemplate/template/+package+/static/css/default.css
mytemplate/mytemplate/template/+package+.egg-info/paster_plugins.txt

まずはじめにディレクトリ構造を作成しましょう。GNU mkdirを備えたマシンがあるなら、簡単にこんなふうにすることができます:

mkdir -p mytemplate/mytemplate/template/+package+.egg-info/
mkdir -p mytemplate/mytemplate/template/static/css

そうでなければ、もう少しコマンドを打つ必要があるでしょう。またすばらしいCSSファイルと空の paster_plugins.txt も欲しいでしょう:

vim mytemplate/mytemplate/template/+package+/static/css/default.css
touch mytemplate/mytemplate/template/+package+.egg-info/paster_plugins.txt

このひな形作成をすべて終えたら、実際の中身が欲しくなるでしょう。 setup.py ファイルはこんな風になります:

from setuptools import setup, find_packages
from turbogears import finddata

setup(name='mytemplate',
      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
      zip_safe=False,
      package_data=finddata.find_package_data(),
      entry_points="""
          [paste.paster_create_template]
              mytemplate = mytemplate:MyTemplate
        """
      )

最初の2行は配布可能な 'mytemplate' パッケージのためのセットアップデータです。 packages= 引数はsetuptoolsに対して、いくつかのパッケージがバンドルされていないということを知らせるものです。 zip_safe=Falsepackage_data= 引数はこれが標準です。

ここで少し重要なのは entry_points 引数です。これはpasteに対して、 mytemplate というテンプレートがあり(これは tg-admin quickstart``に ``-t を使って渡すものです)、このクラスが mytemplate モジュールの MyTemplate? であることを知らせています。

ここで __init__.py を編集しましょう:

from paste.script import templates
import pkg_resources

class MyTemplate(templates.Template):

    egg_plugins = ['MyTemplate']
    _template_dir = pkg_resources.resource_filename("mytemplate",
                                                    "template")
    #use_cheetah = True
    summary = "my own cute template"

_template_dir のある行は、pasteに template ディレクトリがある場所を知らせます。これと paste.script.templates.Template の継承が必要十分条件です。

コメントアウトされた use_cheetah はpasteに対して、テンプレーティングに Cheetah を使うことを知らせています(後で詳しく述べます)。デフォルトでは標準ライブラリの string.Template を使います。

最後にquickstartテンプレートに setup.py_tmpl テンプレートのひな形を作成します:

from setuptools import setup, find_packages
from turbogears.finddata import find_package_data

import os

setup(
    name="${project}",
    version="0.1",

    #description=description,
    #author=author,
    #author_email=email,
    #url=url,
    #download_url=download_url,
    #license=license,

    zip_safe=False,
    packages=find_packages(),
    package_data = find_package_data(where='${package}',
                                     package='${package}')
    )

_tmpl をファイル名の最後につけることに注意してください。これはpasteにテンプレートファイルを作成したことを知らせます。テンプレートファイルはコンテンツを置換するので、すべての ${project} はquickstartでタイプしたすべてのプロジェクト名に対して置換されます。デフォルトのpaste変数は:

Name Example Description
project Wiki-20 The project's name
package wiki20 The project's Python package
egg Wiki_20 The project's egg name (generated by setuptools)

ここでドキュメンテーションテンプレートやテストフレームワークなどをテンプレートに追加しますが、CSSファイルはそのままです。

このテンプレートを使うために、これをシステムにインストールしなければならないでしょう:

cd mytemplate
sudo python setup.py develop  #or install if you prefer

ここまですべてを終えると、以下のように実行することができます:

tg-admin quickstart -t mytemplate

標準プロンプトとちょっとした処理のあと、 static/css/ ディレクトリの中に default.css ファイルができるでしょう!pasteのサイトの テンプレートAPIドキュメント ではさらなる情報を見つけることができます。

テンプレートの拡張

かなり長い導入部でしたので、TurboGearsのテンプレートを拡張するのはもっと難しいだろうと考えるかもしれません。気後れすることはありません!手順としては標準テンプレートによって提供されたファイルを削除しようとするのと大部分はほとんど同じです。

アップデートしたディレクトリ構造は以下のようになるでしょう:

mytemplate/
mytemplate/setup.py
mytemplate/mytemplate/__init__.py
mytemplate/mytemplate/template/+package+/static/css/default.css

paster_plugins.txtsetup.py_tmpl は下位の層で提供されるため削除します。

setup.py をCheeseshopで配布するためにアップデートします:

from setuptools import setup, find_packages
from turbogears.finddata import find_package_data

import os

setup(
    name="mytemplate",
    version=version,
    #description = "The most awesome CSS Template EVAR!"
    #long_description = "More description about your greatness"
    #author = "Your Name Here"
    #email = "YourEmail@YourDomain"
    #copyright = "Vintage 2006 - a good year indeed"

    #オープンソースなら以下の項目も記載しておくとよいでしょう
    #url = "http://yourcool.site/"
    #download_url = "http://yourcool.site/download"
    #license = "MIT"

    install_requires = [
        "TurboGears >= 0.9a8",
    ],
    zip_safe=False,
    packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
    package_data = find_package_data(),
    keywords = [
        'python.templating.engines',
    ],
    classifiers = [
        'Development Status :: 3 - Alpha',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Topic :: Software Development :: Libraries :: Python Modules',
        'Framework :: TurboGears',
        'Framework :: TurboGears :: Templates',
    ]
)

アップデートした __init__.py は以下の通り:

from paste.script import templates
import pkg_resources

class MyTemplate(templates.Template):

    egg_plugins = ['MyTemplate']
    required_templates = ['turbogears']
    _template_dir = pkg_resources.resource_filename("mytemplate",
                                                    "template")
    use_cheetah = True
    summary = "my own cute template"

最初の変更は required_templates という行の追加です。これはこのテンプレートが実行される前に標準的なquickstartテンプレートが実行されることを確認します。もう一つの変更は use_cheetah=True を設定したことです。標準テンプレートはIdentityがどのように生成されるかを制御するためにCheetahを利用します。

継承したファイルの削除

ときどき、quickstartテンプレートを使いたいけれども一部好きではない部分がある、ということがあるかもしれません。こういうときのテンプレートの __init__.py は以下のようになるでしょう:

from paste.script import templates
import pkg_resources
import os

class AdvancedStart(templates.Template):

    egg_plugins = ['AdvancedStart']
    _template_dir = pkg_resources.resource_filename('advancedstart',
                                                    'template')
    summary = 'TurboGears Advanced project template'
    required_templates = ['turbogears']
    use_cheetah = True

    def post(self, command, output_dir, vars):
        templates.Template.post(self, command, output_dir, vars)
        try:
            path = os.path.join(output_dir,
                     vars['package'] + '/controllers.py')
            os.remove(path)
            print 'Removing', path
        except OSError:
            pass