跳转到主要内容

使用MarkItUp!通用标记编辑器对Django进行标记处理

项目描述

Latest PyPI version Number of PyPI downloads Supported Python versions Github Actions CI

A Django可重用应用程序,用于端到端的标记处理。包括

  • 在Django项目中轻松集成MarkItUp!标记编辑器小部件(由Jay Salvat开发),并支持MarkItUp!的AJAX预览。通过表单小部件或模板标记插件MarkItUp!。

  • MarkupField,这是一个TextField,它自动在数据库中渲染和存储其原始和渲染值,假设在Web应用程序中磁盘空间比CPU周期更便宜。

安装

从PyPI安装

pip install django-markitup

在您的Django项目中使用django-markitup

  1. 'markitup'添加到您的INSTALLED_APPS设置中。

  2. 使markitup/static/markitup目录的内容在STATIC_URL/markitup下可用;最简单的方法是通过django.contrib.staticfiles

  3. 设置MARKITUP_FILTER设置

  4. 如果您想使用基于AJAX的预览,请添加

    url(r'^markitup/', include('markitup.urls'))到您的根URLconf中。

依赖关系

django-markitup 4.1.x需要Django 2.2或更高版本和Python 3.5+。

django-markitup 4.0.x需要Django 1.11或更高版本和Python 3.5+。

django-markitup 3.x需要Django 1.8或更高版本和Python 2.7+或3.4+。

django-markitup 2.x需要Django 1.4或更高版本和Python 2.6+或3.3+。

django-markitup 1.x需要Django 1.3或更高版本和Python 2.5或更高版本。

MarkItUp!不是外部依赖项;它包含在django-markitup中。

使用MarkItUp!小部件

MarkItUp!小部件位于markitup.widgets.MarkItUpWidget,可以像使用任何其他Django自定义小部件一样使用。

将其分配给表单字段

from markitup.widgets import MarkItUpWidget

class MyForm(forms.Form):
    content = forms.CharField(widget=MarkItUpWidget())

当此表单在您的网站上显示时,您必须在页面上某处包含表单媒体(使用{{ form.media }}),否则MarkItUpWidget将不起作用。默认情况下,{{ form.media }}还包含基于您的JQUERY_URL设置的jQuery库。要防止包括jQuery,请将JQUERY_URL设置设置为None

MarkItUpWidget接受三个可选的关键字参数:markitup_setmarkitup_skin(见选择MarkItUp!按钮集和皮肤)以及auto_preview(用于覆盖MARKITUP_AUTO_PREVIEW设置的值)。

在Django管理中使用小部件

from markitup.widgets import AdminMarkItUpWidget

class MyModelForm(forms.ModelForm):
    content = forms.CharField(widget=AdminMarkItUpWidget())
    # ...

class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm
    # ...

您还可以使用ModelAdmin的formfield_overrides属性,这更简单,但只能按字段类型设置小部件(因此无法在模型的一个TextField上使用MarkItUpWidget而另一个不使用)

from markitup.widgets import AdminMarkItUpWidget

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {models.TextField: {'widget': AdminMarkItUpWidget}}
如果您在模型中使用MarkupField,则它默认使用AdminMarkItUpWidget进行渲染

在管理界面中。

通过templatetags使用MarkItUp!

在某些情况下,使用 MarkItUpWidget 可能不方便(例如,如果表单是在第三方代码中定义的)。对于这些情况,django-markitup 提供了模板标签,以在模板中纯量地实现相同的效果。

首先,加载 django-markitup 模板标签库

{% load markitup_tags %}

然后,在您页面的 <head> 中包含 MarkItUp! CSS 和 Javascript

{% markitup_media %}

默认情况下,markitup_media 标签根据您的 JQUERY_URL 设置值包括 jQuery,并回退到 Google Ajax APIs 上托管的版本。如果您已经自己包含了 jQuery(要抑制 jQuery 的包含),请将 JQUERY_URL 设置为 None

