django フォームに WMD エディタを接続するにはどうすればよいですか?
3 に答える
完全な Django ウィジェット クラスは次のとおりです。
class WMDEditor(forms.Textarea):
def __init__(self, *args, **kwargs):
attrs = kwargs.setdefault('attrs', {})
if 'cols' not in attrs:
attrs['cols'] = 58
if 'rows' not in attrs:
attrs['rows'] = 8
super(WMDEditor, self).__init__(*args, **kwargs)
def render(self, name, value, attrs=None):
rendered = super(WMDEditor, self).render(name, value, attrs)
return rendered + mark_safe(u'''<script type="text/javascript">
wmd_options = {
output: "Markdown",
buttons: "bold italic | link blockquote code image | ol ul"
};
</script>
<script type="text/javascript" src="%sjs/wmd/wmd.js"></script>''' % settings.MEDIA_URL)
のようなフォーム定義で使用しますtext = forms.CharField(widget=WMDEditor)
。
現在の WMD ダウンロードの readme.txt から:
<body>
エディターをインストールするには、終了タグの直前に wmd.js を含めます。<script type="text/javascript" src="wmd/wmd.js"></script>
例:
<!DOCTYPE html> <html> <head> <title>My Page</title> </head> <body> <textarea></textarea> <script type="text/javascript" src="wmd/wmd.js"></script> </body> </html>
デフォルトでは、WMD はページの最初のテキストエリアをエディターに変えます。
wmd-ignore
以下で説明するクラスを使用して、この動作を変更でき ます。( に示すように、自動起動を無効にして、JavaScript を使用してエディターをインスタンス化することもできますapiExample.html
。ただし、現在の API は、今後のオープンソース リリースで大幅に変更されることに注意してください。実際に公開されることは決してありませんでした。)
したがって、フォームをレンダリングするために使用しているテンプレートに必要なコードを追加し、WMD を使用するテキストエリアがページの最初にあることを確認してください。
私はこれをやり終えました。他の回答でカバーされていないことに注意する必要がある微妙な点がさらにいくつかあります (これまでのところ)。
まず、フォームが送信されたときに Django が WMD エディターの値を適切に取得できるようにするには、id="" に Django の値を設定する必要があります。通常、これは「id_」のようになります
しかし、#1 が問題を引き起こします。WMD エディタは、使用するテキスト領域を知るために id="wmd-input" を探すようにハードコードされています。
したがって、id 属性の値を WMD に渡す方法が必要です。Django テンプレートにグローバルな JavaScript 変数をレンダリングさせることで、これを自分で行いました。これを実行すると、WMD がクライアント側を使用して textarea タグを適切に見つけることができます。
WMD id タグをやり直す場合は、CSS が引き続き機能することも確認する必要があります。
最後に、値が Django によって事前設定されるようにするには、値が textarea タグでレンダリングされていることを確認する必要があります。
だからここにあなたのためのいくつかのコードがあります。
widgets.py
from django import forms
from django.contrib.admin import widgets as admin_widgets
from django.template import loader, Context
from django.utils.html import conditional_escape
from django.utils.encoding import force_unicode
class WMDEditor(forms.Textarea):
def render(self, name, value, attrs=None):
# Prepare values
if not value:
value = ''
attrs = self.build_attrs(attrs, name=name)
# Render widget to HTML
t = loader.get_template('wmd/widget.html')
c = Context({
'attributes' : self._render_attrs(attrs),
'value' : conditional_escape(force_unicode(value)),
'id' : attrs['id'],
})
return t.render(c)
wmd/widget.html
(アプリに必要な名前を付けます)
<div class="wmd-wrapper">
<div id="wmd-button-bar" class="wmd-panel"></div><br/>
<textarea class="wmd-panel wmd-input" {{ attributes|safe }}>{{ value }}</textarea><br/>
Preview
<div id="wmd-preview" class="wmd-panel"></div><br/>
</div>
<script type="text/javascript">// <![CDATA[
var WMD_TEXTAREA_ID = '{{ id }}'
// ]]> </script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/wmd/wmd.js"></script>
注: MEDIA_URL の処理方法 (カスタム テンプレート タグ、ミドルウェアなど) に応じて、MEDIA_URL を調整する必要がある場合があります。あなたが Django に不慣れで、私が言ったことを理解していない場合は、とりあえず値をハードコードして機能させ、後でそれが何を意味するかを学んでください。
最後に、WMD ソースに 1 つのマイナーな編集を加える必要があります (私は StackOverflow フォークを使用しているため、これは他のバージョンでは少し異なる可能性があることに注意してください)。
wmd.js
// This is around line 69
// Change this -> this.input = doc.getElementById("wmd-input");
// Into this:
this.input = doc.getElementById(WMD_TEXTAREA_ID);
wmd.css を使用していて、まだ独自のものを作成していない場合は、これも少し更新する必要があります。その要素は #wmd-input ではないため、wmd-input クラスを使用するように更新する必要があります。
wmd.css
.wmd-input, /* <-- Add this here, around line 33 */
#wmd-input
{
height: 250px;
width: 100%;
background-color: #FFFFFF;
border: 1px solid #4d86c1;
}
うわー!それは束でした。それがみんなに役立つことを願っています。