docs, customizability of preview filter

This commit is contained in:
Carl Meyer 2009-03-18 12:40:42 -04:00
parent 5a10f812f9
commit 06dc0e53c5
33 changed files with 391 additions and 19 deletions

1
AUTHORS.txt Normal file
View File

@ -0,0 +1 @@
Carl Meyer <carl@dirtcircle.com>

4
CHANGELOG.txt Normal file
View File

@ -0,0 +1,4 @@
=========================
django-markitup changelog
=========================

12
INSTALL.txt Normal file
View File

@ -0,0 +1,12 @@
To install django-markitup, run the following command inside this
directory:
python setup.py install
You can also just copy the included ``markitup`` directory somewhere
on your Python path, or symlink to it from somewhere on your Python path;
this is useful if you're working from a Subversion checkout.
This application requires Python 2.3 or later, and Django 1.0 or later.
You can obtain Python from http://www.python.org/ and Django from
http://www.djangoproject.com/.

28
LICENSE.txt Normal file
View File

@ -0,0 +1,28 @@
Copyright (c) 2009, Carl Meyer
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the author nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

16
README.txt Normal file
View File

@ -0,0 +1,16 @@
===============
django-markitup
===============
This application provides convenient integration of the MarkItUp_
markup editor widget (by Jay Salvat) in Django projects, via a custom
form widget. It also provides server-side support for MarkItUp!'s
AJAX preview.
For installation instructions, see the file "INSTALL.txt" in this
directory; for instructions on how to use this application, and on
what it provides, see the file "overview.txt" in the "docs/"
directory.
.. _MarkItUp: http://markitup.jaysalvat.com/

143
docs/overview.txt Normal file
View File

