Rounding off the use of TinyMCE for WYSIWYG editing

This is a follow-up a previous article, which described how I use the TinyMCE editor for comment and article creation.  However, at the time of writing this, there were four items left on my to-do list relating to such rich-text editing:

  • I’ve picked up a common Wikipedia practice which is to use the teletype (<tt>) tag to mark fixed font inline text (such as this).  I added a “quick & dirty” code mod to implement this as the TinyMCE doesn’t facilitate using this tag as standard.  However, I wanted to write a proper custom plugin for this when time permitted.  I have now done this and made it available to the TinyMCE community (see here).
  • The Javascript stub which configures and loads the TinyMCE components can use an AJAX-style XMLHttpRequest to a server-side loader tiny_mce_gzip.php which then assembles, compresses and caches any Javascript components needed server-side for a single Javascript download.  I initially had problems getting the Moxiecode-supplied version of this PHP loader to work – too many bugs – so I rewrote my own.  However, the Moxiecode team subsequently released an improved version that has some good functional improvements, so I back-ported my fixes to this new version and submitted this back to the developers which they have now adopted (see this tracker report and this version).  I’ll describe using this new version in a worked example below.
  • When doing in-place editing of an article I want the edit pane to adopt my style-sheet rather than the default TinyMCE style.  Implementing this was quite straightforward, but I just had to do the work following the documentation for the content_css option.
  • My last change isn’t to do with TinyMCE but I’ll mention it here for completeness, and that is that I have improved my integration with the OpenOffice.org HTML editor to make opening this a single-click function.  To do this, I have also added an extra HTTP pseudo-stream protocol to Firefox and Chrome “blogedit:” using gconftool-2 as below.  (I run Ubuntu on my laptop).  When an article is viewed in admin mode (which means that the user has edit privileges on the article), a couple of extra links are included on the page.  The first of these is the “Edit inline” tag which fires up the TinyMCE editor.  The second is an “Edit URI” tag which links to blogedit://<site>/<article>.  Clicking on this link fires up a client-side script which decodes the URI and opens the OpenOffice.org HTML editor on the cached HTML copy of the article (which the article view generates the server-side in the FTP mapped _admin directory if the user is an admin.
    gconftool-2 --set --type=string /desktop/gnome/url-handlers/blogedit/command '/home/terry/bin/blogedit "%s"'
    gconftool-2 --set --type=bool /desktop/gnome/url-handlers/blogedit/needs_terminal 'false'
    gconftool-2 --set --type=bool /desktop/gnome/url-handlers/blogedit/enabled 'true'

Using the new PHP Compressor

The new compressor makes use of the PHP 5 object model and implements a class TinyMCE_Compressor.  This new design entirely removes the need to do any dynamic loading of Javascript and allows the full server-side marshalling of the code needed to load an editor.  As I described in the previous article, you still need to build a small per-page configuration script which calls the tinyMCE.init() function for that page; however this is now stored on the server in the route directory for the TinyMCE editor.  The class implements three methods:

  • The static method TinyMCE_Compressor::renderTag is used to render the callback tag which can be placed in the HTML source to request the Javascript bundle. The method an array argument containing the non-default parameters specific to that tag.  An optional second boolean argument if true means that the generated tag is returned rather than output.  I use this because all of my output is carried out by a templating engine and I need to pass the tag to it as a parameter.  The code fragment which generates this tag is as follows.
    require_once("$blog_root_dir/includes/tinymce/tiny_mce_gzip.php");
    $scriptTag = TinyMCE_Compressor::renderTag( array(
        "url"     => "includes/tinymce/tiny_mce_gzip.php",
        "plugins" => "table,save,advlink,emotions,inlinepopups,insertdatetime,searchreplace," . 
                    "contextmenu,paste,fullscreen,visualchars,nonbreaking,xhtmlxtras,wordcount,teletype",
        "themes"  => "advanced",
        "files"   => array( "tiny_mce_article_bootstrap" ),
       ), true );
    $page->assign( 'script_tag', $scriptTag);
  • The constructor and handleRequest() method together handle requests generated when the client browser executes the script tag.  The constructor can optionally be modified on a per-site basis to supply any site-side configuration parameters.  In my case, for example, I use a central directory for all caching, so my constructor is as follows.  The handleRequest method decodes the get parameters generated the renderTag call and returns the cache file if it already exists, and marshals the necessary Javascript otherwise.
$tinyMCECompressor = new TinyMCE_Compressor(array(
  "languages" => "en",
  "cache_dir" => realpath(dirname(__FILE__) . "/../../_cache"),
  "expires"   => "1m",
));

Put these together and the only thing that you need to configure is the corresponding tinyMCE.init() function for each page on which you want to implement an editor. No more tinyMCE_GZ.init() calls. Easy and fast to load.

Leave a Reply