Removed django.contrib.markup.
This commit is contained in:
parent
f27a4ee327
commit
ebd2598596
|
@ -1,90 +0,0 @@
|
||||||
"""
|
|
||||||
Set of "markup" template filters for Django. These filters transform plain text
|
|
||||||
markup syntaxes to HTML; currently there is support for:
|
|
||||||
|
|
||||||
* Textile, which requires the PyTextile library available at
|
|
||||||
http://loopcore.com/python-textile/
|
|
||||||
|
|
||||||
* Markdown, which requires the Python-markdown library from
|
|
||||||
http://www.freewisdom.org/projects/python-markdown
|
|
||||||
|
|
||||||
* reStructuredText, which requires docutils from http://docutils.sf.net/
|
|
||||||
"""
|
|
||||||
|
|
||||||
from django import template
|
|
||||||
from django.conf import settings
|
|
||||||
from django.utils.encoding import force_bytes, force_text
|
|
||||||
from django.utils.safestring import mark_safe
|
|
||||||
|
|
||||||
register = template.Library()
|
|
||||||
|
|
||||||
@register.filter(is_safe=True)
|
|
||||||
def textile(value):
|
|
||||||
try:
|
|
||||||
import textile
|
|
||||||
except ImportError:
|
|
||||||
if settings.DEBUG:
|
|
||||||
raise template.TemplateSyntaxError("Error in 'textile' filter: The Python textile library isn't installed.")
|
|
||||||
return force_text(value)
|
|
||||||
else:
|
|
||||||
return mark_safe(force_text(textile.textile(force_bytes(value), encoding='utf-8', output='utf-8')))
|
|
||||||
|
|
||||||
@register.filter(is_safe=True)
|
|
||||||
def markdown(value, arg=''):
|
|
||||||
"""
|
|
||||||
Runs Markdown over a given value, optionally using various
|
|
||||||
extensions python-markdown supports.
|
|
||||||
|
|
||||||
Syntax::
|
|
||||||
|
|
||||||
{{ value|markdown:"extension1_name,extension2_name..." }}
|
|
||||||
|
|
||||||
To enable safe mode, which strips raw HTML and only returns HTML
|
|
||||||
generated by actual Markdown syntax, pass "safe" as the first
|
|
||||||
extension in the list.
|
|
||||||
|
|
||||||
If the version of Markdown in use does not support extensions,
|
|
||||||
they will be silently ignored.
|
|
||||||
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
warnings.warn('The markdown filter has been deprecated',
|
|
||||||
category=DeprecationWarning)
|
|
||||||
try:
|
|
||||||
import markdown
|
|
||||||
except ImportError:
|
|
||||||
if settings.DEBUG:
|
|
||||||
raise template.TemplateSyntaxError("Error in 'markdown' filter: The Python markdown library isn't installed.")
|
|
||||||
return force_text(value)
|
|
||||||
else:
|
|
||||||
markdown_vers = getattr(markdown, "version_info", 0)
|
|
||||||
if markdown_vers < (2, 1):
|
|
||||||
if settings.DEBUG:
|
|
||||||
raise template.TemplateSyntaxError(
|
|
||||||
"Error in 'markdown' filter: Django does not support versions of the Python markdown library < 2.1.")
|
|
||||||
return force_text(value)
|
|
||||||
else:
|
|
||||||
extensions = [e for e in arg.split(",") if e]
|
|
||||||
if extensions and extensions[0] == "safe":
|
|
||||||
extensions = extensions[1:]
|
|
||||||
return mark_safe(markdown.markdown(
|
|
||||||
force_text(value), extensions, safe_mode=True, enable_attributes=False))
|
|
||||||
else:
|
|
||||||
return mark_safe(markdown.markdown(
|
|
||||||
force_text(value), extensions, safe_mode=False))
|
|
||||||
|
|
||||||
@register.filter(is_safe=True)
|
|
||||||
def restructuredtext(value):
|
|
||||||
import warnings
|
|
||||||
warnings.warn('The restructuredtext filter has been deprecated',
|
|
||||||
category=DeprecationWarning)
|
|
||||||
try:
|
|
||||||
from docutils.core import publish_parts
|
|
||||||
except ImportError:
|
|
||||||
if settings.DEBUG:
|
|
||||||
raise template.TemplateSyntaxError("Error in 'restructuredtext' filter: The Python docutils library isn't installed.")
|
|
||||||
return force_text(value)
|
|
||||||
else:
|
|
||||||
docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
|
|
||||||
parts = publish_parts(source=force_bytes(value), writer_name="html4css1", settings_overrides=docutils_settings)
|
|
||||||
return mark_safe(force_text(parts["fragment"]))
|
|
|
@ -1,108 +0,0 @@
|
||||||
# Quick tests for the markup templatetags (django.contrib.markup)
|
|
||||||
import re
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from django.template import Template, Context
|
|
||||||
from django import test
|
|
||||||
from django.utils import unittest
|
|
||||||
from django.utils.html import escape
|
|
||||||
|
|
||||||
try:
|
|
||||||
import textile
|
|
||||||
except ImportError:
|
|
||||||
textile = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
import markdown
|
|
||||||
markdown_version = getattr(markdown, "version_info", 0)
|
|
||||||
except ImportError:
|
|
||||||
markdown = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
import docutils
|
|
||||||
except ImportError:
|
|
||||||
docutils = None
|
|
||||||
|
|
||||||
class Templates(test.TestCase):
|
|
||||||
|
|
||||||
textile_content = """Paragraph 1
|
|
||||||
|
|
||||||
Paragraph 2 with "quotes" and @code@"""
|
|
||||||
|
|
||||||
markdown_content = """Paragraph 1
|
|
||||||
|
|
||||||
## An h2"""
|
|
||||||
|
|
||||||
rest_content = """Paragraph 1
|
|
||||||
|
|
||||||
Paragraph 2 with a link_
|
|
||||||
|
|
||||||
.. _link: http://www.example.com/"""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.save_warnings_state()
|
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning, module='django.contrib.markup')
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.restore_warnings_state()
|
|
||||||
|
|
||||||
@unittest.skipUnless(textile, 'textile not installed')
|
|
||||||
def test_textile(self):
|
|
||||||
t = Template("{% load markup %}{{ textile_content|textile }}")
|
|
||||||
rendered = t.render(Context({'textile_content':self.textile_content})).strip()
|
|
||||||
self.assertEqual(rendered.replace('\t', ''), """<p>Paragraph 1</p>
|
|
||||||
|
|
||||||
<p>Paragraph 2 with “quotes” and <code>code</code></p>""")
|
|
||||||
|
|
||||||
@unittest.skipIf(textile, 'textile is installed')
|
|
||||||
def test_no_textile(self):
|
|
||||||
t = Template("{% load markup %}{{ textile_content|textile }}")
|
|
||||||
rendered = t.render(Context({'textile_content':self.textile_content})).strip()
|
|
||||||
self.assertEqual(rendered, escape(self.textile_content))
|
|
||||||
|
|
||||||
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
|
|
||||||
def test_markdown(self):
|
|
||||||
t = Template("{% load markup %}{{ markdown_content|markdown }}")
|
|
||||||
rendered = t.render(Context({'markdown_content':self.markdown_content})).strip()
|
|
||||||
pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""")
|
|
||||||
self.assertTrue(pattern.match(rendered))
|
|
||||||
|
|
||||||
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
|
|
||||||
def test_markdown_attribute_disable(self):
|
|
||||||
t = Template("{% load markup %}{{ markdown_content|markdown:'safe' }}")
|
|
||||||
markdown_content = "{@onclick=alert('hi')}some paragraph"
|
|
||||||
rendered = t.render(Context({'markdown_content':markdown_content})).strip()
|
|
||||||
self.assertTrue('@' in rendered)
|
|
||||||
|
|
||||||
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
|
|
||||||
def test_markdown_attribute_enable(self):
|
|
||||||
t = Template("{% load markup %}{{ markdown_content|markdown }}")
|
|
||||||
markdown_content = "{@onclick=alert('hi')}some paragraph"
|
|
||||||
rendered = t.render(Context({'markdown_content':markdown_content})).strip()
|
|
||||||
self.assertFalse('@' in rendered)
|
|
||||||
|
|
||||||
@unittest.skipIf(markdown, 'markdown is installed')
|
|
||||||
def test_no_markdown(self):
|
|
||||||
t = Template("{% load markup %}{{ markdown_content|markdown }}")
|
|
||||||
rendered = t.render(Context({'markdown_content':self.markdown_content})).strip()
|
|
||||||
self.assertEqual(rendered, self.markdown_content)
|
|
||||||
|
|
||||||
@unittest.skipUnless(docutils, 'docutils not installed')
|
|
||||||
def test_docutils(self):
|
|
||||||
t = Template("{% load markup %}{{ rest_content|restructuredtext }}")
|
|
||||||
rendered = t.render(Context({'rest_content':self.rest_content})).strip()
|
|
||||||
# Different versions of docutils return slightly different HTML
|
|
||||||
try:
|
|
||||||
# Docutils v0.4 and earlier
|
|
||||||
self.assertEqual(rendered, """<p>Paragraph 1</p>
|
|
||||||
<p>Paragraph 2 with a <a class="reference" href="http://www.example.com/">link</a></p>""")
|
|
||||||
except AssertionError:
|
|
||||||
# Docutils from SVN (which will become 0.5)
|
|
||||||
self.assertEqual(rendered, """<p>Paragraph 1</p>
|
|
||||||
<p>Paragraph 2 with a <a class="reference external" href="http://www.example.com/">link</a></p>""")
|
|
||||||
|
|
||||||
@unittest.skipIf(docutils, 'docutils is installed')
|
|
||||||
def test_no_docutils(self):
|
|
||||||
t = Template("{% load markup %}{{ rest_content|restructuredtext }}")
|
|
||||||
rendered = t.render(Context({'rest_content':self.rest_content})).strip()
|
|
||||||
self.assertEqual(rendered, self.rest_content)
|
|
|
@ -145,9 +145,6 @@ If you want to run the full suite of tests, you'll need to install a number of
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
||||||
* PyYAML_
|
* PyYAML_
|
||||||
* Markdown_
|
|
||||||
* Textile_
|
|
||||||
* Docutils_
|
|
||||||
* setuptools_
|
* setuptools_
|
||||||
* memcached_, plus a :ref:`supported Python binding <memcached>`
|
* memcached_, plus a :ref:`supported Python binding <memcached>`
|
||||||
* gettext_ (:ref:`gettext_on_windows`)
|
* gettext_ (:ref:`gettext_on_windows`)
|
||||||
|
@ -160,9 +157,6 @@ Each of these dependencies is optional. If you're missing any of them, the
|
||||||
associated tests will be skipped.
|
associated tests will be skipped.
|
||||||
|
|
||||||
.. _PyYAML: http://pyyaml.org/wiki/PyYAML
|
.. _PyYAML: http://pyyaml.org/wiki/PyYAML
|
||||||
.. _Markdown: http://pypi.python.org/pypi/Markdown/1.7
|
|
||||||
.. _Textile: http://pypi.python.org/pypi/textile
|
|
||||||
.. _docutils: http://pypi.python.org/pypi/docutils/0.4
|
|
||||||
.. _setuptools: http://pypi.python.org/pypi/setuptools/
|
.. _setuptools: http://pypi.python.org/pypi/setuptools/
|
||||||
.. _memcached: http://memcached.org/
|
.. _memcached: http://memcached.org/
|
||||||
.. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html
|
.. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html
|
||||||
|
@ -200,7 +194,7 @@ multiple modules by using a ``tests`` directory in the normal Python way.
|
||||||
For the tests to be found, a ``models.py`` file must exist, even if it's empty.
|
For the tests to be found, a ``models.py`` file must exist, even if it's empty.
|
||||||
If you have URLs that need to be mapped, put them in ``tests/urls.py``.
|
If you have URLs that need to be mapped, put them in ``tests/urls.py``.
|
||||||
|
|
||||||
To run tests for just one contrib app (e.g. ``markup``), use the same
|
To run tests for just one contrib app (e.g. ``auth``), use the same
|
||||||
method as above::
|
method as above::
|
||||||
|
|
||||||
./runtests.py --settings=settings markup
|
./runtests.py --settings=settings auth
|
||||||
|
|
|
@ -31,7 +31,6 @@ those packages have.
|
||||||
formtools/index
|
formtools/index
|
||||||
gis/index
|
gis/index
|
||||||
humanize
|
humanize
|
||||||
markup
|
|
||||||
messages
|
messages
|
||||||
redirects
|
redirects
|
||||||
sitemaps
|
sitemaps
|
||||||
|
@ -121,13 +120,6 @@ A set of Django template filters useful for adding a "human touch" to data.
|
||||||
|
|
||||||
See the :doc:`humanize documentation </ref/contrib/humanize>`.
|
See the :doc:`humanize documentation </ref/contrib/humanize>`.
|
||||||
|
|
||||||
markup
|
|
||||||
======
|
|
||||||
|
|
||||||
A collection of template filters that implement common markup languages
|
|
||||||
|
|
||||||
See the :doc:`markup documentation </ref/contrib/markup>`.
|
|
||||||
|
|
||||||
messages
|
messages
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
=====================
|
|
||||||
django.contrib.markup
|
|
||||||
=====================
|
|
||||||
|
|
||||||
.. module:: django.contrib.markup
|
|
||||||
:synopsis: A collection of template filters that implement common markup languages.
|
|
||||||
|
|
||||||
.. deprecated:: 1.5
|
|
||||||
This module has been deprecated.
|
|
||||||
|
|
||||||
Django provides template filters that implement the following markup
|
|
||||||
languages:
|
|
||||||
|
|
||||||
* ``textile`` -- implements `Textile`_ -- requires `PyTextile`_
|
|
||||||
* ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_ (>=2.1)
|
|
||||||
* ``restructuredtext`` -- implements `reST (reStructured Text)`_
|
|
||||||
-- requires `doc-utils`_
|
|
||||||
|
|
||||||
In each case, the filter expects formatted markup as a string and
|
|
||||||
returns a string representing the marked-up text. For example, the
|
|
||||||
``textile`` filter converts text that is marked-up in Textile format
|
|
||||||
to HTML.
|
|
||||||
|
|
||||||
To activate these filters, add ``'django.contrib.markup'`` to your
|
|
||||||
:setting:`INSTALLED_APPS` setting. Once you've done that, use
|
|
||||||
``{% load markup %}`` in a template, and you'll have access to these filters.
|
|
||||||
For more documentation, read the source code in
|
|
||||||
:file:`django/contrib/markup/templatetags/markup.py`.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
The output of markup filters is marked "safe" and will not be escaped when
|
|
||||||
rendered in a template. Always be careful to sanitize your inputs and make
|
|
||||||
sure you are not leaving yourself vulnerable to cross-site scripting or
|
|
||||||
other types of attacks.
|
|
||||||
|
|
||||||
.. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29
|
|
||||||
.. _Markdown: http://en.wikipedia.org/wiki/Markdown
|
|
||||||
.. _reST (reStructured Text): http://en.wikipedia.org/wiki/ReStructuredText
|
|
||||||
.. _PyTextile: http://loopcore.com/python-textile/
|
|
||||||
.. _Python-markdown: http://pypi.python.org/pypi/Markdown
|
|
||||||
.. _doc-utils: http://docutils.sf.net/
|
|
||||||
|
|
||||||
reStructured Text
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
When using the ``restructuredtext`` markup filter you can define a
|
|
||||||
:setting:`RESTRUCTUREDTEXT_FILTER_SETTINGS` in your django settings to
|
|
||||||
override the default writer settings. See the `restructuredtext writer
|
|
||||||
settings`_ for details on what these settings are.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
reStructured Text has features that allow raw HTML to be included, and that
|
|
||||||
allow arbitrary files to be included. These can lead to XSS vulnerabilities
|
|
||||||
and leaking of private information. It is your responsibility to check the
|
|
||||||
features of this library and configure appropriately to avoid this. See the
|
|
||||||
`Deploying Docutils Securely
|
|
||||||
<http://docutils.sourceforge.net/docs/howto/security.html>`_ documentation.
|
|
||||||
|
|
||||||
.. _restructuredtext writer settings: http://docutils.sourceforge.net/docs/user/config.html#html4css1-writer
|
|
||||||
|
|
||||||
Markdown
|
|
||||||
--------
|
|
||||||
|
|
||||||
The Python Markdown library supports options named "safe_mode" and
|
|
||||||
"enable_attributes". Both relate to the security of the output. To enable both
|
|
||||||
options in tandem, the markdown filter supports the "safe" argument::
|
|
||||||
|
|
||||||
{{ markdown_content_var|markdown:"safe" }}
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Versions of the Python-Markdown library prior to 2.1 do not support the
|
|
||||||
optional disabling of attributes. This is a security flaw. Therefore,
|
|
||||||
``django.contrib.markup`` has dropped support for versions of
|
|
||||||
Python-Markdown < 2.1 in Django 1.5.
|
|
|
@ -1502,20 +1502,6 @@ Default: ``()`` (Empty tuple)
|
||||||
A tuple of profanities, as strings, that will be forbidden in comments when
|
A tuple of profanities, as strings, that will be forbidden in comments when
|
||||||
``COMMENTS_ALLOW_PROFANITIES`` is ``False``.
|
``COMMENTS_ALLOW_PROFANITIES`` is ``False``.
|
||||||
|
|
||||||
.. setting:: RESTRUCTUREDTEXT_FILTER_SETTINGS
|
|
||||||
|
|
||||||
RESTRUCTUREDTEXT_FILTER_SETTINGS
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
Default: ``{}``
|
|
||||||
|
|
||||||
A dictionary containing settings for the ``restructuredtext`` markup filter from
|
|
||||||
the :doc:`django.contrib.markup application </ref/contrib/markup>`. They override
|
|
||||||
the default writer settings. See the Docutils restructuredtext `writer settings
|
|
||||||
docs`_ for details.
|
|
||||||
|
|
||||||
.. _writer settings docs: http://docutils.sourceforge.net/docs/user/config.html#html4css1-writer
|
|
||||||
|
|
||||||
.. setting:: ROOT_URLCONF
|
.. setting:: ROOT_URLCONF
|
||||||
|
|
||||||
ROOT_URLCONF
|
ROOT_URLCONF
|
||||||
|
|
|
@ -2356,16 +2356,6 @@ django.contrib.humanize
|
||||||
A set of Django template filters useful for adding a "human touch" to data. See
|
A set of Django template filters useful for adding a "human touch" to data. See
|
||||||
:doc:`/ref/contrib/humanize`.
|
:doc:`/ref/contrib/humanize`.
|
||||||
|
|
||||||
django.contrib.markup
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
A collection of template filters that implement these common markup languages:
|
|
||||||
|
|
||||||
* Textile
|
|
||||||
* Markdown
|
|
||||||
* reST (reStructuredText)
|
|
||||||
|
|
||||||
See the :doc:`markup documentation </ref/contrib/markup>`.
|
|
||||||
|
|
||||||
django.contrib.webdesign
|
django.contrib.webdesign
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -48,13 +48,6 @@ escaping.
|
||||||
You should also be very careful when storing HTML in the database, especially
|
You should also be very careful when storing HTML in the database, especially
|
||||||
when that HTML is retrieved and displayed.
|
when that HTML is retrieved and displayed.
|
||||||
|
|
||||||
Markup library
|
|
||||||
--------------
|
|
||||||
|
|
||||||
If you use :mod:`django.contrib.markup`, you need to ensure that the filters are
|
|
||||||
only used on trusted input, or that you have correctly configured them to ensure
|
|
||||||
they do not allow raw HTML output. See the documentation of that module for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
Cross site request forgery (CSRF) protection
|
Cross site request forgery (CSRF) protection
|
||||||
============================================
|
============================================
|
||||||
|
|
Loading…
Reference in New Issue