Pimp my TinyMCE

After using TinyMCE for a little while in my Django project I started looking at a good way to be able to manage the files used in the system that will integrate into TinyMCE.

(drum roll please)

Please everyone welcome Django FileBrowser. The FileBrowser is basically an extension or addon for the Django Admin Interface. It gives you access to add, modify and view directories on the web server as well as upload, modify and delete files. It makes it super easy to work with files and for me, images. Basically replaces the need for an FTP client.

Features:

  1. Multiple file upload.
  2. Define allowed file extensions and maximum upload size.
  3. Automatic/Manual thumbnail generation for single images as well as whole directories with a single click.
  4. Integration with TinyMCE (AdvImage & AdvLink).
  5. Automatic filters for date and file-types.
  6. Define individual select/upload directories for every FileBrowseField.
  7. Rename files/directories.
  8. FileBrowseField: Image-Preview (thumbnail) with the ability to click the thumbnail and see the original image.
  9. Basic image editing support with Snipshot.
  10. Advanced image editing support with Picnik.

Getting FileBrowser:

To get FilBrowser, open a terminal window and enter the following commands: (note that both the username and the password is “guest”)

$ svn co http://django-filebrowser.googlecode.com/svn/trunk/ filebrowser

Installation:

On the FileBrowser site there are installation instructions but I changed them a little so that my project is fully contained. Here are the steps I took:

  1. Copy the contents of the “media” directory into the media directory of your project.
  2. Copy the contents of the “template” directory into the template directory of your project.
  3. Copy the filebrowser project into your application directory.
  4. Create a directory named “admin” in the template directory of your project.
  5. Copy the “index.html” page from the “/Lib/site-packages/django/contrib/admin/templates/admin/” directory of your Python installation into the newly created “admin” directory under “templates”.
  6. Create an “uploads” directory in you directory that “MEDIA_ROOT” points to in your “settings.py” file.

Code Changes Required:

Now with all the files in place we need to make a few minor adjustments to get everything tied up nicely. Firstly we need to add some stuff to the “index.html” we copied over. Put the HTML below in the “{% for app in app_list %} … {% endfor %}” code block.

<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>

This will add a “menu item” in the admin section for the FileBrowser. Then we need to hook all the URLs up by adding a line to the “urls.py” file. Place the following above the admin url include.

(r’^admin/filebrowser/’, include(‘filebrowser.urls’)),

We’re almost done. Edit all references in the “py” files in the FileBrowser application to have “<you_project_name>.filebrowser.<whatever_views_urls_etc>”. You also need to go through the templates and check that all css, images etc are pointed to the right places since we moved it out of the Admin folder in Django into our own solution.

Using FileBrowser:

To use FileBrowser in your models is pretty easy. All you need to do is create a “CharField” with specific “help_text” and the javascript will do the rest. It basically looks at the “help_text” and adds an icon next to the field that will open the FileBrowser with which you can then choose the file that you want to use and if it is an image it will show a small thumbnail of that image below the field. Add the following to your model:

class Menu(models.Model):
    ...
    image = models.CharField(maxlength=300, help_text="FileBrowser.", blank=True, null=True)    

    Admin:
        ...
       js = ('/media/js/getElementsBySelector.js', '/location_to_your_media/filebrowser/js/AddFileBrowser.js',)

If you would like FileBrowser to open at a specific directory set the “help_text” to “FileBrowser: /my_directory/”.

If you are using TinyMCE, here is how you would hook up the FileBrowser in TinyMCE. The magic lies in the “file_browser_callback” where you create a custom javascript callback that is used for the image button. It will then create a window with the FileBrowser in it which then sends back the user’s selection to TinyMCE. Here is the code I used.

function CustomFileBrowser(field_name, url, type, win) {
    var fileBrowserWindow = new Array();
    fileBrowserWindow['title'] = 'File Browser';
    fileBrowserWindow['file'] = "/admin/filebrowser/?pop=2";
    fileBrowserWindow['width'] = '920';
    fileBrowserWindow['height'] = '600';
    fileBrowserWindow['close_previous'] = 'no';

    tinyMCE.openWindow(fileBrowserWindow, {
      window : win,
      input : field_name,
      resizable : 'yes',
      scrollbars : 'yes',
      inline : 'yes',
      editorID: tinyMCE.getWindowArg('editor_id')
    });
    return false;
  }

function myCustomSetupContent(editor_id, body, doc) {
    if (body.innerHTML == "") {
        body.innerHTML = "<p>xxx</p>";
    }
}

