Wagtail Markdown Streamfield
A markdown streamfield for wagtail that includes a live preview.
- markdown
- wagtail
- streamfield
A markdown streamfield for wagtail that includes a live preview.
This function, meant to be used with the pre_save signal, will convert any markdown from a text field to it's corresponding html field.
This is a field that allows multiple markup types but also stores the pre-rendered result in the database which offers an advantage over calling one of the render methods each time. Example usage looks like: class BlogPost(models.Model): ... post = MarkupField() the various extra fields can then be accessed as follows: BlogPost.objects.get(pk=1).post # raw content BlogPost.objects.get(pk=1).post_markup_type # markup type (plain text, html, markdown, rest, textile) BlogPost.objects.get(pk=1).post_rendered # content of post rendered to html BlogPost.objects.get(pk=1).post_as_html # property that access post_rendered but marked safe for easy use in templates After writing my initial version of this I was pointed at the similar http://www.djangosnippets.org/snippets/1169/ I find mine a bit more useful as it includes ReST and includes a mark_safe call to allow showing the rendered HTML directly. I have however borrowed the nice idea of dynamically building MARKUP_TYPES from #1169. Also available via http://gist.github.com/67724.
### Simple wiki with MediaWiki and Markdown Support Once you install the mwlib you can use mwit to convert Mediawiki markup to HTML. I am include the model that uses it to hopefully provide a good example. I maintain a version and only one copy of each wiki entry in the main table and archive replaced markup into another table, you will need to create the archive model or remove that section of code. The line ending changes in mwit are so that it will work with IE.
Personally I hate using markdown for text input just so it can be converted into HTML. Markdown languages almost always don't support some thing I want to do; thus, why not just use HTML in the first place. Well because you don't want anybody posting any kind of HTML on your site. Solution, instead of making your users learn markdown, let them enter HTML and filter out bad tags. This is a filter I use to filter HTML for only certain allowed tags. The allowed tags can be configured with the **allowedhtml** list. To make your text input even more user friendly use a Javascript HTML editor like [FCK Editor](http://www.fckeditor.net/) so your users will have a nice GUI editor.
I updated [MarkdownTextField](http://www.djangosnippets.org/snippets/882/) to have some choices in markup. It currently support for Markdown, Textile, Plain Text, and Plain HTML. It will add `%s_html` for the complied HTML and `%s_markup_choices` for a drop down of markup choices. Usage: class MyModel(models.Model): description = MarkupTextField()
**updated 12/16/08** I run several blogs by visual-artists and web-designers who want a quick way to insert images into their blog without the awkwardness of WSYIWYG and without the technicality of code (eww...). Thanks in advance for your input. #Syntax in a blog goes: [[thumb:the-image-slug]] # Gives you a thumbnail [[image:the-image-slug]] # Presents full-size-image Then of course: {% blog.post|yeagowiki %} You will also need to create some templates (see snippet). Here's a sample: <!-- /templates/photologue/image_snippet.html --> <div class="photologue-image"> <a href="{% if url %}{{ url }}{% else %}/media/{{ image.image }}{% endif %}"> <img src="{{ image.get_display_url }}" /> </a> <p class="photologue-image-caption">{{ image.caption }}</p> </div>
A [common pattern in Django](http://code.djangoproject.com/wiki/UsingMarkup) is to create a TextField intended for Markdown text (i.e. description) and a companion non-editable TextField for storing the HTML version (i.e. description_html), so the Markdown converter need not be run for every page view. This snippet is a custom field which encapsulates this pattern in a single field which can automatically create and update its companion HTML field. Usage: class MyModel(models.Model): description = MarkdownTextField()
Based heavily on [snippet #119](/snippets/119/), this is an all-in-one function which applies Markdown and typogrify, and adds Pygments highlighting (selected from a class name or by having Pygments guess the language) to any `<code>` elements found in the text. It also adds some niceties for picking up useful arguments to Markdown and Pygments, and registers itself as a markup filter with the `template_utils` formatter. Requirements: * [BeautifulSoup](http://www.crummy.com/software/BeautifulSoup/) * [Pygments](http://pygments.org/) * [python-markdown](http://www.freewisdom.org/projects/python-markdown/) * [template_utils](http://code.google.com/p/django-template-utils/) * [typogrify](http://code.google.com/p/typogrify/)
This method lets you define your markup language and then processes your entries and puts the HTML output in another field on your database. I came from a content management system that worked like this and to me it makes sense. Your system doesn't have to process your entry every time it has to display it. You would just call the "*_html" field in your template. Requires: Django .96 [Markdown](http://cheeseshop.python.org/pypi/Markdown/1.6 "Python Package Index: Markdown") [Textile](http://cheeseshop.python.org/pypi/textile "Python Package Index: Textile")
A variation on a theme, inspired by [snippet 39][39] and [snippet 119][119]. The intent is to provide a more generic and simple mechanism for combining [Markdown][markdown] with [Pygments][pygments]. Common scenarios could include blogging or commenting. Snippet 119 seemed too specific and perhaps not as efficient, needing to process the HTML twice to accomplish it's ends. The one snag in the implementation is the need to use a tag other than `code` as a wrapper. See the comments for details. You will need the [BeautifulSoup][soup] module installed. Sample usage: from django.db import models class Blog(models.Model): '''Bare bones blogging model''' title = models.CharField(maxlength=255) slug = models.SlugField(maxlength=255, prepopulate_from=('title',)) pub_date = models.DateTimeField() # the cooked view, cached for quick retrieval blog = models.TextField() # the raw markdown-encoded text, saved for subsequent edits markdown = models.TextField() def save(self): from datetime import datetime if not self.id and not self.pub_date: self.pub_date = datetime.now() self.blog = pygmented_markdown(self.markdown) super(Blog, self).save() [39]: http://www.djangosnippets.org/snippets/39/ [119]: http://www.djangosnippets.org/snippets/119/ [soup]: http://www.crummy.com/software/BeautifulSoup/ [markdown]: http://www.freewisdom.org/projects/python-markdown/Installation [pygments]: http://pygments.org/
I wanted to keep the flexibility of generic_markup but add my own filtering option for apply_markup. So I created app/templatetags/mm_markup.py.
This is a [Django template tag](http://www.djangoproject.com/documentation/templates_python/#extending-the-template-system "Extending the template system") that renders an arbitrary block of text with Markdown and [Pygments](http://pygments.org "Syntax highlighter"). Use Markdown as usual, and when you have a code block to insert, put it inside `code` tags, with the language as the class: `<code class='python'>print "Hello, World"</code>` To use it in a template, first `{% load ... %}` the tag library, then `{{ content|render }}` your content. The tag takes one optional argument, to enable safe rendering in markdown. To use it, call `{{ content|render:"safe" }}`.
I'm a big fan of Markdown, and often set up models to automatically apply it to certain fields before saving. But that's not really flexible, because if I then distribute the code someone else might want to use reStructuredText or Textile or whatever, and then they have to hack my code. So here's a function which looks for a setting called `MARKUP_FILTER` and, based on what it finds there (see the docstring for what it looks at), chooses a text-to-HTML conversion function and applies it to a piece of text. Since Textile, Markdown and reStructuredText all support various useful options, it has the ability to pick up arbitrary keyword arguments and pass them through.
14 snippets posted so far.