Fixed #18041 -- Removed support for Markdown versions < 2.1, following the 1.5 deprecation timeline. Thanks Ramiro Morales for the review.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17909 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Claude Paroz 2012-04-14 12:35:31 +00:00
parent a9187e5447
commit 749243941c
3 changed files with 22 additions and 38 deletions

View File

@ -11,8 +11,6 @@ markup syntaxes to HTML; currently there is support for:
* reStructuredText, which requires docutils from http://docutils.sf.net/ * reStructuredText, which requires docutils from http://docutils.sf.net/
""" """
import warnings
from django import template from django import template
from django.conf import settings from django.conf import settings
from django.utils.encoding import smart_str, force_unicode from django.utils.encoding import smart_str, force_unicode
@ -56,35 +54,21 @@ def markdown(value, arg=''):
raise template.TemplateSyntaxError("Error in 'markdown' filter: The Python markdown library isn't installed.") raise template.TemplateSyntaxError("Error in 'markdown' filter: The Python markdown library isn't installed.")
return force_unicode(value) return force_unicode(value)
else: else:
# markdown.version was first added in 1.6b. The only version of markdown markdown_vers = getattr(markdown, "version_info", 0)
# to fully support extensions before 1.6b was the shortlived 1.6a. if markdown_vers < (2, 1):
if hasattr(markdown, 'version'): if settings.DEBUG:
extensions = [e for e in arg.split(",") if e] raise template.TemplateSyntaxError(
if len(extensions) > 0 and extensions[0] == "safe": "Error in 'markdown' filter: Django does not support versions of the Python markdown library < 2.1.")
extensions = extensions[1:] return force_unicode(value)
safe_mode = True
else:
safe_mode = False
python_markdown_deprecation = "The use of Python-Markdown "
"< 2.1 in Django is deprecated; please update to the current version"
# Unicode support only in markdown v1.7 or above. Version_info
# exist only in markdown v1.6.2rc-2 or above.
markdown_vers = getattr(markdown, "version_info", None)
if markdown_vers < (1,7):
warnings.warn(python_markdown_deprecation, DeprecationWarning)
return mark_safe(force_unicode(markdown.markdown(smart_str(value), extensions, safe_mode=safe_mode)))
else:
if markdown_vers >= (2,1):
if safe_mode:
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode, enable_attributes=False))
else:
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
else:
warnings.warn(python_markdown_deprecation, DeprecationWarning)
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
else: else:
warnings.warn(python_markdown_deprecation, DeprecationWarning) extensions = [e for e in arg.split(",") if e]
return mark_safe(force_unicode(markdown.markdown(smart_str(value)))) if extensions and extensions[0] == "safe":
extensions = extensions[1:]
return mark_safe(markdown.markdown(
force_unicode(value), extensions, safe_mode=True, enable_attributes=False))
else:
return mark_safe(markdown.markdown(
force_unicode(value), extensions, safe_mode=False))
@register.filter(is_safe=True) @register.filter(is_safe=True)
def restructuredtext(value): def restructuredtext(value):

View File

@ -37,7 +37,7 @@ Paragraph 2 with a link_
.. _link: http://www.example.com/""" .. _link: http://www.example.com/"""
@unittest.skipUnless(textile, 'texttile not installed') @unittest.skipUnless(textile, 'textile not installed')
def test_textile(self): def test_textile(self):
t = Template("{% load markup %}{{ textile_content|textile }}") t = Template("{% load markup %}{{ textile_content|textile }}")
rendered = t.render(Context({'textile_content':self.textile_content})).strip() rendered = t.render(Context({'textile_content':self.textile_content})).strip()
@ -45,13 +45,13 @@ Paragraph 2 with a link_
<p>Paragraph 2 with &#8220;quotes&#8221; and <code>code</code></p>""") <p>Paragraph 2 with &#8220;quotes&#8221; and <code>code</code></p>""")
@unittest.skipIf(textile, 'texttile is installed') @unittest.skipIf(textile, 'textile is installed')
def test_no_textile(self): def test_no_textile(self):
t = Template("{% load markup %}{{ textile_content|textile }}") t = Template("{% load markup %}{{ textile_content|textile }}")
rendered = t.render(Context({'textile_content':self.textile_content})).strip() rendered = t.render(Context({'textile_content':self.textile_content})).strip()
self.assertEqual(rendered, escape(self.textile_content)) self.assertEqual(rendered, escape(self.textile_content))
@unittest.skipUnless(markdown, 'markdown not installed') @unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
def test_markdown(self): def test_markdown(self):
t = Template("{% load markup %}{{ markdown_content|markdown }}") t = Template("{% load markup %}{{ markdown_content|markdown }}")
rendered = t.render(Context({'markdown_content':self.markdown_content})).strip() rendered = t.render(Context({'markdown_content':self.markdown_content})).strip()

View File

@ -9,7 +9,7 @@ Django provides template filters that implement the following markup
languages: languages:
* ``textile`` -- implements `Textile`_ -- requires `PyTextile`_ * ``textile`` -- implements `Textile`_ -- requires `PyTextile`_
* ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_ * ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_ (>=2.1)
* ``restructuredtext`` -- implements `reST (reStructured Text)`_ * ``restructuredtext`` -- implements `reST (reStructured Text)`_
-- requires `doc-utils`_ -- requires `doc-utils`_
@ -53,13 +53,13 @@ Markdown
The Python Markdown library supports options named "safe_mode" and The Python Markdown library supports options named "safe_mode" and
"enable_attributes". Both relate to the security of the output. To enable both "enable_attributes". Both relate to the security of the output. To enable both
options in tandem, the markdown filter supports the "safe" argument. options in tandem, the markdown filter supports the "safe" argument::
{{ markdown_content_var|markdown:"safe" }} {{ markdown_content_var|markdown:"safe" }}
.. warning:: .. warning::
Versions of the Python-Markdown library prior to 2.1 do not support the Versions of the Python-Markdown library prior to 2.1 do not support the
optional disabling of attributes and by default they will be included in optional disabling of attributes. This is a security flaw. Therefore,
any output from the markdown filter - a warning is issued if this is the ``django.contrib.markup`` has dropped support for versions of
case. Python-Markdown < 2.1 in Django 1.5.