tinyMCE.init({
    mode: "textareas",
    theme : "advanced",
    language : "en",
    theme_advanced_toolbar_location : "top",
    theme_advanced_toolbar_align : "left",
    theme_advanced_statusbar_location : "",
    theme_advanced_buttons1 : "fullscreen,|,image,code,preview,|,cut,copy,paste,|,undo,redo,|,bold,italic,underline,|,bullist,numlist,|,sub,sup,|,justifyleft,justifycenter,justifyright,justifyfull,|,outdent,indent,|,link,unlink",
    theme_advanced_buttons2 : "formatselect,|,forecolor,backcolor,|,table,delete_col,delete_row,col_after,col_before,row_after,row_before,row_after,row_before,split_cells,merge_cells",
    theme_advanced_buttons3 : "",
    theme_advanced_path : false,
    theme_advanced_blockformats : "p,h1,h2,h3",
    width: '800',
    height: '500',
    content_css : "/path_to_your_media/css/preview.css",
    plugins : "advimage,advlink,fullscreen,table,preview",
    advimage_styles : "Linksbündig neben Text=img_left;Rechtsbündig neben Text=img_right;Eigener Block=img_block",
    advlink_styles : "intern (innerhalb von skipclass.at)=internal;extern (Link zu einer externen Seite)=external",
    advimage_update_dimensions_onchange: true,
    file_browser_callback : "CustomFileBrowser",
    relative_urls : false
});

You may also want to comment out or delete line 80 of “tiny_mce_popup.js” so that it does not overwrite your Django CSS. The like looks like this:

document.write(‘<link href=”‘ + tinyMCE.getParam(“popups_css”) + ‘” rel=”stylesheet” type=”text/css”>’);

That’s that. Try it out. I think it’s a pretty cool addon for Django especially if you’re using something like TinyMCE. The project’s website has some screen shots for you to look at as well as howto’s if you do not want it part of your project.

11 Responses to “Pimp my TinyMCE”

  1. some notes:
    # step 3) using django-terminology, the filebrowser is not a “project” but an “application”. I suggest doing the checkout within your app-directory, so step 3 is not necessary.
    # if the filebrowser is in your pythonpath (e.g. the application-directory), you don´t have to change any references in the “py”-files.
    # from my experience, you don´t have to load “/media/js/getElementsBySelector.js” …

  2. Hi patrickk,

    Thanks for the tips. Still pretty new to Python as a whole so all the help I get is really appreciated to help me do things better as well as those that read this.

    Cheers

  3. I don’t think the svn link is working. Can you please send me the sources on my email ? Thanks!

  4. Hi Radu,

    It seems that the code has moved according to http://trac.dedhost-sil-076.sil.at/trac/filebrowser/

    It is now at http://django-filebrowser.googlecode.com/svn/trunk/

    I will update this post.

  5. Hi! :)
    I’m using this nice file browser together with TinyMCE. I have integrated the filebrowser into TinyMCE (almost) successfully. I can upload pictures, generate thumbnails etc.

    But if I click on the white arrow inside the small blue box to select a picture I get the error message “tinyMCE is not defined”. (See this picture: http://www.idioglossia.de/temp/filebrowser-error.jpg)

    I don’t use any gzip compression with TinyMCE. Do you have any hints how to solve this problem! :-)

    Cheers,
    Nils

  6. Hi Nils,

    Make sure that in the model that you want this in that you you have set the “js” attribute in the Admin class.

    js = (‘/media/js/getElementsBySelector.js’, ‘/site_media/filebrowser/js/AddFileBrowser.js’,)

    Your paths may be different. Basically all that does is tell the Django Admin interface to use these two Javascript files as well.

    Hope that helps.

  7. Christopher!
    Thanks for your reply! :)

    In my admin class you can find this:

    js = (
    ‘tinymce/jscripts/tiny_mce/tiny_mce.js’,
    ‘tinymce/textareas.js’,
    ‘js/getElementsBySelector.js’,
    ‘filebrowser/js/AddFileBrowser.js’,
    )

    The paths are all correct, I’ve checked this twice. Still the same error. :( I’ve use the CustomFileBrowser function and the tinyMCE.init from your example. Any other ideas?

    Cheers,
    Nils

  8. i had to add ‘from django.utils.translation import ugettext as _ ‘
    to views.py: iwas getting name ‘_’ is not defined
    any other way of fixing this

  9. Very cool! Thanks for the helpful description.

  10. i know its been a while since tren posted, but the uggettext not defined is fixed in the svn version of django.

  11. I’ve been trying to get this to work with my TinyMCE, but I keep getting the error:

    tinyMCE.getWindowArg is not a function

    I’ve looked up the error and I have a feeling it’s because of the version of tinyMCE and tha the code is different now? Will I have to downgrade?

    Any help would be appreciated…


Leave a Reply