Drkcore

03 03 2013 Python Flask SQLAlchemy Tweet

FlaskとSQLAlchemyでつくるreStructuredTextなWiki (5)

reStructuredTextをHTMLにコンバートする

まずはreStructuredTextをHTMLにコンバートするためにdocutilsをインストールします。

pip install docutils

modelを修正してreStructuredTextをHTMLにコンバートするメソッドを追加します。

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 '<Title %r>' % (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にコンバートしたものにします。

@app.route("/<title>", methods=["POST"])
def post_content(title=None):
    ...略...
    return content.html

httpieでちょっとテストしてみます

$ 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

{% extends "layout.html" %}
{% block body %}
<h1>{{content.title}}</h1>
<div>{{content.html|safe}}</div>
<p>{{content.date}}</p>
{% endblock %}

content.bodyをhtmlに変更するだけですが、そのままだとHTMLタグがエスケープされてしまうのでsafeフィルターを付ける必要があります。

flaski4

クリックで書き換えられるようにする

wikiのコンテンツエリアをクリックした時にformの編集画面に切り替わるようにします。そのためにjeditableプラグインを利用するのでminifyバージョンをstaticディレクトリにダウンロードしておいてください。

これはajaxで通信するので編集画面に切り替わった際に元データをGETするためのAPIを用意しておきます。

app.pyに次の関数を追加します。

@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

{% 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で呼び出すようになっています。

コンテンツをクリックすると編集画面になるので

flaski5

日本酒に対する熱い思いをぶつけます。

flaski6

ここまでのGitHub

  • rstのコンバートに対応
  • テンプレートのrst対応
  • クリック編集画面の実装

まとめ

reStructuredTextなWikiのための機能はひと通り揃いました。あとは見栄えを良くするためにStylus+Nib+Nibbleあたりでデザインをちょこまかいじればいいでしょう。

1362294513

About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021