================== 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("/<title>", 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 <div class="document"> <p>rst <strong>strong</strong> and <em>italic</em></p> </div> 正しく変換されていますね。 テンプレートを修正する ====================== ブラウザでアクセスした場合にもきちんとHTMLが表示されるようにJinja2テンプレートを修正します。 show_content.html .. code-block:: html {% extends "layout.html" %} {% block body %} <h1>{{content.title}}</h1> <div>{{content.html|safe}}</div> <p>{{content.date}}</p> {% endblock %} content.bodyをhtmlに変更するだけですが、そのままだとHTMLタグがエスケープされてしまうのでsafeフィルターを付ける必要があります。 .. image:: static/flaski4.png クリックで書き換えられるようにする ================================== wikiのコンテンツエリアをクリックした時にformの編集画面に切り替わるようにします。 そのためにjQueryの `jeditable <http://www.appelsiini.net/projects/jeditable>`_ プラグインを利用します。 minifyバージョンをstaticディレクトリにダウンロードしておいてください。 jeditableをajaxで通信させたいので編集画面に切り替わった際にhtml変換する前のreStructuredTextをGETするためのAPIを用意するため app.pyに次の関数を追加します。 .. code-block:: python @app.route("/rst/<title>") 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 %} <h1>{{content.title}}</h1> <div class="editable_textarea">{{content.html|safe}}</div> <p>{{content.date}}</p> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="{{url_for('static', filename='jquery.jeditable.mini.js')}}"></script> <script> $(".editable_textarea").editable("{{content.title}}", { type : 'textarea', submitdata: { _method: "post" }, name : 'body', loadurl : '/rst/' + '{{content.title}}', rows : 10, submit : 'OK', cancel : 'cancel', cssclass : "editable" }); </script> {% endblock %} jeditableで操作するためにdiv要素にクラスを追加しています。 bodyの最後にjQueryとjeditableを呼び出しています。先ほどapp.pyに追加した関数はloadurlで呼び出すようになっています。 動かしてみる ============ コンテンツをクリックすると編集画面になるので .. image:: static/flaski5.png 日本酒に対する熱い思いをぶつけます。 .. image:: static/flaski6.png ここまでのGitHub ================ - `rstのコンバートに対応 <https://github.com/kzfm/flaski/commit/095a6237b50f57b4a56602d93e799f30fb96229a>`_ - `テンプレートのrst対応 <https://github.com/kzfm/flaski/commit/19c59fa1214bce747ff7591766d627776a4bb258>`_ - `クリック編集画面の実装 <https://github.com/kzfm/flaski/commit/cbe66d6edcd95d0c610455071b9fecb67c565658>`_