reStructuredText とHTMLをそのまま表示

= reStructuredText とHTMLをそのまま表示 =

ユーザー側で

* 管理側のテキストエリアで入力された「HTML」をそのまま表示させたい。
* コメント欄(テキストエリア)を「reStructuredText」で書けるようにしたい。
* コメント欄(テキストエリア)に入力された「HTML」は「escape」させたい。

なので、

ユーザー側に

* reStructuredTextのみを表示させる。
* reStructuredTextとHTMLをそのまま表示させる。

の2パターンが必要になる。

なのでテンプレートフィルタを作成。

まずテンプレートフィルタの作成方法を

Djangoの和訳ドキュメントに書かれている通りやってみた。

「templatetags」パッケージを適当な「Django」アプリケーションパッケージ内に作る。[[BR]]
※パッケージは models.py や views.py などと同じ階層にせねばなりません。

なので下記のようになる。

{{{
test/
models.py
templatetags/
views.py
}}}

のように「templatetags」ディレクトリを作成。[[BR]]
その後に[[BR]]
「templatetags」内にファイルを2つ追加する。

* __init__.py
* 自作のタグ/フィルタ定義の入ったファイル

今回は自作のタグ/フィルタ定義の入ったファイルを「rawtext.py」のような名前で作成するので、

* __init__.py
* rawtext.py

になる。

「__init__.py」には何も書かなくて良いが、「rawtext.py」にフィルタ定義を書く。

今回は「reStructuredText」使うため[[BR]]
/DjangoをインストールしたPATH/django/contrib/markup/templatetags/markup.py[[BR]]
に記述されている。

{{{
#!python
def restructuredtext(value):
try:
from docutils.core import publish_parts
except ImportError:
if settings.DEBUG:
raise template.TemplateSyntaxError, “Error in {% restructuredtext %} filter: The Python docutils library isn’t installed.”
return force_unicode(value)
else:
docutils_settings = getattr(settings, “RESTRUCTUREDTEXT_FILT|~ER_SETTINGS”, {})
parts = publish_parts(source=smart_str(value), writer_name=”html4css1″,settings_overrides=docutils_settings)
return force_unicode(parts[“fragment”])
}}}

を使用します。
「rawtext.py」を下記のように記述する。

{{{
#!python
# vim: fileencoding=utf-8 :

import re
from django.template import Library
from docutils import nodes
from docutils.parsers.rst import directives
from django.conf import settings
from django.utils.encoding import smart_str, force_unicode

register = Library()

@register.filter
def rawtext(value):
def raw_directive(name, arguments,options, content, lineno,
content_offset, block_text, state, state_machine):
return [nodes.raw(”, u’\n’.join(content), format=’html’)]
raw_directive.content = 1
directives.register_directive(‘raw’, raw_directive)

try:
from docutils.core import publish_parts
except ImportError:
if settings.DEBUG:
raise template.TemplateSyntaxError, “Error in {% restructuredtext %} filter: The Python docutils library isn’t installed.”
return force_unicode(value)
else:
docutils_settings = getattr(settings, “RESTRUCTUREDTEXT_FILTER_SETTINGS”, {})
parts = publish_parts(source=smart_str(value), writer_name=”html4css1″, settings_overrides=docutils_settings)
return force_unicode(parts[“fragment”])
}}}

まず必要なライブラリなどをimportする。[[BR]]
その時にテンプレートフィルタを作成するのにひつようなのが、

{{{
#!python
from django.template import Library
register = Library()
}}}

上記を記述するのは、

{{{
有効なタグライブラリを作るには、
register という名前のモジュールレベル変数に template.Library のインスタンスを入れておく必要がある。
このインスタンスには、全てのタグとフィルタが登録される。
}}}

の為。

次に[[BR]]
Django テンプレート言語で使えるようにするために Library インスタンスに登録する必要があります。[[BR]]
※バージョン 2.4 以上の Python を使っているのなら、 register.filter() デコレータを使えます

なので、

下記も記述する。

{{{
#!python
@register.filter
}}}

ドキュメントに記載されている通り

{{{
#!python
@register.filter(name=’rawtext’)
}}}

でも良い。[[BR]]
今回は関数名をそのままフィルタ名として使用するので省略。[[BR]]

次に実際に作成したテンプレートフィルタを使用する。[[BR]]
下記を使用するテンプレートに記述する。[[BR]]

{{{
#!python
{% load rawtext %}
}}}

フィルタの使用例は下記になる。

{{{
#!python
{{ comment|rawtext }}
}}}

のようになる。

「reStructuredText」のみを表示する場合は、

{{{
#!python
{{ comment|restructuredtext }}
}}}
よって、

ユーがー側のコメントを表示する部分を

{{{
#!python
{{ comment|restructuredtext }}
}}}

にして、

管理画面でテキストエリア(tipstext)に入力された部分を表示する場合を

{{{
#!python
{{ tipstext|rawtext }}
}}}

と記述する。

入力方法は

「reStructuredText」で入力する場合は、

{{{
.. sourcecode:: 言語(javascriptやpythonなどのように)

$(‘hoge’).html(‘hige’)
}}}

そうすると下記のような感じで表示される。

{{{
#!javascript
$(‘hoge’).html(‘hige’)
}}}

「HTML」を表示させる場合は、

{{{
.. raw::


}}}

これでテキストボックスがそのまま表示される。

これで2パターン対応する事が出来た。

参考サイト[[BR]]
Djangoオンラインドキュメント和訳[[BR]]

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です