django-tinymce-1.5/ 0000755 0001750 0001750 00000000000 11145270203 013340 5 ustar joost joost django-tinymce-1.5/tinymce/ 0000755 0001750 0001750 00000000000 11145270203 015010 5 ustar joost joost django-tinymce-1.5/tinymce/widgets.py 0000644 0001750 0001750 00000011160 11145270127 017034 0 ustar joost joost # Copyright (c) 2008 Joost Cassee
# Licensed under the terms of the MIT License (see LICENSE.txt)
"""
This TinyMCE widget was copied and extended from this code by John D'Agostino:
http://code.djangoproject.com/wiki/CustomWidgetsTinyMCE
"""
from django import forms
from django.conf import settings
from django.contrib.admin import widgets as admin_widgets
from django.core.urlresolvers import reverse
from django.forms.widgets import flatatt
from django.forms.util import smart_unicode
from django.utils.html import escape
from django.utils import simplejson
from django.utils.datastructures import SortedDict
from django.utils.safestring import mark_safe
from django.utils.translation import get_language, ugettext as _
import tinymce.settings
class TinyMCE(forms.Textarea):
"""
TinyMCE widget. Set settings.TINYMCE_JS_URL to set the location of the
javascript file. Default is "MEDIA_URL + 'js/tiny_mce/tiny_mce.js'".
You can customize the configuration with the mce_attrs argument to the
constructor.
In addition to the standard configuration you can set the
'content_language' parameter. It takes the value of the 'language'
parameter by default.
In addition to the default settings from settings.TINYMCE_DEFAULT_CONFIG,
this widget sets the 'language', 'directionality' and
'spellchecker_languages' parameters by default. The first is derived from
the current Django language, the others from the 'content_language'
parameter.
"""
def __init__(self, content_language=None, attrs=None, mce_attrs={}):
super(TinyMCE, self).__init__(attrs)
self.mce_attrs = mce_attrs
if content_language is None:
content_language = mce_attrs.get('language', None)
self.content_language = content_language
def render(self, name, value, attrs=None):
if value is None: value = ''
value = smart_unicode(value)
final_attrs = self.build_attrs(attrs)
final_attrs['name'] = name
assert 'id' in final_attrs, "TinyMCE widget attributes must contain 'id'"
mce_config = tinymce.settings.DEFAULT_CONFIG.copy()
mce_config.update(get_language_config(self.content_language))
if tinymce.settings.USE_FILEBROWSER:
mce_config['file_browser_callback'] = "djangoFileBrowser"
mce_config.update(self.mce_attrs)
mce_config['mode'] = 'exact'
mce_config['elements'] = final_attrs['id']
mce_config['strict_loading_mode'] = 1
mce_json = simplejson.dumps(mce_config)
html = [u'' % (flatatt(final_attrs), escape(value))]
if tinymce.settings.USE_COMPRESSOR:
compressor_config = {
'plugins': mce_config.get('plugins', ''),
'themes': mce_config.get('theme', 'advanced'),
'languages': mce_config.get('language', ''),
'diskcache': True,
'debug': False,
}
compressor_json = simplejson.dumps(compressor_config)
html.append(u'' % compressor_json)
html.append(u'' % mce_json)
return mark_safe(u'\n'.join(html))
def _media(self):
if tinymce.settings.USE_COMPRESSOR:
js = [reverse('tinymce-compressor')]
else:
js = [tinymce.settings.JS_URL]
if tinymce.settings.USE_FILEBROWSER:
js.append(reverse('tinymce-filebrowser'))
return forms.Media(js=js)
media = property(_media)
class AdminTinyMCE(admin_widgets.AdminTextareaWidget, TinyMCE):
pass
def get_language_config(content_language=None):
language = get_language()[:2]
if content_language:
content_language = content_language[:2]
else:
content_language = language
config = {}
config['language'] = language
lang_names = SortedDict()
for lang, name in settings.LANGUAGES:
if lang[:2] not in lang_names: lang_names[lang[:2]] = []
lang_names[lang[:2]].append(_(name))
sp_langs = []
for lang, names in lang_names.items():
if lang == content_language:
default = '+'
else:
default = ''
sp_langs.append(u'%s%s=%s' % (default, ' / '.join(names), lang))
config['spellchecker_languages'] = ','.join(sp_langs)
if content_language in settings.LANGUAGES_BIDI:
config['directionality'] = 'rtl'
else:
config['directionality'] = 'ltr'
if tinymce.settings.USE_SPELLCHECKER:
config['spellchecker_rpc_url'] = reverse('tinymce.views.spell_check')
return config
django-tinymce-1.5/tinymce/templates/ 0000755 0001750 0001750 00000000000 11145270203 017006 5 ustar joost joost django-tinymce-1.5/tinymce/templates/tinymce/ 0000755 0001750 0001750 00000000000 11145270203 020456 5 ustar joost joost django-tinymce-1.5/tinymce/templates/tinymce/tiny_mce_gzip.js 0000644 0001750 0001750 00000006343 11145270127 023667 0 ustar joost joost /**
* Based on "TinyMCE Compressor PHP" from MoxieCode.
*
* http://tinymce.moxiecode.com/
*
* Copyright (c) 2008 Jason Davies
* Licensed under the terms of the MIT License (see LICENSE.txt)
*
* Usage: copy this file into the same directory as tiny_mce.js and change
* settings.page_name below to match your tinymce installation as appropriate.
*/
var tinyMCE_GZ = {
settings : {
themes : '',
plugins : '',
languages : '',
disk_cache : true,
page_name : '{% url tinymce-compressor %}',
debug : false,
suffix : ''
},
init : function(s, cb, sc) {
var t = this, n, i;//, nl = document.getElementsByTagName('script');
for (n in s)
t.settings[n] = s[n];
s = t.settings;
t.baseURL = '{{ base_url }}';
if (!t.coreLoaded)
t.loadScripts(1, s.themes, s.plugins, s.languages, cb, sc);
},
loadScripts : function(co, th, pl, la, cb, sc) {
var t = this, x, w = window, q, c = 0, ti, s = t.settings;
function get(s) {
x = 0;
try {
x = new ActiveXObject(s);
} catch (s) {
}
return x;
};
// Build query string
q = 'js=true&diskcache=' + (s.disk_cache ? 'true' : 'false') + '&core=' + (co ? 'true' : 'false') + '&suffix=' + escape(s.suffix) + '&themes=' + escape(th) + '&plugins=' + escape(pl) + '&languages=' + escape(la);
if (co)
t.coreLoaded = 1;
// Send request
x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Msxml2.XMLHTTP') || get('Microsoft.XMLHTTP');
x.overrideMimeType && x.overrideMimeType('text/javascript');
x.open('GET', s.page_name + '?' + q, !!cb);
// x.setRequestHeader('Content-Type', 'text/javascript');
x.send('');
// Handle asyncronous loading
if (cb) {
// Wait for response
ti = w.setInterval(function() {
if (x.readyState == 4 || c++ > 10000) {
w.clearInterval(ti);
if (c < 10000 && x.status == 200) {
t.loaded = 1;
t.eval(x.responseText);
tinymce.dom.Event.domLoaded = true;
cb.call(sc || t, x);
}
ti = x = null;
}
}, 10);
} else
t.eval(x.responseText);
},
start : function() {
var t = this, each = tinymce.each, s = t.settings, ln = s.languages.split(',');
tinymce.suffix = s.suffix;
function load(u) {
tinymce.ScriptLoader.markDone(tinyMCE.baseURI.toAbsolute(u));
};
// Add core languages
each(ln, function(c) {
if (c)
load('langs/' + c + '.js');
});
// Add themes with languages
each(s.themes.split(','), function(n) {
if (n) {
load('themes/' + n + '/editor_template' + s.suffix + '.js');
each (ln, function(c) {
if (c)
load('themes/' + n + '/langs/' + c + '.js');
});
}
});
// Add plugins with languages
each(s.plugins.split(','), function(n) {
if (n) {
load('plugins/' + n + '/editor_plugin' + s.suffix + '.js');
each(ln, function(c) {
if (c)
load('plugins/' + n + '/langs/' + c + '.js');
});
}
});
},
end : function() {
},
eval : function(co) {
var w = window;
// Evaluate script
if (!w.execScript) {
if (/Gecko/.test(navigator.userAgent))
eval(co, w); // Firefox 3.0
else
eval.call(w, co);
} else
w.execScript(co); // IE
}
};
django-tinymce-1.5/tinymce/templates/tinymce/preview_javascript.html 0000644 0001750 0001750 00000000673 11145270127 025266 0 ustar joost joost
django-tinymce-1.5/tinymce/templates/tinymce/filebrowser.js 0000644 0001750 0001750 00000001041 11145270127 023340 0 ustar joost joost function djangoFileBrowser(field_name, url, type, win) {
var url = "{{ fb_url }}?pop=2&type=" + type;
tinyMCE.activeEditor.windowManager.open(
{
'file': url,
'width': 820,
'height': 500,
'resizable': "yes",
'scrollbars': "yes",
'inline': "no",
'close_previous': "no"
},
{
'window': win,
'input': field_name,
'editor_id': tinyMCE.selectedInstance.editorId
}
);
return false;
}
django-tinymce-1.5/tinymce/settings.py 0000644 0001750 0001750 00000001216 11145270127 017227 0 ustar joost joost import os
from django.conf import settings
DEFAULT_CONFIG = getattr(settings, 'TINYMCE_DEFAULT_CONFIG',
{'theme': "simple", 'relative_urls': False})
USE_SPELLCHECKER = getattr(settings, 'TINYMCE_SPELLCHECKER', False)
USE_COMPRESSOR = getattr(settings, 'TINYMCE_COMPRESSOR', False)
USE_FILEBROWSER = getattr(settings, 'TINYMCE_FILEBROWSER',
'filebrowser' in settings.INSTALLED_APPS)
JS_URL = getattr(settings, 'TINYMCE_JS_URL',
'%sjs/tiny_mce/tiny_mce.js' % settings.MEDIA_URL)
JS_ROOT = getattr(settings, 'TINYMCE_JS_ROOT',
os.path.join(settings.MEDIA_ROOT, 'js/tiny_mce'))
JS_BASE_URL = JS_URL[:JS_URL.rfind('/')]
django-tinymce-1.5/tinymce/views.py 0000644 0001750 0001750 00000010544 11145270127 016530 0 ustar joost joost # Copyright (c) 2008 Joost Cassee
# Licensed under the terms of the MIT License (see LICENSE.txt)
import logging
from django.core import urlresolvers
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext, loader
from django.utils import simplejson
from django.utils.translation import ugettext as _
from tinymce.compressor import gzip_compressor
from tinymce.widgets import get_language_config
def textareas_js(request, name, lang=None):
"""
Returns a HttpResponse whose content is a Javscript file. The template
is loaded from 'tinymce/_textareas.js' or
'/tinymce_textareas.js'. Optionally, the lang argument sets the
content language.
"""
template_files = (
'tinymce/%s_textareas.js' % name,
'%s/tinymce_textareas.js' % name,
)
template = loader.select_template(template_files)
vars = get_language_config(lang)
vars['content_language'] = lang
context = RequestContext(request, vars)
return HttpResponse(template.render(context),
content_type="application/x-javascript")
def spell_check(request):
"""
Returns a HttpResponse that implements the TinyMCE spellchecker protocol.
"""
try:
import enchant
raw = request.raw_post_data
input = simplejson.loads(raw)
id = input['id']
method = input['method']
params = input['params']
lang = params[0]
arg = params[1]
if not enchant.dict_exists(str(lang)):
raise RuntimeError("dictionary not found for language '%s'" % lang)
checker = enchant.Dict(lang)
if method == 'checkWords':
result = [word for word in arg if not checker.check(word)]
elif method == 'getSuggestions':
result = checker.suggest(arg)
else:
raise RuntimeError("Unkown spellcheck method: '%s'" % method)
output = {
'id': id,
'result': result,
'error': None,
}
except Exception:
logging.exception("Error running spellchecker")
return HttpResponse(_("Error running spellchecker"))
return HttpResponse(simplejson.dumps(output),
content_type='application/json')
def preview(request, name):
"""
Returns a HttpResponse whose content is an HTML file that is used
by the TinyMCE preview plugin. The template is loaded from
'tinymce/_preview.html' or '/tinymce_preview.html'.
"""
template_files = (
'tinymce/%s_preview.html' % name,
'%s/tinymce_preview.html' % name,
)
template = loader.select_template(template_files)
return HttpResponse(template.render(RequestContext(request)),
content_type="text/html")
def flatpages_link_list(request):
"""
Returns a HttpResponse whose content is a Javscript file representing a
list of links to flatpages.
"""
from django.contrib.flatpages.models import FlatPage
link_list = [(page.title, page.url) for page in FlatPage.objects.all()]
return render_to_link_list(link_list)
def compressor(request):
"""
Returns a GZip-compressed response.
"""
return gzip_compressor(request)
def render_to_link_list(link_list):
"""
Returns a HttpResponse whose content is a Javscript file representing a
list of links suitable for use wit the TinyMCE external_link_list_url
configuration option. The link_list parameter must be a list of 2-tuples.
"""
return render_to_js_vardef('tinyMCELinkList', link_list)
def render_to_image_list(image_list):
"""
Returns a HttpResponse whose content is a Javscript file representing a
list of images suitable for use wit the TinyMCE external_image_list_url
configuration option. The image_list parameter must be a list of 2-tuples.
"""
return render_to_js_vardef('tinyMCEImageList', image_list)
def render_to_js_vardef(var_name, var_value):
output = "var %s = %s" % (var_name, simplejson.dumps(var_value))
return HttpResponse(output, content_type='application/x-javascript')
def filebrowser(request):
fb_url = "%s://%s%s" % (request.is_secure() and 'https' or 'http',
request.get_host(), urlresolvers.reverse('filebrowser-index'))
return render_to_response('tinymce/filebrowser.js', {'fb_url': fb_url},
context_instance=RequestContext(request))
django-tinymce-1.5/tinymce/models.py 0000644 0001750 0001750 00000001343 11145270127 016653 0 ustar joost joost # Copyright (c) 2008 Joost Cassee
# Licensed under the terms of the MIT License (see LICENSE.txt)
from django.db import models
from django.contrib.admin import widgets as admin_widgets
from tinymce import widgets as tinymce_widgets
class HTMLField(models.TextField):
"""
A large string field for HTML content. It uses the TinyMCE widget in
forms.
"""
def formfield(self, **kwargs):
defaults = {'widget': tinymce_widgets.TinyMCE}
defaults.update(kwargs)
# As an ugly hack, we override the admin widget
if defaults['widget'] == admin_widgets.AdminTextareaWidget:
defaults['widget'] = tinymce_widgets.AdminTinyMCE
return super(HTMLField, self).formfield(**defaults)
django-tinymce-1.5/tinymce/templatetags/ 0000755 0001750 0001750 00000000000 11145270203 017502 5 ustar joost joost django-tinymce-1.5/tinymce/templatetags/tinymce_tags.py 0000644 0001750 0001750 00000000700 11145270127 022544 0 ustar joost joost # Copyright (c) 2009 Joost Cassee
# Licensed under the terms of the MIT License (see LICENSE.txt)
from django import template
from django.template.loader import render_to_string
import tinymce.settings
register = template.Library()
def tinymce_preview(element_id):
return render_to_string('tinymce/preview_javascript.html',
{'base_url': tinymce.settings.JS_BASE_URL, 'element_id': element_id})
register.simple_tag(tinymce_preview)
django-tinymce-1.5/tinymce/templatetags/__init__.py 0000644 0001750 0001750 00000000142 11145270127 021615 0 ustar joost joost # Copyright (c) 2008 Joost Cassee
# Licensed under the terms of the MIT License (see LICENSE.txt)
django-tinymce-1.5/tinymce/urls.py 0000644 0001750 0001750 00000001233 11145270127 016353 0 ustar joost joost # Copyright (c) 2008 Joost Cassee
# Licensed under the terms of the MIT License (see LICENSE.txt)
from django.conf.urls.defaults import *
urlpatterns = patterns('tinymce.views',
url(r'^js/textareas/(?P.+)/$', 'textareas_js', name='tinymce-js'),
url(r'^js/textareas/(?P.+)/(?P.*)$', 'textareas_js', name='tinymce-js-lang'),
url(r'^spellchecker/$', 'spell_check'),
url(r'^flatpages_link_list/$', 'flatpages_link_list'),
url(r'^compressor/$', 'compressor', name='tinymce-compressor'),
url(r'^filebrowser/$', 'filebrowser', name='tinymce-filebrowser'),
url(r'^preview/(?P.+)/$', 'preview', name='tinymce-preview'),
)
django-tinymce-1.5/tinymce/__init__.py 0000644 0001750 0001750 00000000142 11145270127 017123 0 ustar joost joost # Copyright (c) 2008 Joost Cassee
# Licensed under the terms of the MIT License (see LICENSE.txt)
django-tinymce-1.5/tinymce/compressor.py 0000644 0001750 0001750 00000010510 11145270127 017560 0 ustar joost joost """
Based on "TinyMCE Compressor PHP" from MoxieCode.
http://tinymce.moxiecode.com/
Copyright (c) 2008 Jason Davies
Licensed under the terms of the MIT License (see LICENSE.txt)
"""
from datetime import datetime
import os
from django.conf import settings
from django.core.cache import cache
from django.http import HttpResponse
from django.shortcuts import Http404
from django.template import RequestContext
from django.template.loader import render_to_string
from django.utils.text import compress_string
from django.utils.cache import patch_vary_headers, patch_response_headers
import tinymce.settings
def get_file_contents(filename):
try:
f = open(os.path.join(tinymce.settings.JS_ROOT, filename))
try:
return f.read()
finally:
f.close()
except IOError:
return ""
def split_commas(str):
if str == '':
return []
return str.split(",")
def gzip_compressor(request):
plugins = split_commas(request.GET.get("plugins", ""))
languages = split_commas(request.GET.get("languages", ""))
themes = split_commas(request.GET.get("themes", ""))
isJS = request.GET.get("js", "") == "true"
compress = request.GET.get("compress", "true") == "true"
suffix = request.GET.get("suffix", "") == "_src" and "_src" or ""
content = []
response = HttpResponse()
response["Content-Type"] = "text/javascript"
if not isJS:
response.write(render_to_string('tinymce/tiny_mce_gzip.js', {
'base_url': tinymce.settings.JS_BASE_URL,
}, context_instance=RequestContext(request)))
return response
patch_vary_headers(response, ['Accept-Encoding'])
now = datetime.utcnow()
response['Date'] = now.strftime('%a, %d %b %Y %H:%M:%S GMT')
cacheKey = '|'.join(plugins + languages + themes)
cacheData = cache.get(cacheKey)
if not cacheData is None:
if cacheData.has_key('ETag'):
if_none_match = request.META.get('HTTP_IF_NONE_MATCH', None)
if if_none_match == cacheData['ETag']:
response.status_code = 304
response.content = ''
response['Content-Length'] = '0'
return response
if cacheData.has_key('Last-Modified'):
if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None)
if if_modified_since == cacheData['Last-Modified']:
response.status_code = 304
response.content = ''
response['Content-Length'] = '0'
return response
# Add core, with baseURL added
content.append(get_file_contents("tiny_mce%s.js" % suffix).replace(
"tinymce._init();", "tinymce.baseURL='%s';tinymce._init();"
% tinymce.settings.JS_BASE_URL))
# Patch loading functions
content.append("tinyMCE_GZ.start();")
# Add core languages
for lang in languages:
content.append(get_file_contents("langs/%s.js" % lang))
# Add themes
for theme in themes:
content.append(get_file_contents("themes/%s/editor_template%s.js"
% (theme, suffix)))
for lang in languages:
content.append(get_file_contents("themes/%s/langs/%s.js"
% (theme, lang)))
# Add plugins
for plugin in plugins:
content.append(get_file_contents("plugins/%s/editor_plugin%s.js"
% (plugin, suffix)))
for lang in languages:
content.append(get_file_contents("plugins/%s/langs/%s.js"
% (plugin, lang)))
# Add filebrowser
if tinymce.settings.USE_FILEBROWSER:
content.append(render_to_string('tinymce/filebrowser.js', {},
context_instance=RequestContext(request)).encode("utf-8"))
# Restore loading functions
content.append("tinyMCE_GZ.end();")
# Compress
if compress:
content = compress_string(''.join(content))
response['Content-Encoding'] = 'gzip'
response['Content-Length'] = str(len(content))
response.write(content)
timeout = 3600 * 24 * 10
patch_response_headers(response, timeout)
cache.set(cacheKey, {
'Last-Modified': response['Last-Modified'],
'ETag': response['ETag'],
})
return response
django-tinymce-1.5/PKG-INFO 0000644 0001750 0001750 00000002413 11145270203 014435 0 ustar joost joost Metadata-Version: 1.0
Name: django-tinymce
Version: 1.5
Summary: A Django application that contains a widget to render a form field as a TinyMCE editor.
Home-page: http://code.google.com/p/django-tinymce/
Author: Joost Cassee
Author-email: joost@cassee.net
License: MIT License
Download-URL: http://code.google.com/p/django-tinymce/downloads/list
Description:
Use the TinyMCE editor for your form textareas.
Features:
* Use as a form widget or with a view.
* Enhanced support for content languages.
* Integration with the TinyMCE spellchecker.
* Enables predefined link and image lists for dialogs.
* Can compress the TinyMCE javascript files.
* Integration with django-filebrowser.
Keywords: django widget tinymce
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: Libraries :: Python Modules
django-tinymce-1.5/setup.py 0000755 0001750 0001750 00000003100 11145270131 015047 0 ustar joost joost #!/usr/bin/env python
from distutils.core import setup
import metadata
app_name = metadata.name
version = metadata.version
setup(
name = "django-%s" % app_name,
version = version,
packages = [app_name, '%s.templatetags' % app_name],
package_data = {app_name: ['templates/tinymce/*']},
author = "Joost Cassee",
author_email = "joost@cassee.net",
description = "A Django application that contains a widget to render a" \
" form field as a TinyMCE editor.",
long_description = \
"""
Use the TinyMCE editor for your form textareas.
Features:
* Use as a form widget or with a view.
* Enhanced support for content languages.
* Integration with the TinyMCE spellchecker.
* Enables predefined link and image lists for dialogs.
* Can compress the TinyMCE javascript files.
* Integration with django-filebrowser.
""",
license = "MIT License",
keywords = "django widget tinymce",
classifiers = [
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Software Development :: Libraries :: Application Frameworks',
'Topic :: Software Development :: Libraries :: Python Modules',
],
platforms = ['any'],
url = "http://code.google.com/p/django-%s/" % app_name,
download_url = "http://code.google.com/p/django-%s/downloads/list" \
% app_name,
)
django-tinymce-1.5/metadata.py 0000644 0001750 0001750 00000000114 11145270141 015467 0 ustar joost joost name = 'tinymce'
authors = 'Joost Cassee'
version = '1.5'
release = version
django-tinymce-1.5/docs/ 0000755 0001750 0001750 00000000000 11145270203 014270 5 ustar joost joost django-tinymce-1.5/docs/usage.rst 0000644 0001750 0001750 00000021600 11145270131 016125 0 ustar joost joost =====
Usage
=====
The application can enable TinyMCE for one form field using the ``widget``
keyword argument of ``Field`` constructors or for all textareas on a page using
a view.
.. _widget:
Using the widget
----------------
If you use the widget (recommended) you need to add some python code and
possibly modify your template.
Python code
^^^^^^^^^^^
The TinyMCE widget can be enabled by setting it as the widget for a formfield.
For example, to use a nice big TinyMCE widget for the content field of a
flatpage form you could use the following code::
from django import forms
from django.contrib.flatpages.models import FlatPage
from tinymce.widgets import TinyMCE
class FlatPageForm(ModelForm):
...
content = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
...
class Meta:
model = FlatPage
The widget accepts the following keyword arguments:
``mce_attrs`` (default: ``{}``)
Extra TinyMCE configuration options. Options from
``settings.TINYMCE_DEFAULT_CONFIG`` (see :ref:`configuration`) are applied
first and can be overridden.
Python types are automatically converted to Javascript types, using standard
JSON encoding. For example, to disable word wrapping you would include
``'nowrap': True``.
``content_language`` (default: ``django.utils.translation.get_language_code()``)
The language of the widget content. Will be used to set the ``language``,
``directionality`` and ``spellchecker_languages`` configuration options of
the TinyMCE editor. It may be different from the interface language (changed
using ``language`` in ``mce_attrs``) which defaults to the current Django
language.
Templates
^^^^^^^^^
The widget requires a link to the TinyMCE javascript code. The
``django.contrib.admin`` templates do this for you automatically, so if you are
just using tinymce in admin forms then you are done. In your own templates
containing a TinyMCE widget you must add the following to the HTML ``HEAD``
section (assuming you named your form 'form')::
...
{{ form.media }}
See also `the section of form media`_ in the Django documentation.
.. _`the section of form media`: http://www.djangoproject.com/documentation/forms/#media-on-forms
The ``HTMLField`` model field type
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For lazy developers the tinymce application also contains a model field type
for storing HTML. It uses the TinyMCE widget to render its form field. In this
example, the admin will render the ``my_field`` field using the TinyMCE
widget::
from django.db import models
from tinymce import models as tinymce_models
class MyModel(models.Model):
my_field = tinymce_models.HTMLField()
In all other regards, ``HTMLField`` behaves just like the standard Django
``TextField`` field type.
Using the view
--------------
If you cannot or will not change the widget on a form you can also use the
``tinymce-js`` named view to convert some or all textfields on a page to
TinyMCE editors. On the template of the page, add the following lines to the
``HEAD`` element::
The ``NAME`` argument allows you to create multiple TinyMCE configurations. Now
create a template containing the Javascript initialization code. It should be
placed in the template path as ``NAME/tinymce_textareas.js`` or
``tinymce/NAME_textareas.js``.
Example::
tinyMCE.init({
mode: "textareas",
theme: "advanced",
plugins: "spellchecker,directionality,paste,searchreplace",
language: "{{ language }}",
directionality: "{{ directionality }}",
spellchecker_languages : "{{ spellchecker_languages }}",
spellchecker_rpc_url : "{{ spellchecker_rpc_url }}"
});
This example also shows the variables you can use in the template. The language
variables are based on the current Django language. If the content language is
different from the interface language use the ``tinymce-js-lang`` view which
takes a language (``LANG_CODE``) argument::
External link and image lists
-----------------------------
The TinyMCE link and image dialogs can be enhanced with a predefined list of
links_ and images_. These entries are filled using a variable loaded from an
external Javascript location. The tinymce application can serve these lists for
you.
.. _links: http://wiki.moxiecode.com/index.php/TinyMCE:Configuration/external_link_list_url
.. _images: http://wiki.moxiecode.com/index.php/TinyMCE:Configuration/external_image_list_url
Creating external link and image views
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To use a predefined link list, add the ``external_link_list_url`` option to the
``mce_attrs`` keyword argument to the widget (or the template if you use the
view). The value is a URL that points to a view that fills a list of 2-tuples
(*name*, *URL*) and calls ``tinymce.views.render_to_link_list``. For example:
Create the widget::
from django import forms
from django.db import models
from django.core.urlresolvers import reverse
from tinymce.widgets import TinyMCE
class SomeModel(models.Model):
somefield = forms.CharField(widget=TinyMCE(mce_attrs={'external_link_list_url': reverse('someapp.views.someview')})
Create the view::
from tinymce.views import render_to_link_list
def someview(request):
objects = ...
link_list = [(unicode(obj), obj.get_absolute_url()) for obj in objects]
return render_to_link_list(link_list)
Finally, include the view in your URLconf.
Image lists work exactly the same way, just use the TinyMCE
``external_image_list_url`` configuration option and call
``tinymce.views.render_to_image_list`` from your view.
The ``flatpages_link_list`` view
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
As an example, the tinymce application contains a predefined view that lists
all ``django.contrib.flatpages`` objects:
``tinymce.views.flatpages_link_list``. If you want to use a TinyMCE widget for
the flatpages ``content`` field with a predefined list of other flatpages in
the link dialog you could use something like this::
from django import forms
from django.core.urlresolvers import reverse
from django.contrib.flatpages.admin import FlatPageAdmin
from django.contrib.flatpages.models import FlatPage
from tinymce.widgets import TinyMCE
class TinyMCEFlatPageAdmin(FlatPageAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'content':
return forms.CharField(widget=TinyMCE(
attrs={'cols': 80, 'rows': 30},
mce_attrs={'external_link_list_url': reverse('tinymce.views.flatpages_link_list')},
))
return super(TinyMCEFlatPageAdmin, self).formfield_for_dbfield(db_field, **kwargs)
somesite.register(FlatPage, TinyMCEFlatPageAdmin)
If you want to enable this for the default admin site
(``django.contrib.admin.site``) you will need to unregister the original
ModelAdmin class for flatpages first::
from django.contrib import admin
admin.site.unregister(FlatPage)
admin.site.register(FlatPage, TinyMCEFlatPageAdmin)
The source contains a `test project`_ that includes this flatpages model admin.
You just need to add the TinyMCE javascript code.
#. Checkout the test project: ``svn checkout http://django-tinymce.googlecode.com/svn/trunk/testtinymce``
#. Copy the ``tiny_mce`` directory from the TinyMCE distribution into ``media/js``
#. Run ``python manage.py syncdb``
#. Run ``python manage.py runserver``
#. Connect to `http://localhost:8000/admin/`_
.. _`test project`: http://code.google.com/p/django-tinymce/source/browse/trunk/testproject/
.. _`http://localhost:8000/admin/`: http://localhost:8000/admin/
The TinyMCE preview button
--------------------------
TinyMCE contains a `preview plugin`_ that can be used to allow the user to view
the contents of the editor in the website context. The tinymce application
provides a view and a template tag to make supporting this plugin easier. To
use it point the ``plugin_preview_pageurl`` configuration to the view named
``tinymce-preview``::
from django.core.urlresolvers import reverse
widget = TinyMCE(mce_attrs={'plugin_preview_pageurl': reverse('tinymce-preview', "NAME")})
The view named by ``tinymce-preview`` looks for a template named either
``tinymce/NAME_preview.html`` or ``NAME/tinymce_preview.html``. The template
accesses the content of the TinyMCE editor by using the ``tinymce_preview``
tag::
{% load tinymce_tags %}
...
{% tinymce_preview "preview-content" %}
...
...
With this template code the tekst inside the HTML element with id
``preview-content`` will be replace by the content of the TinyMCE editor.
.. _`preview plugin`: http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/preview
django-tinymce-1.5/docs/index.rst 0000644 0001750 0001750 00000002006 11145270131 016127 0 ustar joost joost Welcome to the tinymce documentation
====================================
tinymce is a Django_ application that contains a widget to render a form field
as a TinyMCE_ editor.
Features:
* Use as a form widget or with a view.
* Enhanced support for content languages.
* Integration with the TinyMCE spellchecker.
* Enables predefined link and image lists for dialogs.
* Can compress the TinyMCE Javascript code.
* Integration with `django-filebrowser`_.
The tinymce code is licensed under the `MIT License`_. See the ``LICENSE.txt``
file in the distribution. Note that the TinyMCE editor is distributed under
`its own license`_.
.. _Django: http://www.djangoproject.com/
.. _TinyMCE: http://tinymce.moxiecode.com/
.. _`django-filebrowser`: http://code.google.com/p/django-filebrowser/
.. _`MIT License`: http://www.opensource.org/licenses/mit-license.php
.. _`its own license`: http://tinymce.moxiecode.com/license.php
Documentation
-------------
.. toctree::
:maxdepth: 2
installation
usage
history
django-tinymce-1.5/docs/installation.rst 0000644 0001750 0001750 00000007622 11145270131 017532 0 ustar joost joost ============
Installation
============
This section describes how to install the tinymce application in your Django
project.
Prerequisites
-------------
The tinymce application requires Django_ version 1.0 or higher. You will also
need TinyMCE_ version 3.0 or higher and optionally a `language pack`_ for your
projects languages. If you use the `django-filebrowser`_ application in your
project, the tinymce application can use it as a browser when including media.
If you want to use the `spellchecker plugin`_ using the supplied view (no PHP
needed) you must install the `PyEnchant`_ package and dictionaries for your
project languages. Note that the Enchant needs a dictionary that exactly
matches your language codes. For example, a dictionary for code ``'en-us'``
will not automatically be used for ``'en'``. You can check the availability of
the Enchant dictionary for the ``'en'`` language code using the following
Python code::
import enchant
enchant.dict_exists('en')
.. _Django: http://www.djangoproject.com/download/
.. _TinyMCE: http://tinymce.moxiecode.com/download.php
.. _`language pack`: http://tinymce.moxiecode.com/download_i18n.php
.. _`spellchecker plugin`: http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker
.. _`PyEnchant`: http://pyenchant.sourceforge.net/
.. _`django-filebrowser`: http://code.google.com/p/django-filebrowser/
Installation
------------
#. Place the ``tinymce`` module in your Python path. You can put it into your
Django project directory or run ``python setup.py install`` from a shell.
#. Copy the ``jscripts/tiny_mce`` directory from the TinyMCE distribution into
a directory named ``js`` in your media root. You can override the location in
your settings (see below).
#. If you want to use any of the views add tinymce your installed applications
list and URLconf:
``settings.py``::
INSTALLED_APPS = (
...
'tinymce',
...
)
``urls.py``::
urlpatterns = patterns('',
...
(r'^tinymce/', include('tinymce.urls')),
...
)
.. _configuration:
Configuration
-------------
The application can be configured by editing the project's ``settings.py``
file.
``TINYMCE_JS_URL`` (default: ``settings.MEDIA_URL + 'js/tiny_mce/tiny_mce.js'``)
The URL of the TinyMCE javascript file.
``TINYMCE_JS_ROOT`` (default: ``settings.MEDIA_ROOT + 'js/tiny_mce'``)
The filesystem location of the TinyMCE files.
``TINYMCE_DEFAULT_CONFIG`` (default: ``{'theme': "simple", 'relative_urls': False}``)
The default TinyMCE configuration to use. See `the TinyMCE manual`_ for all
options. To set the configuration for a specific TinyMCE editor, see the
``mce_attrs`` parameter for the :ref:`widget `.
``TINYMCE_SPELLCHECKER`` (default: ``False``)
Whether to use the spell checker through the supplied view. You must add
``spellchecker`` to the TinyMCE plugin list yourself, it is not added
automatically.
``TINYMCE_COMPRESSOR`` (default: ``False``)
Whether to use the TinyMCE compressor, which gzips all Javascript files into
a single stream. This makes the overall download size 75% smaller and also
reduces the number of requests. The overall initialization time for TinyMCE
will be reduced dramatically if you use this option.
``TINYMCE_FILEBROWSER`` (default: ``True`` if ``'filebrowser'`` is in ``INSTALLED_APPS``, else ``False``)
Whether to use `django-filebrowser`_ as a custom filebrowser for media
inclusion. See the `official TinyMCE documentation on custom filebrowsers`_.
Example::
TINYMCE_JS_URL = 'http://debug.example.org/tiny_mce/tiny_mce_src.js'
TINYMCE_DEFAULT_CONFIG = {
'plugins': "table,spellchecker,paste,searchreplace",
'theme': "advanced",
}
TINYMCE_SPELLCHECKER = True
TINYMCE_COMPRESSOR = True
.. _`the TinyMCE manual`: http://wiki.moxiecode.com/index.php/TinyMCE:Configuration
.. _`official TinyMCE documentation on custom filebrowsers`: http://wiki.moxiecode.com/index.php/TinyMCE:Custom_filebrowser
django-tinymce-1.5/docs/history.rst 0000644 0001750 0001750 00000003576 11145270163 016543 0 ustar joost joost =========
History
=========
Changelog
---------
Release 1.5 (2009-02-13):
* Updated Google Code CSS location.
* Fixed a compressor crash when 'theme' configuration was omitted.
* Added a note in the documentation about Python-JSON type conversion.
* Fixed the filebrowser integration when serving media from a different
domain.
* Fixed flatpages example code in documentation.
* Added support for the preview plugin.
* Added "'relative_urls': False" to the default settings to fix integration
with django-filebrowser.
Release 1.4 (2009-01-28):
* Fixed bugs in compressor code causing it not to load.
* Fixed widget media property.
Release 1.3 (2009-01-15):
* Added integration with `django-filebrowser`_.
* Added templates to source distribution.
* Updated TinyMCE compressor support: copying media files no longer required.
.. _`django-filebrowser`: http://code.google.com/p/django-filebrowser/
Release 1.2 (2008-11-26):
* Moved documentation from Wiki into repository.
Release 1.1 (2008-11-20):
* Added TinyMCE compressor support by Jason Davies.
* Added HTMLField.
Release 1.0 (2008-09-10):
* Added link and image list support.
* Moved from private repository to Google Code.
Credits
-------
tinymce was written by `Joost Cassee`_ based on the work by John D'Agostino. It
was partly taken from `his code at the Django code wiki`_. The TinyMCE_
Javascript WYSIWYG editor is made by Moxiecode_.
The TinyMCE compressor was written by `Jason Davies`_ based on the `PHP TinyMCE
compressor`_ from Moxiecode.
.. _`Joost Cassee`: http://joost.cassee.net/
.. _TinyMCE: http://tinymce.moxiecode.com/
.. _Moxiecode: http://www.moxiecode.com/
.. _`his code at the Django code wiki`: http://code.djangoproject.com/wiki/CustomWidgetsTinyMCE
.. _`Jason Davies`: http://www.jasondavies.com
.. _`PHP TinyMCE compressor`: http://wiki.moxiecode.com/index.php/TinyMCE:Compressor
django-tinymce-1.5/README.txt 0000644 0001750 0001750 00000000354 11145270127 015045 0 ustar joost joost This Django application provides a TinyMCE widget.
Copyright (C) 2008 Joost Cassee
This program is licensed under the MIT License (see LICENSE.txt)
See http://django-tinymce.googlecode.com for docs.
--
Joost Cassee
joost@cassee.net
django-tinymce-1.5/LICENSE.txt 0000644 0001750 0001750 00000002040 11145270127 015164 0 ustar joost joost Copyright (c) 2008 Joost Cassee
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.