8

我如何将 WMD 编辑器连接到我的 django 表单上?

4

3 回答 3

10

这是完整的 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).

于 2009-01-27T21:51:32.627 回答
3

从当前 WMD 下载的 readme.txt 中:

要安装编辑器,请在结束标记之前包含 wmd.js <body>

<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 的文本区域是页面上的第一个,这样就可以了。

于 2009-01-26T14:47:05.277 回答
2

我刚做完这个。还有一些微妙之处需要注意,其他答案(到目前为止)并未涵盖这些细节。

  1. 首先,为了让 Django 在提交表单时正确检索 WMD 编辑器的值,它需要设置 Django 的 id="" 值。通常这看起来像'id_'

  2. 但是#1 产生了一个问题:WMD 编辑器被硬编码为查找 id="wmd-input" 以了解它使用的文本区域。

  3. 因此,我们需要一种将 id 属性的值传递给 WMD 的方法。我自己通过让 Django 模板呈现一个全局 javascript 变量来完成此操作,当执行客户端时,WMD 将使用该变量正确定位 textarea 标记。

  4. 如果我们要重新制作 WMD id 标签,那么我们还需要确保 CSS 仍然有效

  5. 最后,为了让 Django 预先填充该值,我们需要确保该值在 textarea 标记中呈现

所以这里有一些代码给你。

小部件.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。如果您是 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;
}

哇!那是一堆。希望对大家有所帮助。

于 2009-10-07T02:52:07.380 回答