django-tinymce-1.5/0000755000175000017500000000000011145270203013340 5ustar joostjoostdjango-tinymce-1.5/tinymce/0000755000175000017500000000000011145270203015010 5ustar joostjoostdjango-tinymce-1.5/tinymce/widgets.py0000644000175000017500000001116011145270127017034 0ustar joostjoost# 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'%s' % (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/0000755000175000017500000000000011145270203017006 5ustar joostjoostdjango-tinymce-1.5/tinymce/templates/tinymce/0000755000175000017500000000000011145270203020456 5ustar joostjoostdjango-tinymce-1.5/tinymce/templates/tinymce/tiny_mce_gzip.js0000644000175000017500000000634311145270127023667 0ustar joostjoost/** * 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.html0000644000175000017500000000067311145270127025266 0ustar joostjoost django-tinymce-1.5/tinymce/templates/tinymce/filebrowser.js0000644000175000017500000000104111145270127023340 0ustar joostjoostfunction 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.py0000644000175000017500000000121611145270127017227 0ustar joostjoostimport 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.py0000644000175000017500000001054411145270127016530 0ustar joostjoost# 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.py0000644000175000017500000000134311145270127016653 0ustar joostjoost# 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/0000755000175000017500000000000011145270203017502 5ustar joostjoostdjango-tinymce-1.5/tinymce/templatetags/tinymce_tags.py0000644000175000017500000000070011145270127022544 0ustar joostjoost# 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__.py0000644000175000017500000000014211145270127021615 0ustar joostjoost# Copyright (c) 2008 Joost Cassee # Licensed under the terms of the MIT License (see LICENSE.txt) django-tinymce-1.5/tinymce/urls.py0000644000175000017500000000123311145270127016353 0ustar joostjoost# 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__.py0000644000175000017500000000014211145270127017123 0ustar joostjoost# Copyright (c) 2008 Joost Cassee # Licensed under the terms of the MIT License (see LICENSE.txt) django-tinymce-1.5/tinymce/compressor.py0000644000175000017500000001051011145270127017560 0ustar joostjoost""" 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-INFO0000644000175000017500000000241311145270203014435 0ustar joostjoostMetadata-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.py0000755000175000017500000000310011145270131015047 0ustar joostjoost#!/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.py0000644000175000017500000000011411145270141015467 0ustar joostjoostname = 'tinymce' authors = 'Joost Cassee' version = '1.5' release = version django-tinymce-1.5/docs/0000755000175000017500000000000011145270203014270 5ustar joostjoostdjango-tinymce-1.5/docs/usage.rst0000644000175000017500000002160011145270131016125 0ustar joostjoost===== 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.rst0000644000175000017500000000200611145270131016127 0ustar joostjoostWelcome 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.rst0000644000175000017500000000762211145270131017532 0ustar joostjoost============ 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.rst0000644000175000017500000000357611145270163016543 0ustar joostjoost========= 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.txt0000644000175000017500000000035411145270127015045 0ustar joostjoostThis 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.txt0000644000175000017500000000204011145270127015164 0ustar joostjoostCopyright (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.