Как я могу подключить редактор WMD к моим формам Django? - PullRequest
8 голосов
/ 26 января 2009

Как я могу подключить редактор WMD к моим формам Django?

Ответы [ 3 ]

10 голосов
/ 28 января 2009

Вот полный класс виджетов 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).

3 голосов
/ 26 января 2009

Из файла 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>

По умолчанию ОМУ будет первым textarea на вашей странице в редакторе. Вы можете изменить это поведение с помощью wmd-ignore класс, описанный ниже. (Также возможно отключить автозапуск и создание экземпляра редактора через JavaScript, как показано на apiExample.html. Но имейте в виду, что текущий API сильно изменится в предстоящий релиз с открытым исходным кодом; Это никогда не предназначался для публики потребление.)

Итак, добавьте необходимый код в шаблон, который вы используете для визуализации формы, и убедитесь, что текстовое поле, на котором вы хотите использовать ОМУ, является первым на странице, и вам будет хорошо.

2 голосов
/ 07 октября 2009

Я только что закончил делать это. Есть еще пара тонкостей, о которых нужно знать, но они не описаны в других ответах (пока).

  1. Во-первых, чтобы Django правильно извлекал значение редактора WMD при отправке формы, в нем должно быть установлено значение Django для id = "". Обычно это будет выглядеть примерно так: 'id _'

  2. Но # 1 создает проблему: редактор WMD жестко запрограммирован для поиска id = "wmd-input", чтобы узнать, какую текстовую область он использует.

  3. Следовательно, нам нужен способ передать значение атрибута id в ОМП. Я сам сделал это с помощью шаблона Django, отображающего глобальную переменную javascript, которая при выполнении клиентской стороны будет использоваться WMD для правильного определения местоположения тега textarea.

  4. Если мы повторно сделаем тэг идентификатора WMD, нам также нужно убедиться, что CSS все еще работает

  5. Наконец, для того, чтобы значение было предварительно заполнено 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)

ВРС / 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 и не понимаете, что я только что сказал, просто жестко запишите это значение, чтобы оно заработало, и узнайте, что это все значит позже.

Наконец, вам нужно сделать 1 незначительное редактирование источника WMD (обратите внимание, что я использую вилку 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;
}

Уф! Это была куча. Надеюсь, что это поможет всем.

...