Ticket #10317: markupfield-with-docs.diff
File markupfield-with-docs.diff, 9.3 KB (added by , 16 years ago) |
---|
-
new file django/contrib/markup/fields.py
diff --git a/django/contrib/markup/fields.py b/django/contrib/markup/fields.py new file mode 100644 index 0000000..230e388
- + 1 from django.db import models 2 from django.utils.html import linebreaks, urlize 3 from django.utils.safestring import mark_safe 4 5 PLAIN_TEXT, HTML, MARKDOWN, REST, TEXTILE = range(5) 6 7 # determine available choices dynamically upon first import 8 MARKUP_TYPES = ( 9 (PLAIN_TEXT, 'plain'), 10 (HTML, 'html'), 11 ) 12 13 try: 14 import markdown 15 MARKUP_TYPES += ( (MARKDOWN, 'markdown'), ) 16 except ImportError: 17 pass 18 19 try: 20 from docutils.core import publish_parts 21 MARKUP_TYPES += ( (REST, 'restructuredtext'), ) 22 except ImportError: 23 pass 24 25 try: 26 import textile 27 MARKUP_TYPES += ( (TEXTILE, 'textile'), ) 28 except ImportError: 29 pass 30 31 _rendered_field_name = lambda name: '%s_rendered' % name 32 _markup_type_field_name = lambda name: '%s_markup_type' % name 33 34 class MarkupField(models.TextField): 35 def __init__(self, verbose_name=None, name=None, 36 default_markup_type=PLAIN_TEXT, sanitize=False, 37 extra_options=None, **kwargs): 38 self.default_markup_type = default_markup_type 39 self.extra_options = extra_options 40 self.sanitize = sanitize 41 super(MarkupField, self).__init__(verbose_name, name, **kwargs) 42 43 def contribute_to_class(self, cls, name): 44 # add markup_type field with creation_counter 1 greater than self 45 # so that admin by default shows these fields together 46 markup_type_field = models.PositiveIntegerField(choices=MARKUP_TYPES, 47 default=self.default_markup_type, 48 blank=self.blank) 49 markup_type_field.creation_counter = self.creation_counter+1 50 cls.add_to_class(_markup_type_field_name(name), markup_type_field) 51 rendered_field = models.TextField(editable=False) 52 cls.add_to_class(_rendered_field_name(name), rendered_field) 53 super(MarkupField, self).contribute_to_class(cls, name) 54 55 # define read-only property to easily access rendered string 56 def as_html(self): 57 return mark_safe(getattr(self, _rendered_field_name(name))) 58 cls.add_to_class('%s_as_html' % name, property(as_html)) 59 60 def pre_save(self, instance, add): 61 # update rendered value on save 62 markup = getattr(instance, self.attname) 63 markup_type = getattr(instance, _markup_type_field_name(self.attname)) 64 rendered = self.render_markup(markup, markup_type) 65 setattr(instance, _rendered_field_name(self.attname), rendered) 66 67 return markup 68 69 def render_markup(self, markup, markup_type): 70 """ 71 Renders ``markup`` string to HTML calling the renderer specified by 72 ``markup_type``. 73 """ 74 if markup_type == MARKDOWN: 75 # markdown.version implies support for extensions 76 if hasattr(markdown, 'version'): 77 return markdown.markdown(markup, self.extra_options, 78 safe_mode=self.sanitize) 79 return markdown.markdown(markup) 80 elif markup_type == REST: 81 # use extra_options as settings_overrides 82 parts = publish_parts(source=markup, writer_name="html4css1", 83 settings_overrides=self.extra_options) 84 return parts["fragment"] 85 elif markup_type == TEXTILE: 86 return textile.textile(markup, encoding='utf-8', output='utf-8', 87 sanitize=self.sanitize) 88 elif markup_type == PLAIN_TEXT: 89 return urlize(linebreaks(markup)) 90 else: 91 return markup -
docs/ref/contrib/index.txt
diff --git a/docs/ref/contrib/index.txt b/docs/ref/contrib/index.txt index 82a8955..16d0c32 100644
a b those packages have. 34 34 formtools/index 35 35 humanize 36 36 localflavor 37 markup 37 38 redirects 38 39 sitemaps 39 40 sites … … contains a ``USZipCodeField`` that you can use to validate U.S. zip codes. 126 127 127 128 See the :ref:`localflavor documentation <ref-contrib-localflavor>`. 128 129 129 .. _ref-contrib-markup:130 131 130 markup 132 131 ====== 133 132 134 A collection of template filters that implement common markup languages: 135 136 * ``textile`` -- implements `Textile`_ 137 * ``markdown`` -- implements `Markdown`_ 138 * ``restructuredtext`` -- implements `ReST (ReStructured Text)`_ 139 140 In each case, the filter expects formatted markup as a string and returns a 141 string representing the marked-up text. For example, the ``textile`` filter 142 converts text that is marked-up in Textile format to HTML. 143 144 To activate these filters, add ``'django.contrib.markup'`` to your 145 :setting:`INSTALLED_APPS` setting. Once you've done that, use ``{% load markup %}`` in 146 a template, and you'll have access to these filters. For more documentation, 147 read the source code in django/contrib/markup/templatetags/markup.py. 133 Utilities for using common markup languages. 148 134 149 .. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29 150 .. _Markdown: http://en.wikipedia.org/wiki/Markdown 151 .. _ReST (ReStructured Text): http://en.wikipedia.org/wiki/ReStructuredText 135 See the :ref:`markup documentation <ref-contrib-markup>`. 152 136 153 137 redirects 154 138 ========= -
new file docs/ref/contrib/markup.txt
diff --git a/docs/ref/contrib/markup.txt b/docs/ref/contrib/markup.txt new file mode 100644 index 0000000..c9d6119
- + 1 .. _ref-contrib-markup: 2 3 ====================== 4 django.contrib.markup 5 ====================== 6 7 .. module:: django.contrib.markup 8 :synopsis: Utilities for using common markup languages. 9 10 Two different methods of dealing with markup are offered: `Template Filters`_ 11 for rendering any block of text and a special :class:`MarkupField` that 12 provides a convenient way to store markup alongside it's type and 13 pre-rendered HTML in the database. 14 15 Template Filters 16 ---------------- 17 18 A collection of template filters that implement common markup languages: 19 20 * ``textile`` -- implements `Textile`_ 21 * ``markdown`` -- implements `Markdown`_ 22 * ``restructuredtext`` -- implements `ReST (ReStructured Text)`_ 23 24 In each case, the filter expects formatted markup as a string and returns a 25 string representing the marked-up text. For example, the ``textile`` filter 26 converts text that is marked-up in Textile format to HTML. 27 28 To activate these filters, add ``'django.contrib.markup'`` to your 29 :setting:`INSTALLED_APPS` setting. Once you've done that, use 30 ``{% load markup %}`` in a template, and you'll have access to these filters. 31 For more documentation, read the source code in 32 django/contrib/markup/templatetags/markup.py. 33 34 .. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29 35 .. _Markdown: http://en.wikipedia.org/wiki/Markdown 36 .. _ReST (ReStructured Text): http://en.wikipedia.org/wiki/ReStructuredText 37 38 39 ``MarkupField`` 40 --------------- 41 42 .. class:: MarkupField([default_markup_type=PLAIN_TEXT, **options]) 43 44 A :class:`TextField` that also adds an associated field for storing a markup 45 type and a read only accessor for getting the rendered HTML. Has a few optional 46 arguments: 47 48 .. attribute:: MarkupField.default_markup_type 49 50 Optional. Choice from ``MARKUP_TYPES`` to be used as the default value 51 for the associated markup_type field. 52 53 .. attribute: MarkupField.sanitize 54 55 Optional. Tell underlying renderer to strip HTML. (supported for 56 Markdown and Textile) 57 58 .. attribute: MarkupField.extra_options 59 60 Optional. Set of extra options to pass to renderer. This parameter is 61 passed to ``markdown.markdown`` as ``extensions`` and to 62 ``docutils.core.publish_parts`` as ``settings_overrides``. 63 64 This field has slightly more complicated internals than the typical field. 65 Behind the scenes it actually creates additional fields, for example:: 66 67 from django.contrib.markup.fields import MarkupField 68 69 class Post(models.Model): 70 body = MarkupField() 71 72 ...Instances of Post would have the additional attributes ``body_markup_type`` 73 and ``body_as_html``. ``body_markup_type`` is a :class:`PositiveIntegerField` 74 with choices defined in ``MARKUP_TYPES``. ``body_as_html`` is a read-only 75 property containing a pre-rendered HTML version of the content assigned to 76 ``body``. 77 78 .. versionadded:: 1.2 79 ``MarkupField`` was added in this version. 80 81 MARKUP_TYPES 82 ------------ 83 84 Choices for markup_type field: 85 86 ====================== ====================================================== 87 Type Description 88 ====================== ====================================================== 89 ``PLAIN_TEXT`` Applies urlize and linebreak filters. 90 91 ``HTML`` Applies no filters, ``field_as_html`` returns the body 92 verbatim. 93 94 ``MARKDOWN`` `Markdown`_ (only available if markdown library is 95 available) 96 97 ``REST`` `ReST (ReStructured Text)`_ (only available if 98 docutils is installed) 99 100 ``TEXTILE`` `Textile`_ (only available if textile library is 101 installed) 102 ====================== ======================================================