Last updated by johnbarclay on Mon, 2008-12-01 20:25
The WYSIWYG problem
The problem in allowing a Graphic User Interface editor to become What-You-See-Is-What-You-Get is that unless it is told the current CSS styling and the current CSS context then it is impossible for the editor to know what the end-result is supposed to look like. No matter how capable the editor is of being WYSIWYG it will fail unless it is supplied with enough information to know what styling it should be rendering, otherwise it is just a "pretty" editor and not a "WYSIWYG" editor.
Note: Before anyone tries to take this to extreme... pixel perfect WYSIWYG editing is not an achievable goal considering the wide range of factors that can influence the live published page in an internet environment and is not needed for the purpose of providing a user-friendly intuitive editing environment.
Commonly editors such as TinyMCE can be made to achieve WYSIWYG in a restricted manner that is typically limited to a single site, a single field type (e.g. pages and not blocks) and limited styling (e.g. will not know about CSS introduced by modules). Implimentation typically involve adapting the site theme's CSS to caer for the editor, have a seperate adapted copy of the CSS page just for the editor etc. A proper interface should allow an editor to automatically receive the current total CSS and what style context it should be operating in.
The key issues, as you may gather from above, appear to be:-
- Passing site/theme CSS
- Style Context
1: Passing site/theme CSS
The editor needs to know the current total CSS that may be required. This includes:-
- Site's styling
- User's current theme styling
- Content-Type styling
- Module added styling
Fortunately this is fairly easy to achieve by directing the editor to pick up it's CSS from the single location of the CSS cache. When enabled this cache contains the combined total CSS applicable for the current site visitor.
See How to make TinyMCE be WYSIWYG - almost
This needs extra logic added to it for resilience etc. but appears to be functional. But in order
2: Style Context
This is a much bigger issue and can be broken down to individual issues, but first of all a crude explanation of what is meant here by style context. The main "content" of a page when live or in the preview tab is preceeded by style information that does not form part of the actual content itself (see blow), all this information is omitted in Drupal's edit pages so that there is nothing to indicate to the GUI editor being launched as to whether the field being edited is a Story, Block or other type of content.
Published style context information..
<div id="main">
<div id="threecol"><div id="content" class="content-right"><div id="squeeze">
<h1 class="title node-type-forum">How to make TinyMCE be WYSIWYG - almost</h1>
<div class="node">
<div class="content">
.. PUBLISHED CONENT ..Edit screen style context information..
<div id="contentwrapper">
<div id="main">
<div id="threecol"><div id="content" class="content-right"><div id="squeeze">
<div class="content">
<form ..>
<div class="form-item">
<label for="edit-comment">Comment:</label>
<textarea cols="60" rows="15" name="comment" id="edit-comment" class="form-textarea resizable required">
.. EDITOR SESSION ..
</textarea>Note: Although there are more CSS div id's being applied, missing is the information that this is to be a "node" and that it is to be a "node-type-forum", therefore the editor can deduce that it is editing a form item, but it can not tell what type of content it is editing
Take the example of a simple <H2>Some Text</H2> - On our theoretical site <H2> on a standard story page might be styled differently depending on what sort of page it is being displayed in:-
- Story Page: <H2>=Large black Arial text with no background:
- News Letter - summary: <H2>=White Times-New-Roman on black background:
- News Letter - full-page: <H2>=Black Times-New-Roman on newspaper textured background:
- Events list block: <H2>=Blue italicised Arial:
- etc.
You can see that the same <H2> can be rendered differently depending on the style context of the field content being edited.
Issues that may need to be addressed to allow editors to reflect the style as it will be displayed in the published page:-
- Editors: Receving style context?
- Drupal: Increasing context information
- Drupal: Passing context information
Editors: Receiving style context?
The methods that CSS context can be rceived will vary from editor to editor so please add to this list. But without substantial re-writing editors to fit Drupal we need to know how editors currently decide what, if any, page context applies:-
- Inherited from source page - ?
- Template blank html page - TinyMCE(some browsers)
- Hard coded within editor - TinyMCE(some browsers)
Inherited from source page
Any style context in the page that the editor is being lauched from, i.e. applicable to the point in the page that the editor is launched from, is inherited by the editor and effects the editors rendered output.
Template blank html page
A dummy HTML page is used by the editor to allow the style context to be defined e.g.:-
"\sites\all\modules\tinymce\tinymce\jscripts\tiny_mce\blank.htm"
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>blank_page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body class="mceContentBody">
</body>
</html>Hard coded within editor
e.g. within TinyMCE:-
sites/all/modules/tinymce/tinymce/jscripts/tiny_mce/tiny_mce.js
..
..
if(dynamicIFrame)
{
html=tinyMCE.getParam('doctype')+'<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="'+tinyMCE.settings.base_href+'" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><div class="node"><div class="content"><body class="mceContentBody"></body></div></div></html>';
..
..Drupal: Increasing context information
This is a much more minor issues. The amount of context information supplied even to normal HTML content is limited and could benefit from enhancement.
For example the following additions to the node.tpl.php allow the site developer to alter how nodes are displayed by node-type; whether they are in full page, node list or teaser. These enhancements and the fairly standard "sticky" class output etc. may be better suited to the automatically rendered html along with other context classes.
From standard node.tpl.php
<div class="node<?php if ($sticky) { print " sticky"; } ?><?php if (!$status) { print " node-unpublished"; } ?>">
..
..From standard context enhanced node.tpl.php
<div class="node nodetype_<?php print $node->type; if ($sticky) { print " sticky"; } if ($page) { print " node_page"; } else { print " node_list"; } if ($page) { print " node_teaser"; } else { print " node_full"; } if (!$status) { print " node-unpublished"; } ?>">
..
.."Context" class suggestions
Suggestions for context classes to be rendered by Drupal in output page creation, please add or comment as "remove - unimportant" etc.:-
- sticky
- published / unpublished
- <node-type>
- node_page / node_list
- node_full / node_teaser
- auth_<author>
- tax_<nodes main taxonomy>
Drupal: Passing context information
The final part is ofcourse passing the context information to the editors. Multiple methods should be provided to cope with a wide range of editors and could include the following (please discuss, refute and add):-
Edit Tab
A variant of the node edit "PreView" tab which the editor can be launched in a dedicated page where all the CSS context is provide for the editor to inherit.
Generated Resultant CSS file
A variant of the Drupal CSS Cache mechanism that combines relevant styles but omits non-relevant styles so that it is a combination of the styles that should be applicapable to the current editing session. Impractical?
Generated blank.htm file
Create a blank.htm file that includes the style context, either in the editor module's directory or by redirecting the editor to pick up it's blank.htm from a drupal location.
Generated context string/function
String and/or function that returns a list of current context class (e.g. "node nodetype-newsletter published sticky") which can be imbedded into an editors code etc. with minimal change e.g.:-
..
..
if(dynamicIFrame)
{
html=tinyMCE.getParam('doctype')+'<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="'+tinyMCE.settings.base_href+'" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><div class='+DrupalClassContect()+'><div class="content"><body class="mceContentBody"></body></div></div></html>';
..
..Everything is invisible in Flock and Opera mac osx.
Many times the context is not predictable. What I often want to do is allow the user to apply styles, but only in certain contexts within the editor area, not where it is in a drupal block or node. Like classing only certain elements (h1,h2,..) with an "offscreen" class. FCK editor allows for some of this configuration (http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Configuration/S...) but is very limited. It will not apply multiple classes to the same element; rather it puts additional elements. I cannot for example have a class "nobullet" that is only applied to UL elements.