diff --git a/README.rst b/README.rst index 077392b..e5ebecc 100644 --- a/README.rst +++ b/README.rst @@ -22,7 +22,7 @@ Installation Required ~~~~~~~~ -#. Install or add django-ckeditor-updated to your python path. Note: You may not have the original django-ckeditor and django-ckeditor-updated installed at the same time. +#. Install or add django-ckeditor to your python path. #. Add ``ckeditor`` to your ``INSTALLED_APPS`` setting. @@ -48,7 +48,7 @@ Required - ``pillow``: uses PIL or Pillow -#. django-ckeditor uses jQuery in ckeditor-init.js file. You must set ``CKEDITOR_JQUERY_URL`` to a jQuery URL that will be used to load the library. If you have jQuery loaded from a different source just don't set this variable and django-ckeditor will not try to load its own jQuery. Example:: +#. **django-ckeditor uses jQuery in ckeditor-init.js file. You must set ``CKEDITOR_JQUERY_URL`` to a jQuery URL that will be used to load the library**. If you have jQuery loaded from a different source just don't set this variable and django-ckeditor will not try to load its own jQuery. Example:: CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' @@ -120,6 +120,17 @@ Alernatively you can use the included ``CKEditorWidget`` as the widget for a for admin.site.register(Post, PostAdmin) + +Note that when using outside of admin panel you will have to make sure all form media is present for the editor to work. You may have to render the media like so:: + +
+ {{ myform.media }} + {{ myform.as_p }} + +
+ + + Managment Commands ~~~~~~~~~~~~~~~~~~ Included is a management command to create thumbnails for images already contained in ``CKEDITOR_UPLOAD_PATH``. This is useful to create thumbnails when starting to use django-ckeditor with existing images. Issue the command as follows:: @@ -136,13 +147,13 @@ See http://django-storages.readthedocs.org/en/latest/ If you want to use allowedContent ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To allowedContent works, disable **stylesheetparser** plugin. -So included this on your settings.py. +So included this on your settings.py.:: -CKEDITOR_CONFIGS = { - "default": { - "removePlugins": "stylesheetparser", + CKEDITOR_CONFIGS = { + "default": { + "removePlugins": "stylesheetparser", + } } -} Demo / Test application diff --git a/ckeditor/urls.py b/ckeditor/urls.py index a88bb0d..e8a3d70 100644 --- a/ckeditor/urls.py +++ b/ckeditor/urls.py @@ -1,10 +1,11 @@ from django.conf.urls import patterns, url from django.contrib.admin.views.decorators import staff_member_required +from django.views.decorators.cache import never_cache from ckeditor import views urlpatterns = patterns( '', url(r'^upload/', staff_member_required(views.upload), name='ckeditor_upload'), - url(r'^browse/', staff_member_required(views.browse), name='ckeditor_browse'), + url(r'^browse/', never_cache(staff_member_required(views.browse)), name='ckeditor_browse'), ) diff --git a/ckeditor/views.py b/ckeditor/views.py index ddabc87..3223581 100644 --- a/ckeditor/views.py +++ b/ckeditor/views.py @@ -4,6 +4,7 @@ import os from django.conf import settings from django.core.files.storage import default_storage from django.views.decorators.csrf import csrf_exempt +from django.views import generic from django.http import HttpResponse from django.shortcuts import render_to_response from django.template import RequestContext @@ -32,42 +33,43 @@ def get_upload_filename(upload_name, user): return default_storage.get_available_name(os.path.join(upload_path, upload_name)) -@csrf_exempt -def upload(request): - """ - Uploads a file and send back its URL to CKEditor. +class ImageUploadView(generic.View): + http_method_names = ['post'] - TODO: - Validate uploads - """ - # Get the uploaded file from request. - upload = request.FILES['upload'] + def post(self, request, **kwargs): + """ + Uploads a file and send back its URL to CKEditor. + """ + # Get the uploaded file from request. + upload = request.FILES['upload'] - #Verify that file is a valid image - backend = image_processing.get_backend() - try: - backend.image_verify(upload) - except utils.NotAnImageException: + #Verify that file is a valid image + backend = image_processing.get_backend() + try: + backend.image_verify(upload) + except utils.NotAnImageException: + return HttpResponse(""" + """.format(request.GET['CKEditorFuncNum'])) + + # Open output file in which to store upload. + upload_filename = get_upload_filename(upload.name, request.user) + saved_path = default_storage.save(upload_filename, upload) + + if backend.should_create_thumbnail(saved_path): + backend.create_thumbnail(saved_path) + + url = utils.get_media_url(saved_path) + + # Respond with Javascript sending ckeditor upload url. return HttpResponse(""" - """.format(request.GET['CKEditorFuncNum'])) + """.format(request.GET['CKEditorFuncNum'], url)) - # Open output file in which to store upload. - upload_filename = get_upload_filename(upload.name, request.user) - saved_path = default_storage.save(upload_filename, upload) - - if backend.should_create_thumbnail(saved_path): - backend.create_thumbnail(saved_path) - - url = utils.get_media_url(saved_path) - - # Respond with Javascript sending ckeditor upload url. - return HttpResponse(""" - """.format(request.GET['CKEditorFuncNum'], url)) +upload = csrf_exempt(ImageUploadView.as_view()) def get_image_files(user=None, path=''): @@ -96,7 +98,7 @@ def get_image_files(user=None, path=''): return for filename in storage_list[STORAGE_FILES]: - if os.path.splitext(filename)[0].endswith('_thumb'): + if os.path.splitext(filename)[0].endswith('_thumb') or os.path.basename(filename).startswith('.'): continue filename = os.path.join(browse_path, filename) yield filename diff --git a/ckeditor/widgets.py b/ckeditor/widgets.py index c322be8..bf68d59 100644 --- a/ckeditor/widgets.py +++ b/ckeditor/widgets.py @@ -8,10 +8,19 @@ from django.utils.encoding import force_text from django.utils.translation import get_language from django.core.exceptions import ImproperlyConfigured from django.forms.util import flatatt -import json + +from django.utils.functional import Promise +from django.utils.encoding import force_text +from django.core.serializers.json import DjangoJSONEncoder + +class LazyEncoder(DjangoJSONEncoder): + def default(self, obj): + if isinstance(obj, Promise): + return force_text(obj) + return super(LazyEncoder, self).default(obj) -json_encode = json.JSONEncoder().encode +json_encode = LazyEncoder().encode DEFAULT_CONFIG = { 'skin': 'moono',