Django: Django-TinyMCE und Django-Filebrowser einrichten
07. September 2009Im Folgenden wird Schritt für Schritt erklärt, wie man Django mit TinyMCE und einem Filebrowser aufbaut. In diesem Beispiel werden dabei Flatpages verwendet.
Zunächst müssen wir Django installieren:
Nun erstellen wir ein neues Projekt und wechseln in das Verzeichnis:
cd myapp
Als nächstes laden wir die Django-Applikationen “django-tinymce” und “django-filebrowser” (bitte auf die “Requirements” von django-filebrowser achten):
svn checkout http://django-filebrowser.googlecode.com/svn/trunk/filebrowser/ filebrowser
Es sollten 2 Ordner mit dem Namen “tinymce” und “filebrowser” im Projekt Ordner sein. Anschließend erstellen wir einen Ordner “static” bzw. “static/js” im Projektordner und laden die aktuellen TinyMCE-Dateien mit den gewünschten Sprachpaketen herunter: http://tinymce.moxiecode.com/download.php. Den soeben heruntergeladenen “tiny_mce”-Ordner kopieren wir komplett in “static/js” und ersetzen die gewünschten Sprachdateien. Schließlich müssen wir noch die Dateien aus dem App-Ordner “filebrowser/media/filebrowser” in den Ordner “static/filebrowser” kopieren und den Ordner “/static/uploads” erstellen, der später als Speicherort für alle Dateien des Filebrowsers dient.
Als nächstes passen wir unsere “settings” an (darauf achten, dass bei INSTALLED_APPS nicht mypro.filebrowser oder mypro.tinymce steht, sondern einfach tinymce und filebrowser):
import os
PROJECT_ROOT = os.path.abspath(".")
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ("Your Name", "your_email@domain.com"),
)
MANAGERS = ADMINS
DATABASE_ENGINE = "sqlite3" # "postgresql_psycopg2", "postgresql", "mysql", "sqlite3" or "oracle".
DATABASE_NAME = "database.sqlite" # Or path to database file if using sqlite3.
DATABASE_USER = "" # Not used with sqlite3.
DATABASE_PASSWORD = "" # Not used with sqlite3.
DATABASE_HOST = "" # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = "" # Set to empty string for default. Not used with sqlite3.
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = "Europe/Berlin"
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = "de-de"
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = os.path.join(PROJECT_ROOT, "static")
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = "/static/"
# URL prefix for admin media — CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = "/media/"
# Make this unique, and don"t share it with anybody.
SECRET_KEY = "85fq704e+mbox17=lezi(sj8t=-39)qjl%)eznf95ly4epyu%y"
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
"django.template.loaders.filesystem.load_template_source",
"django.template.loaders.app_directories.load_template_source",
# "django.template.loaders.eggs.load_template_source",
)
MIDDLEWARE_CLASSES = (
"django.middleware.common.CommonMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.flatpages.middleware.FlatpageFallbackMiddleware",
)
ROOT_URLCONF = "mypro.urls"
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, "templates"),
)
INSTALLED_APPS = (
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.sites",
"django.contrib.admin",
"django.contrib.sites",
"django.contrib.flatpages",
"mypro.main",
"filebrowser",
"tinymce",
)
FILEBROWSER_FORCE_GENERATOR = False
FILEBROWSER_FORCE_GENERATOR_RUN = False
FILEBROWSER_URL_WWW = MEDIA_URL + "uploads/"
FILEBROWSER_URL_FILEBROWSER_MEDIA = MEDIA_URL + "filebrowser/"
FILEBROWSER_PATH_SERVER = os.path.join(MEDIA_ROOT, "uploads")
FILEBROWSER_PATH_FILEBROWSER_MEDIA = os.path.join(MEDIA_ROOT, "filebrowser/")
TINYMCE_COMPRESSOR = True
TINYMCE_JS_URL = MEDIA_URL + "js/tiny_mce/tiny_mce.js"
TINYMCE_JS_ROOT = os.path.join(MEDIA_ROOT, "js/tiny_mce")
TINYMCE_DEFAULT_CONFIG = {
"theme":"advanced",
"theme_advanced_toolbar_location":"top",
"theme_advanced_toolbar_align":"left",
"relative_urls":"false",
"remove_linebreaks":"false",
"plugins":"syntaxhl,safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
"theme_advanced_buttons1":"syntaxhl,|,save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
"theme_advanced_buttons2":"cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
"theme_advanced_buttons3":"tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
"theme_advanced_buttons4":"insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
"extended_valid_elements":"textarea[cols|rows|disabled|name|readonly|class]"
}
Die urls.py sieht folgendermaßen aus:
from django.contrib import admin
from django.conf import settings
admin.autodiscover()
urlpatterns = patterns("",
(r"^admin/tinymce/", include("tinymce.urls")),
(r"^admin/filebrowser/", include("filebrowser.urls")),
(r"^admin/", include(admin.site.urls)),
(r"^static/(?P<path>.*)$", "django.views.static.serve", {"document_root": settings.MEDIA_ROOT}),
)
Damit der Filebrowser im Admin-Panel angezeigt wird, müssen wir noch das Admin-Template modifizieren. Zunächst müssen wir einen “templates”-Ordner im Projekt-Ordner und darin einen Ordner mit dem Namen “admin” erstellen. Zum Schluss noch die Datei “templates/admin/index.html” mit folgendem Inhalt (verändert wurde nur der Bereich zwischen den “filebrowser”-Tags):
{% load i18n %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% load adminmedia %}{% admin_media_prefix %}css/dashboard.css" />{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}dashboard{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block content %}
<div id="content-main">
<!– filebrowser –>
<div class="module">
<table>
<caption>File-Browser</caption>
<tr class="row2">
<th scope="row"><a href="filebrowser/">File-Browser</a></th>
<td> </td>
<td> </td>
</tr>
</table>
</div>
<!– end filebrowser –>
{% if app_list %}
{% for app in app_list %}
<div class="module">
<table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
<caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
{% for model in app.models %}
<tr>
{% if model.perms.change %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% if model.perms.add %}
<td><a href="{{ model.admin_url }}add/" class="addlink">{% trans "Add" %}</a></td>
{% else %}
<td> </td>
{% endif %}
{% if model.perms.change %}
<td><a href="{{ model.admin_url }}" class="changelink">{% trans "Change" %}</a></td>
{% else %}
<td> </td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
{% else %}
<p>{% trans "You don"t have permission to edit anything." %}</p>
{% endif %}
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% trans "Recent Actions" %}</h2>
<h3>{% trans "My Actions" %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% trans "None available" %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}</span></li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
Zusätzlich erstellen wir noch die Datei “templates/flatpages/default.html”:
Nun brauchen wir noch eine neue App für unsere Flatpages:
Hier erstellen wir nur die Datei “admin.py”:
from django.contrib import admin
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):
tinymce_fields = ["content"]
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == "content":
return forms.CharField(widget=TinyMCE(
attrs={"cols":100, "rows":30},
mce_attrs={
"language":"en",
},
))
return super(TinyMCEFlatPageAdmin, self).formfield_for_dbfield(db_field, **kwargs)
admin.site.unregister(FlatPage)
admin.site.register(FlatPage, TinyMCEFlatPageAdmin)
Abschließend benötigen wir noch einen Datenbank-Sync:
Jetzt sollte im Admin-Interface ein Bereich Filebrowser erscheinen, in dem man neue Dateien hochladen kann. Des Weiteren sollte bei den Flatpages ein integrierter TinyMCE-Editor vorhanden sein. Wenn man auf “Bild einfügen” klickt und dort auf das Dialog-Icon neben “Adresse” geht, sollte der integrierte Filebrowser erscheinen.
Will man das ganze hier mit eigenen Models einrichten, hier ein Beispiel dazu (admin.py):
from mypro.myapp.models import MyModel
from django import forms
from tinymce.widgets import TinyMCE
class TinyMCEAdmin(admin.ModelAdmin):
tinymce_fields = list()
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name in self.tinymce_fields:
return db_field.formfield(widget=TinyMCE(attrs={"cols": 100, "rows": 30}))
return super(TinyMCEAdmin, self).formfield_for_dbfield(db_field, **kwargs)
class MyModelTinyMCEAdmin(admin.ModelAdmin, TinyMCEAdmin):
tinymce_fields = ["content"]
admin.site.register(MyModel, MyModelTinyMCEAdmin)
Tags: Anleitung, Django, einrichten, Filebrowser, Flatpages, Howto, installieren, Python, TinyMCE