@ -0,0 +1,143 @@
===============
django-markitup
===============
Easy integration of the MarkItUp_ markup editor widget in Django projects.
.. _MarkItUp: http://markitup.jaysalvat.com/
Installation
============
Get the Bazaar trunk version of the application::
bzr checkout lp:django-markitup django-markitup
To install django-markitup:
1. Put the ``markitup`` folder somewhere on your Python path.
2. Put ``'markitup'`` in your ``INSTALLED_APPS`` setting.
3. Make the contents of the "markitup/media" directory available
at ``MEDIA_URL/markitup``. This can be done by copying the
files, making a symlink, or through your webserver
configuration.
4. If you want to use AJAX-based preview:
- Add ``url(r'^markitup/', include('markitup.urls')`` in your
root URLconf.
- Set the MARKITUP_PREVIEW_FILTER setting (see `Using AJAX preview`_
below).
Using the MarkItUp! widget
==========================
The MarkItUp! widget lives at ``markitup.widgets.MarkItUpWidget``, and
can be used like any other Django custom widget.
To assign it to a form field::
from markitup.widgets import MarkItUpWidget
...
content = forms.TextField(widget=MarkItUpWidget())
When this form is displayed on your site, you must include the form
media somewhere on the page using ``{{ form.media }}``, or the
MarkItUpWidget will have no effect.
To use MarkItUpWidget in the Django admin:
from markitup.widgets import MarkItUpWidget
class MyModelAdmin(admin.ModelAdmin):
...
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'content':
kwargs['widget'] = MarkItUpWidget(attrs={'class': 'vLargeTextField'})
return super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)
Choosing a MarkItUp! button set and skin
========================================
MarkItUp! allows the toolbar button-set to be customized in a
Javascript settings file. By default, django-markitup uses the
"default" set (meant for HTML editing). Django-markitup also includes
basic "markdown" and "textile" sets (these are the sets available from
`the MarkItUp site <http://markitup.jaysalvat.com>`_, modified only to
add previewParserPath).
To use an alternate set, assign the ``MARKITUP_SET`` setting a URL
path (absolute or relative to MEDIA_URL) to the set directory. For
instance, to use the "markdown" set included with django-markitup::
MARKITUP_SET = 'markitup/sets/markdown'
MarkItUp! skins can be specified in a similar manner. Both "simple"
and "markitup" skins are included, by default "simple" is used. To
use the "markitup" skin instead::
MARKITUP_SKIN = 'markitup/skins/markitup'
Neither of these settings has to refer to a location inside
django-markitup's media. You can define your own sets and skins and
store them anywhere, as long as you set the MARKITUP_SET and
MARKITUP_SKIN settings to the appropriate URLs.
Set and skin may also be chosen on a per-widget basis by passing the
``markitup_set`` and ``markitup_skin`` keyword arguments to
MarkItUpWidget.
Using AJAX preview
==================
If you've included ``markitup.urls`` in your root URLconf (as
demonstrated above under `Installation`_), all you need to enable
server-side AJAX preview is the ``MARKITUP_PREVIEW_FILTER`` setting.
``MARKITUP_PREVIEW_FILTER`` must be a two-tuple.
The first element must be a string, the Python dotted path to a markup
filter function. This function should accept markup as its first
argument and return HTML. It may accept other keyword arguments as
well. You may parse your markup for preview using any method you
choose, as long as you can wrap it in a function that meets these
criteria.
The second element must be a dictionary of keyword arguments to pass
to the filter function. The dictionary may be empty.
For example, if you have python-markdown installed, you could use it
like this::
MARKITUP_PREVIEW_FILTER = ('markdown.markdown', {'safe_mode': True})
Alternatively, you could use the "textile" filter provided by Django
like this::
MARKITUP_PREVIEW_FILTER = ('django.contrib.markup.templatetags.markup.textile', {})
(The textile filter function doesn't accept keyword arguments, so the
kwargs dictionary must be empty in this case.)
**Note:** If you use your own custom MarkItUp! set, be sure to set the
``previewParserPath`` option to ``'/markitup/preview/'``.
Other settings
==============
MarkItUp! requires the jQuery Javascript library. By default,
django-markitup links to the most recent minor version of jQuery 1.3
available at ajax.googleapis.com (via the URL
``http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js``).
If you wish to use a different version of jQuery, or host it yourself,
set the JQUERY_URL setting. For example::
JQUERY_URL = 'jquery.min.js'
This will use the jQuery available at MEDIA_URL/jquery.min.js.

40
markitup/markup.py Normal file
View File

@ -0,0 +1,40 @@
"""
markup filters for django-markitup
Time-stamp: <2009-03-18 11:44:57 carljm markup.py>
This module provides a ``filter_func`` module-level markup filter
function based on the MARKITUP_PREVIEW_FILTER setting.
MARKITUP_PREVIEW_FILTER should be a two-tuple, where the first element
is a dotted-path string to a markup filter function, and the second
element is a dictionary of kwargs to be passed to the filter function
along with the markup to parse.
For instance, if MARKITUP_PREVIEW_FILTER is set to::
('markdown.markdown', {'safe_mode': True})
then calling ``filter_func(text)`` is equivalent to::
from markdown import markdown
markdown(text, safe_mode=True)
Though the implementation differs, the format of the
MARKITUP_PREVIEW_FILTER setting is inspired by James Bennett's
django-template-utils_.
.. _django-template-utils: http://code.google.com/p/django-template-utils/
"""
from django.utils.functional import curry, wraps
from markitup.settings import MARKITUP_PREVIEW_FILTER
if MARKITUP_PREVIEW_FILTER is None:
filter_func = lambda text: text
else:
filter_path, filter_kwargs = MARKITUP_PREVIEW_FILTER
module, funcname = filter_path.rsplit('.', 1)
func = getattr(__import__(module, {}, {}, [funcname]), funcname)
filter_func = wraps(func)(curry(func, **filter_kwargs))

View File

