
Customizing Kupu

  Written by: Guido Wesdorp
  Email: guido@infrae.com
  Valid for: Kupu 1.0.3

This is a document describing in detail how to customize Kupu on different
levels: using CSS and HTML to change or remove parts of the UI, overriding
initKupu() to reduce or extend the amount of tools used and hook in custom
tools, writing tools and overriding default Kupu behaviour.

Sidenote: in the Kupu package there's a subdirectory called 'silva' which
contains the customizing code used for a Zope based CMS (well, not strictly
but anyway ;) called 'Silva'. This code uses all the customization techniques 
described below, and can serve as an example for how to perform heavy 
customizations.

1. Integration and customization

  Kupu is a feature rich WYSIWYG editor and will provide a lot of ready-to-use
  features out-of-the-box. When one takes kupu.html (or kupumacros.html for
  Zope users) one doesn't have to change anything to use those features, but
  in a real-life situation, where issues like the available amount of real-
  estate, the capabilites of the back-end or even the expected knowledge of
  the users can play important roles, integrators will most likely want to
  perform some customization. The Kupu developers have tried to make 
  customization clean and clear, and to provide different ways of doing 
  customization, either changing the HTML or CSS for small customization 
  (we understand most people deploying a tool like Kupu will usually not
  want to hack JavaScript, so in most cases customizing Kupu should not 
  involve any programming) or overriding core Kupu functionality using 
  JavaScript.

2. Configuration

  Even though it really doesn't belong in this document, I would like to 
  mention configuration options as well, since they can be really useful for
  people who want to perform customizations, and we don't want to overlook
  them, ending up doing things from JavaScript that can easily be changed in
  the configuration... ;)
  Kupu has a very limited set of configuration options, which can all be set
  as attributes on the iframe. These are:

  Attribute             Possible values
  ----------------------------------------------------------------------------
  src                   the source URL of the document
  dst                   the URL to PUT to (not used for POST setups)
  use_css               whether Kupu should try to (it will succeed in Mozilla
                        use CSS for bold, italic etc. rather then plain <b>,
                        <i> or <strong>, <em> tags
  reload_after_save     whether Kupu should reload the iframe's content after
                        saving, or keep it in tact, retaining cursor position,
                        selection etc. (the last is obviously the nicest)
  strict_output         when set to 1, Kupu will send a full XHTML compliant
                        document, including document type declaration and 
                        xmlns namespace declaration to the server
  
3. CSS customization
  
  If an integrator wants to customize small issues, like the image of a 
  toolbar button, the font of a toolbox but also whether a toolbox or a button
  should appear in the client's page, he can modify the CSS. There's one
  main CSS, kupustyles.css, which contains classnames or ids for each button
  and toolbar. To change a color, image or font of that element, just override
  the CSS for the class or id that points to that element (note that classes
  are sometimes chosen where ids seem more appropriate, this is because one 
  can do more with CSS classes from JavaScript: when dynamically changing an 
  id of an element, any CSS directives connected to that id will not be 
  performed, when doing so with a class instead the CSS directives *will* 
  be performed), perferrably in another CSS file (having a seperate CSS file
  for overriding CSS will improve maintainability: when you upgrade from an
  already customized Kupu to a newer version you don't have to modify the
  core's CSS). 
  To remove an element from the page easily, you can add 'display: none' as
  a style directive for the element, it will be hidden from view. Note that
  it is also possible to remove the complete tool from the view using 
  JavaScript, which has the advantage that less data has to be sent to the
  client and the HTML will become a bit smaller, but is a bit harder.
  
4. Changing initKupu

  In one of the JavaScript files, kupuinit.js, there's a function called 
  initKupu(). Here's where the bootstrapping takes place: the editor is 
  instantiated and configuration and a logger are fed to it, the contextmenu 
  and the tools are instantiated and registered etc. If you want to 
  override or completely remove tools and context menu etc. from Kupu, you
  will need to override (probably copy and change) this function.
  When you want to remove a tool from Kupu, remove the lines in which it is
  instantiated and registered from your custom initKupu. When you subclass
  an existing tool or want to plug in your own, copy the lines of code used
  to instantiate an existing tool and change them.
  Since Kupu is still in development (even thought we passed 1.0 a while ago,
  unfortunatly it showed things aren't completely the way they should be, 
  hopefully at some point the API and core will be frozen for a while) you can
  expect customized initKupu's need modification after an Kupu upgrade. For
  instance, in 1.0.1 a toolbox was reflected by 1 JavaScript class, nowadays
  there's a seperate class for the functionality of that tool and one for the
  UI elements. The initKupu functions that are written for 1.0.1 need to be
  modified to reflect this change. 
  If you override this function, before starting an upgrade be sure to check 
  out the documentation or the mailinglist, where changes that break 
  customized initKupu functions will be mentioned.

5. Removing or changing tools

  As mentioned in the previous paragraph, to remove a tool from Kupu 
  completely you can just remove the lines in which it (and it's UI element)
  is instantiated. However, in some cases you will want to use or re-use the
  functionality of the tool class and get rid of or override the UI element.
  If you don't want the UI toolbox element of the TableTool to be part of the 
  HTML, but *do* want the contextmenu's table functionality available (which 
  is also provided via the tools), the UI element shouldn't be visible but 
  the tool itself should be available. This case could be solved using CSS
  (display: none) but if you have an overridden initKupu anyway, or if you
  really appreciate clean HTML it can be done using initKupu as well, by
  just not registering the UI element (TableToolBox) to the tool (TableTool).
  When you want to change the UI part of a tool, or want to override such a 
  toolbox you can just register it to the tool in a similar way. 

6. The KupuTool and KupuToolBox API's

  For a reference of the KupuTool and KupuToolBox API's, see API.txt. For
  a description of how to write them, see EXTENDING.txt. 

7. Overriding KupuEditor methods

  To override methods on the KupuEditor object, you can either attach a method
  with the name of the one to override to the prototype of the class or create
  a subclass. We did our best to make the API available on this core object 
  clean and small, and to keep the methods single operations as much as 
  possible, so overriding a method on this object usually won't involve much
  code duplication. 
  Note: unfortunately this is not really the case for saveDocument (although I 
  guess the need for overriding this is a lot smaller now that prepareForm is 
  available ;) and especially not for insertNodeAtSelection (if someone wants 
  to rewrite that to something a bit more compact, please do! ;).