如果您希望从不同的位置链接 CSS 和 Javascript,则可以将 markitup_media 标签替换为两个单独的标签,markitup_cssmarkitup_jsmarkitup_js 接受一个参数来抑制 jQuery 的包含,就像 markitup_media 一样。

最后,使用 markitup_editor 模板标签将 MarkItUp! 编辑器应用到您页面中的 textarea。它接受一个参数,即 textarea 的 HTML id。如果您通过 Django 表单对象以通常的方式渲染 textarea,则该 id 值可用作 form.fieldname.auto_id

{{ form.fieldname }}

{% markitup_editor form.fieldname.auto_id %}

您可以在任何数量的不同 textarea 上使用 markitup_editor

markitup_editor 接受一个可选的第二个参数,该参数可以是 "auto_preview""no_auto_preview",以覆盖 MARKITUP_AUTO_PREVIEW 设置的值。

这些模板标签实际包含的 HTML 由模板 markitup/include_css.htmlmarkitup/include_js.htmlmarkitup/editor.html 的内容定义。您可以在项目中覆盖这些模板,并根据您的需要进行自定义。

MarkupField

您可以使用上述技术将 MarkItUp! 编辑器控件应用到任何 textarea,并按您喜欢的任何方式在服务器端处理标记。

为了提供一个无缝的标记处理解决方案,django-markitup 还提供了一个 MarkupField 模型字段,该字段自动将原始值和渲染值渲染并存储在数据库中,使用 MARKITUP_FILTER 设置 值将标记解析为 HTML。

MarkupField 很容易添加到任何模型定义中

from django.db import models
from markitup.fields import MarkupField

class Article(models.Model):
    title = models.CharField(max_length=100)
    body = MarkupField()

MarkupField 自动创建一个额外的不可编辑字段 _body_rendered 来存储渲染的标记。该字段不需要直接访问;请参见下面的说明。

在模型上访问 MarkupField

当访问被声明为 MarkupField 的模型属性时,会返回一个 Markup 对象。该 Markup 对象有两个属性

raw:

未渲染的标记。

rendered:

raw 的渲染 HTML 版本(只读)。

该对象还有一个 __unicode__ 方法,它会在 rendered 上调用 django.utils.safestring.mark_safe,允许 MarkupField 属性以渲染的 HTML 形式出现在模板中,而不需要任何特殊的模板标签或直接访问 rendered

假设上面的 Article 模型

>>> a = Article.objects.all()[0]
>>> a.body.raw
'*fancy*'
>>> a.body.rendered
'<p><em>fancy</em></p>'
>>> print(unicode(a.body))
<p><em>fancy</em></p>
>>> a.body.render_with('markitup.renderers.render_rest')
>>> print(unicode(a.body))
'<div class="document">\n<p><em>fancy</em></p>\n</div>\n'

a.body 的赋值等效于将 a.body.raw 赋值。

在表单中编辑 MarkupField

当在《ModelForm》模型属性(即在Django管理后台中)编辑《MarkupField》时,通常需要编辑原始标记而不是渲染的HTML。因为《Markup》对象从其__unicode__方法返回渲染的HTML,所以需要使用来自《markupfield.widgets》模块的《MarkupTextarea》小部件,它知道返回原始标记。

默认情况下,《MarkupField》在管理后台中(通过提供的《AdminMarkItUpWidget》)使用MarkItUp!编辑器控件,但在其他表单中使用纯《MarkupTextarea》。如果您想在您的表单中使用MarkItUp!编辑器与这个《MarkupField》,则需要使用提供的《MarkItUpWidget》而不是《MarkupTextarea》。

如果您将自定义小部件应用于表示《MarkupField》的表单字段,则您的部件必须继承自《MarkupTextarea》或其《render》方法必须将其《value》参数转换为《value.raw》。

选择MarkItUp!按钮集和皮肤