@ -11,7 +11,7 @@
// Feel free to add more tags
// -------------------------------------------------------------------
mySettings = {
previewParserPath: '',
previewParserPath: '/markitup/preview/',
onShiftEnter: {keepDefault:false, openWith:'\n\n'},
markupSet: [
{name:'First Level Heading', key:'1', placeHolder:'Your title here...', closeWith:function(markItUp) { return miu.markdownTitle(markItUp, '=') } },

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

View File

@ -0,0 +1,11 @@
Markup language:
Textile
Description:
A basic Textile markup set with Headings, Bold, Italic, Stroke through, Picture, Link, List, Quotes, Code, Preview button.
Install:
- Download the zip file
- Unzip it in your markItUp! sets folder
- Modify your JS link to point at this set.js
- Modify your CSS link to point at this style.css

View File

@ -0,0 +1,40 @@
// -------------------------------------------------------------------
// markItUp!
// -------------------------------------------------------------------
// Copyright (C) 2008 Jay Salvat
// http://markitup.jaysalvat.com/
// -------------------------------------------------------------------
// Textile tags example
// http://en.wikipedia.org/wiki/Textile_(markup_language)
// http://www.textism.com/
// -------------------------------------------------------------------
// Feel free to add more tags
// -------------------------------------------------------------------
mySettings = {
previewParserPath: '/markitup/preview/',
onShiftEnter: {keepDefault:false, replaceWith:'\n\n'},
markupSet: [
{name:'Heading 1', key:'1', openWith:'h1(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
{name:'Heading 2', key:'2', openWith:'h2(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
{name:'Heading 3', key:'3', openWith:'h3(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
{name:'Heading 4', key:'4', openWith:'h4(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
{name:'Heading 5', key:'5', openWith:'h5(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
{name:'Heading 6', key:'6', openWith:'h6(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
{name:'Paragraph', key:'P', openWith:'p(!(([![Class]!]))!). '},
{separator:'---------------' },
{name:'Bold', key:'B', closeWith:'*', openWith:'*'},
{name:'Italic', key:'I', closeWith:'_', openWith:'_'},
{name:'Stroke through', key:'S', closeWith:'-', openWith:'-'},
{separator:'---------------' },
{name:'Bulleted list', openWith:'(!(* |!|*)!)'},
{name:'Numeric list', openWith:'(!(# |!|#)!)'},
{separator:'---------------' },
{name:'Picture', replaceWith:'![![Source:!:http://]!]([![Alternative text]!])!'},
{name:'Link', openWith:'"', closeWith:'([![Title]!])":[![Link:!:http://]!]', placeHolder:'Your text to link here...' },
{separator:'---------------' },
{name:'Quotes', openWith:'bq(!(([![Class]!])!)). '},
{name:'Code', openWith:'@', closeWith:'@'},
{separator:'---------------' },
{name:'Preview', call:'preview', className:'preview'}
]
}

View File

@ -0,0 +1,60 @@
/* -------------------------------------------------------------------
// markItUp!
// By Jay Salvat - http://markitup.jaysalvat.com/
// ------------------------------------------------------------------*/
.markItUp .markItUpButton1 a {
background-image:url(images/h1.png);
}
.markItUp .markItUpButton2 a {
background-image:url(images/h2.png);
}
.markItUp .markItUpButton3 a {
background-image:url(images/h3.png);
}
.markItUp .markItUpButton4 a {
background-image:url(images/h4.png);
}
.markItUp .markItUpButton5 a {
background-image:url(images/h5.png);
}
.markItUp .markItUpButton6 a {
background-image:url(images/h6.png);
}
.markItUp .markItUpButton7 a {
background-image:url(images/paragraph.png);
}
.markItUp .markItUpButton8 a {
background-image:url(images/bold.png);
}
.markItUp .markItUpButton9 a {
background-image:url(images/italic.png);
}
.markItUp .markItUpButton10 a {
background-image:url(images/stroke.png);
}
.markItUp .markItUpButton11 a {
background-image:url(images/list-bullet.png);
}
.markItUp .markItUpButton12 a {
background-image:url(images/list-numeric.png);
}
.markItUp .markItUpButton13 a {
background-image:url(images/picture.png);
}
.markItUp .markItUpButton14 a {
background-image:url(images/link.png);
}
.markItUp .markItUpButton15 a {
background-image:url(images/quotes.png);
}
.markItUp .markItUpButton16 a {
background-image:url(images/code.png);
}
.markItUp .preview a {
background-image:url(images/preview.png);
}

14
markitup/settings.py Normal file
View File

@ -0,0 +1,14 @@
"""
settings for django-markitup
Time-stamp: <2009-03-18 11:54:09 carljm settings.py>
"""
from django.conf import settings
MARKITUP_PREVIEW_FILTER = getattr(settings, 'MARKITUP_PREVIEW_FILTER', None)
MARKITUP_SET = getattr(settings, 'MARKITUP_SET', 'markitup/sets/default')
MARKITUP_SKIN = getattr(settings, 'MARKITUP_SKIN', 'markitup/skins/simple')
JQUERY_URL = getattr(
settings, 'JQUERY_URL',
'http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js')

View File

@ -1,8 +1,8 @@
from django.conf.urls.defaults import *
from markitup.views import apply_markdown
from markitup.views import apply_filter
urlpatterns = patterns(
'',
url(r'markdown/$', apply_markdown, name='markitup_markdown')
url(r'preview/$', apply_filter, name='markitup_preview')
)

View File

@ -1,15 +1,16 @@
"""
views for django-markitup
Time-stamp: <2009-03-09 13:42:35 carljm views.py>
Time-stamp: <2009-03-18 11:24:32 carljm views.py>
"""
from markdown import markdown
from django.template.context import RequestContext
from django.shortcuts import render_to_response
def apply_markdown(request):
markup = markdown(request.POST.get('data', ''))
from markitup.markup import filter_func
def apply_filter(request):
markup = filter_func(request.POST.get('data', ''))
return render_to_response( 'markitup/preview.html',
{'preview':markup},
context_instance=RequestContext(request))

View File

@ -1,38 +1,40 @@
"""
widgets for django-markitup
Time-stamp: <2009-03-09 13:23:33 carljm widgets.py>
Time-stamp: <2009-03-18 11:50:47 carljm widgets.py>
"""
from django import forms
from django.utils.safestring import mark_safe
from markitup.settings import MARKITUP_SET, MARKITUP_SKIN, JQUERY_URL
class MarkItUpWidget(forms.Textarea):
"""
Widget for a MarkItUp editor textarea.
Takes two additional optional keyword arguments:
``miu_set``
``markitup_set``
URL path (absolute or relative to MEDIA_URL) to MarkItUp
button set directory. Default: ``markitup/sets/default``.
button set directory. Default: value of MARKITUP_SET setting.
``miu_skin``
``markitup_skin``
URL path (absolute or relative to MEDIA_URL) to MarkItUp skin
directory. Default: ``markitup/skins/simple``.
directory. Default: value of MARKITUP_SKIN setting.
"""
def __init__(self, attrs=None,
miu_set='markitup/sets/default',
miu_skin='markitup/skins/simple'):
self.miu_set = miu_set
self.miu_skin = miu_skin
markitup_set=None,
markitup_skin=None):
self.miu_set = markitup_set or MARKITUP_SET
self.miu_skin = markitup_skin or MARKITUP_SKIN
super(MarkItUpWidget, self).__init__(attrs)
def _media(self):
return forms.Media(css={'screen': ('%s/style.css' % self.miu_skin,
'%s/style.css' % self.miu_set)},
js=('http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js',
js=(JQUERY_URL,
'markitup/jquery.markitup.js',
'%s/set.js' % self.miu_set))
media = property(_media)

View File

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name='django-markitup',
version='0.1.0',
version='0.2.0',
description='Django integration with the MarkItUp universal markup editor',
author='Carl Meyer',
author_email='carl@dirtcircle.com',