読者です 読者をやめる 読者になる 読者になる

Djangoのrestructuredtextフィルターでblockdiagを使う

Python Django

Djangoのcontribには、テンプレートでrestructuredtextなどのマークアップをHTMLに変換してくれるフィルタのセット、django.contrib.markupがあります。
https://docs.djangoproject.com/en/dev/ref/contrib/markup/
restructuredtextフィルターを使う場合は、docutilsのインストールが必要になります。
今回は、このrestructuredtextフィルターでblockdiagディレクティブを使えるようにしてみます。
ブロック図生成ツール blockdiag — blockdiag 1.0 ドキュメント
試したバージョンは、Python2.7、Django1.4.2、docutils0.9.1、blockdiag1.2.2です。

Djangoの初期化時に読み込まれるアプリケーションを追加する

blockdiagのディレクティブを設定するために、Djangoアプリケーションを新規に作成してINSTALLED_APPSに追加します。

$ python manage.py startapp blockdiag_setup

django.contrib.markupも有効にしておきます。

INSTALLED_APPS = (
    'django.contrib.markup',
    'blockdiag_setup',
    'myapp',
)

今回はテンプレートでの表示テスト用にmyappというアプリケーションも追加しています。

blockdiagのディレクティブを設定する

作成したDjangoアプリケーションの__init__.pyでblockdiagのrstディレクティブを設定する関数を呼び出します。

blockdiag_setup/__init__.py
from blockdiag.utils.rst.directives import setup


setup(format='SVG',
      nodoctype=True,
      inline_svg=True,
      noviewbox=True,
      ignore_pil=True)

今回はインラインでSVGを出力するように設定しています。こうすると静的ファイルが不要なので認証をかけたい場合にも簡単です。
nodoctype=Trueを指定して、DOCTYPEが出力されないようにしています。また、noviewbox=Trueでviewboxの指定をはずしています(設定しないと余白が大きかった)。
ignore_pil=Trueを指定すると、PILがなくても動作します。

viewとテンプレートを用意する

表示を試すためにmyappにviewとテンプレートを用意します。

myapp/views.py
# coding: utf-8
from django.views.generic import TemplateView

test_text = """
restructuredtextフィルタでblockdiagを使う
=========================================

restructuredtextフィルタでblockdiagディレクティブを使っています。

.. blockdiag::

   {
     A -> B -> ほげ;
          B -> ふが;
   }

テスト
======

ほげふが
"""


class IndexView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        return {'test_text': test_text}
myapp/templates/index.html
{% load markup %}
<html>
<title>restructuredtextフィルタ</title>
<body>
<div style="width:800px;">
{{ test_text|restructuredtext }}
</div>
</body>
</html>
myapp/urls.py
from django.conf.urls import patterns, include, url
from myapp.views import IndexView


urlpatterns = patterns('',
    url(r'^$', IndexView.as_view()),
)

実行結果

これをサイトのurls.pyで有効にして、runserverで確認したところ、問題なく動作しました。

コードはbitbucketに置いてます。
tokibito / sample_nullpobug / source / django / blockdiag_example — Bitbucket