MarkItUp!允许通过JavaScript设置文件自定义工具栏按钮集。默认情况下,django-markitup使用“default”集(适用于HTML编辑)。Django-markitup还包括基本的“markdown”和“textile”集(这些来自MarkItUp网站),以及一个“restructuredtext”集。

要使用备用集,将《MARKITUP_SET》设置分配给集目录的URL路径(绝对路径或相对于《STATIC_URL》的相对路径)。例如,要使用django-markitup包含的“markdown”集

MARKITUP_SET = 'markitup/sets/markdown/'

以类似方式指定MarkItUp!皮肤。默认情况下包括“simple”和“markitup”皮肤,“simple”被使用。要使用“markitup”皮肤代替

MARKITUP_SKIN = 'markitup/skins/markitup/'

这些设置不必引用django-markitup媒体内部的位置。您可以定义自己的集和皮肤并将其存储在任何位置,只要将《MARKITUP_SET》和《MARKITUP_SKIN》设置设置为适当的URL。

可以通过将《markitup_set》和《markitup_skin》关键字参数传递给MarkItUpWidget,在单个小部件的基础上选择设置和皮肤。

使用AJAX预览

如果您已在根URLconf中包含《markitup.urls》(如上所述在《安装》部分所示),要启用服务器端AJAX预览,只需要《MARKITUP_FILTER》设置

渲染的HTML内容在由《markitup/preview.html》模板生成的HTML页面中显示,您可以在项目中对该模板进行覆盖并自定义预览输出。

《MARKITUP_FILTER》设置

《MARKITUP_FILTER》设置定义了标记如何在您的网站上转换为HTML。此设置仅在您使用《MarkupField》或MarkItUp! AJAX预览时需要。

《MARKITUP_FILTER》必须是一个二元组。第一个元素必须是一个字符串,Python点路径到一个标记过滤函数。该函数应接受标记作为其第一个参数并返回HTML。它可以接受其他关键字参数。您可以按照您选择的方法解析您的标记,只要您可以将其包装在一个满足这些标准的函数中。

第二个元素必须是要传递给过滤函数的关键字参数的字典。该字典可能为空。

例如,如果您已安装python-markdown,您可以像这样使用它

MARKITUP_FILTER = ('markdown.markdown', {})

或者,您可以使用 django-markwhat 库提供的“textile”过滤器,如下所示

MARKITUP_FILTER = ('django_markwhat.templatetags.markup.textile', {})

(textile 过滤器不接受关键字参数,所以在这种情况下 kwargs 字典必须为空。)

django-markitup 提供了一个示例渲染函数,即 render_rest,位于 markitup.renderers 模块中。

避免跨站脚本(XSS)攻击

如果您的网站正在向世界展示用户提供的标记,那么用户将恶意 <script> 标签(或类似内容)注入到其标记文本中的风险就存在,而您的网站将在其 HTML 页面中渲染这些内容。任何通过 HTML 未修改传递的过滤器(例如 python-markdown)在这里都特别容易受到攻击。

可以通过将渲染的 HTML 通过 bleach 库运行来减轻这种情况,例如

MARKITUP_FILTER = ('my_lib.bleached_markdown', {})

其中 my_lib 包含

import bleach
from bleach_allowlist import markdown_tags, markdown_attrs
from markdown import markdown

def bleached_markdown(text, **kwargs):
    markdown_rendered = markdown(text, **kwargs)
    bleached = bleach.clean(markdown_rendered, markdown_tags, markdown_attrs)
    return bleached

render_markup 模板过滤器

如果您已设置 MARKITUP_FILTER 设置 并使用 MarkItUp! AJAX 预览,但不希望将渲染的标记存储在数据库中的 MarkupField(或正在使用不使用 MarkupField 的第三方模型),您可能希望在模板中使用 MARKITUP_FILTER 函数来渲染内容。为此,您可以使用 render_markup 模板过滤器

{% load markitup_tags %}

{{ post.content|render_markup }}

其他设置

MARKITUP_PREVIEW_FILTER

