==================
AjaxなWikiにする
==================
reStructuredTextをHTMLにコンバートする
======================================
まずはreStructuredTextをHTMLにコンバートするためにdocutilsをインストールします。
.. code-block:: sh
pip install docutils
modelを修正してreStructuredTextをHTMLにコンバートするメソッドを追加します。
.. code-block:: python
from sqlalchemy import Column, Integer, String, Text, DateTime
from flaski.database import Base
from datetime import datetime
from docutils.core import publish_parts
overrides = {'doctitle_xform': 0,
'initial_header_level': 2}
class WikiContent(Base):
__tablename__ = 'wikicontents'
id = Column(Integer, primary_key=True)
title = Column(String(128), unique=True)
body = Column(Text)
date = Column(DateTime, default=datetime.now())
def __init__(self, title=None, body=None, date=None):
self.title = title
self.body = body
self.date = date
def __repr__(self):
return '
' % (self.title)
@property
def html(self):
parts = publish_parts(source=self.body,
writer_name="html",
settings_overrides=overrides
)
return parts['html_body']
@propertyデコレータを使うことでcontent.html()とメソッド呼び出しではなく
content.htmlとプロバティとしてアクセスできるようになります。
setting_overridesしているのはタイトルをh1要素にしているので、トップレベ
ルのヘッダーをh2から始めたいからです。
postした時の戻り値もhtmlにコンバートしたものにします。
.. code-block:: python
@app.route("/", methods=["POST"])
def post_content(title=None):
...略...
return content.html
httpieでちょっとテストしてみます
.. code-block:: sh
$ http --form POST http://localhost:5000/rsttest body="rst **strong** and *italic*"
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 85
Server: Werkzeug/0.8.3 Python/2.7.3
Date: Sun, 03 Mar 2013 06:29:59 GMT
正しく変換されていますね。
テンプレートを修正する
======================
ブラウザでアクセスした場合にもきちんとHTMLが表示されるようにJinja2テンプレートを修正します。
show_content.html
.. code-block:: html
{% extends "layout.html" %}
{% block body %}
{{content.title}}
{{content.html|safe}}
{{content.date}}
{% endblock %}
content.bodyをhtmlに変更するだけですが、そのままだとHTMLタグがエスケープされてしまうのでsafeフィルターを付ける必要があります。
.. image:: static/flaski4.png
クリックで書き換えられるようにする
==================================
wikiのコンテンツエリアをクリックした時にformの編集画面に切り替わるようにします。
そのためにjQueryの `jeditable `_ プラグインを利用します。
minifyバージョンをstaticディレクトリにダウンロードしておいてください。
jeditableをajaxで通信させたいので編集画面に切り替わった際にhtml変換する前のreStructuredTextをGETするためのAPIを用意するため
app.pyに次の関数を追加します。
.. code-block:: python
@app.route("/rst/")
def show_rst(title):
content = WikiContent.query.filter_by(title=title).first()
if content is None:
abort(404)
return content.body
単にrstなデータを返しているだけですね。
続いてテンプレートも修正します。
show_content.html
.. code-block:: html
{% extends "layout.html" %}
{% block body %}
{{content.title}}
{{content.html|safe}}
{{content.date}}
{% endblock %}
jeditableで操作するためにdiv要素にクラスを追加しています。
bodyの最後にjQueryとjeditableを呼び出しています。先ほどapp.pyに追加した関数はloadurlで呼び出すようになっています。
動かしてみる
============
コンテンツをクリックすると編集画面になるので
.. image:: static/flaski5.png
日本酒に対する熱い思いをぶつけます。
.. image:: static/flaski6.png
ここまでのGitHub
================
- `rstのコンバートに対応 `_
- `テンプレートのrst対応 `_
- `クリック編集画面の実装 `_