此可选设置可用于覆盖 Ajax 预览视图使用的标记过滤器,如果出于某种原因需要与用于在 MarkupField 中渲染标记的过滤器不同。它具有与 MARKITUP_FILTER 相同的格式;默认情况下,它设置为等于 MARKITUP_FILTER

MARKITUP_AUTO_PREVIEW

如果设置为 True,预览窗口将默认激活。默认为 False

JQUERY_URL

MarkItUp! 需要jQuery JavaScript库。默认情况下,django-markitup 通过 //ajax.googleapis.ac.cn/ajax/libs/jquery/2.0.3/jquery.min.js 链接到 ajax.googleapis.com 的 jQuery 2.0.3(通过 URL)。如果您希望使用不同的 jQuery 版本或自己托管它,请设置 JQUERY_URL 设置。例如

JQUERY_URL = 'jquery.min.js'

这将使用位于 STATIC_URL/jquery.min.js 的 jQuery。一个相对 JQUERY_URL 是相对于 STATIC_URL 的。

如果您手动在模板中包含 jQuery 库且不希望 django-markitup 包含它,请将 JQUERY_URL 设置为 None。CHANGES =======

4.1.0 (2022-08-25)

  • 添加对 Django 4.0 & 4.1 的支持。

4.0.0 (2020.04.06)

  • 放弃对 Python 2.7 的支持。

  • 放弃与 Django < 1.11 的兼容性。

3.5.0 (2020.02.09)

  • 添加对 Django 1.11 和 2.0 的支持。

3.0.0 (2016.09.04)

  • 放弃对 Python 3.3 的支持。

  • 放弃与 Django < 1.8 的兼容性。

2.3.1 (2016.02.06)

  • 使用无协议的 URL 避免外部托管 jQuery 的浏览器警告。

2.3.0 (2016.01.17)

  • 模板标签现在支持 Django 的 STATICFILES_STORAGE 设置。感谢 Ivan Ven Osdel 提供的报告和修复。

  • 添加了 render_with 方法,用于使用不同的过滤器渲染 MarkupField。

  • 放弃与 Django < 1.7 的兼容性。

  • 与 Django 1.8 和 1.9 兼容。感谢 Ivan Ven Osdel 提供的修复!

  • 放弃与 Python 2.6 的兼容性。

  • 添加了对 Python 3.5 的支持。

2.2.2 (2014.09.08)

  • 将 MarkupField 适配到 Django 1.7 迁移。感谢 Neil Muller 提供的报告和修复。

2.2.1 (2014.07.15)

  • 修复了在 Python 2 中使用 MARKITUP_FILTER 和 MARKITUP_PREVIEW_FILTER 的回归。感谢 Berker Peksag 和 Neil Muller 提供的报告,以及 Neil Muller 提供的修复。

2.2 (2014.07.03)

  • 添加了对 Python 3.3+ 的支持。感谢 Berker Peksag。

2.1 (2013.11.11)

  • 将默认 jQuery 版本从 1.6 更新到 2.0.3。

  • 修复了 MARKITUP_AUTO_PREVIEW;2.0 中的“修复”是错误的,导致它崩溃。

2.0 (2013.11.06)

  • 修复了 MARKITUP_AUTO_PREVIEW;MarkItUp! 现在观察鼠标按下事件,而不是鼠标释放。感谢 Alexandr Shurigin。

  • 增加了对 Django 1.6 的支持。

  • 向后不兼容:删除了对 Python 2.5 和 Django 1.3 的支持。

1.1.0 (2013.04.26)

  • 更新到 MarkItUp! 1.1.14 并修复了与 jQuery 1.9 的兼容性。感谢 Roman Akinfold!

  • 修复了带有自定义属性的 MarkItUpWidget。感谢 GeyseR。

  • 动态设置 previewParserPath,而不是要求在 set.js 中设置。感谢 Sebastian Brandt。

  • 修复了 MarkupField 的隐藏小部件渲染。感谢 Aramgutang。

  • 防止对元素应用 MarkItUp! 编辑器两次。修复了 #4。感谢 Rich Leland。

  • Markup 对象中添加了 __len__,以方便在模板中进行长度和真值检查。修复了 #16。感谢 Edmund von der Burg。

1.0.0 (2011.07.11)

  • 删除了对 Django 1.3 之前版本的所有兼容性包装,包括对 MEDIA_URL 中的静态媒体、media/ 下的静态资产以及 MARKITUP_MEDIA_URL 设置的所有支持。

  • 更新到 jquery 1.6。

  • 当在抽象基模型类上使用 MarkupField 时,添加了检查以避免双 _rendered 字段。修复了 #11。感谢 Denis Kolodin 提供的报告和补丁。

  • 添加了对 Django 1.2.5 和 1.3 中新的 AJAX CSRF 要求的兼容性。修复了 #7。感谢 zw0rk 提供的报告。

  • 将 MarkupField 的自动添加的 rendered-field 的 blank=True 添加,以避免 South 警告。

  • Django 1.3 & staticfiles 兼容性:如果设置,MARKITUP_MEDIA_URL 和 jQuery URL 默认为 STATIC_URL 而不是 MEDIA_URL。静态资产现在可以在 static/ 以及 media/ 下找到。感谢 Mikhail Korobov。

  • MarkupField.get_db_prep_value 更新为接受“connection”和“prepared”参数,以避免 Django 1.3 下的弃用警告。感谢 Mikhail Korobov。

  • 为 MarkItUp!-插入的 h1 和 h2 下划线式标题设置最小长度为 3 个字符(绕过 python-markdown 中的错误)。感谢 Daemian Mack 提供的报告。

0.6.1 (2010.07.01)

  • 添加了 reST 的 markitup 设置。感谢 Jannis Leidel。

  • 修复了 reST 渲染器,使其不删除初始标题。感谢 Jannis Leidel。

  • 防止 mark_safe 修改 Markup 对象。

0.6.0 (2010.04.26)

  • 删除了之前弃用的 markitup_head 模板标签。

  • 将 jQuery 使用包装在匿名函数中,以提高对页面上的其他 JS 框架代码(包括其他 jQuery)的鲁棒性。感谢 Mikhael Korneev。

  • 升级到 MarkItUp! 1.1.7

  • 添加了 render_markup 模板过滤器。

  • 更新到 jQuery 1.4 和 MarkItUp! 1.1.6

  • 添加了 auto_preview 选项。

  • Ajax 预览视图现在使用 RequestContext,并且还把 MARKITUP_MEDIA_URL 传递到模板上下文中。(以前,MARKITUP_MEDIA_URL 作为 MEDIA_URL 传递,并且没有使用 RequestContext)。向后不兼容;可能需要更改预览模板。

0.5.2 (2009.11.24)

  • 修复 setup.py,以便不安装 tests 包。

0.5.1 (2009.11.18)

  • 添加了空的 models.py 文件,以便正确在 INSTALLED_APPS 中注册 markitup。修复了与 django-staticfiles 提示找不到媒体的问题。

0.5 (2009.11.12)

  • 添加了 MarkupField(来自 http://github.com/carljm/django-markupfield,感谢 Mike Korobov)

  • 弃用 markitup_head 模板标签,转而使用 markitup_media

  • 添加了 MARKITUP_MEDIA_URL 设置,以覆盖相对媒体 URL 路径的基本部分。

0.3 (2009.11.04)

  • 添加了应用 MarkItUp! 编辑器的模板标签方法(灵感来自 django-wysiwyg)

0.2 (2009.03.18)

  • 初始版本

待办事项

  • 添加对多个标记选项的支持(可能与 django-markup 集成)

  • 链接到实时演示?

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

django-markitup-4.1.0.tar.gz (93.7 kB 查看散列)

上传时间 源代码

构建分发

django_markitup-4.1.0-py3-none-any.whl (112.9 kB 查看散列)

上传时间 Python 3

支持