Customising block-level formatting in TinyMCE

August 21, 2007

Although TinyMCE allows you to specify custom styles (using the “theme_advanced_styles”parameter), it doesn’t exppose any easy way of specifying custom block-level formats.

This is most probably because the assumption is that people shouldn’t muck around with creating block-level tags beyond those normally present in HTML: “p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp”

However, in my case, I wanted to use an existing block-level element (“p”) div, but with the ability to simultaneously apply a css class to the element.

After a bit of poking around I discovered the way to do this:

  •  In the theme, define the menu names as desirable for the user to see (in “tinymce\jscripts\tiny_mce\themes\advanced\langs\en.js” in my case):
theme_author : 'Authors',
theme_ref : 'Ref',
theme_genre : 'Genre',
theme_citatio : 'Citatio',
theme_anot : 'Anot',
  • In the theme template, add some extra entries to the lookup table in getControlHTML (in “tiny_mce\themes\advanced\editor_template_src.js” in my case) with two parts: a prefix indicating the block-level element; and a suffix indicating the css style desired:
['p.author', '{$lang_theme_author}'],
['p.ref', '{$lang_theme_ref}'],
['p.genre', '{$lang_theme_genre}'],
['p.citatio', '{$lang_theme_citatio}'],
['p.anot', '{$lang_theme_anot}']
  • Now the biggy – amend the execCommand function to cope with these dotted names (in “tinymce\jscripts\tiny_mce\tiny_mce_src.js”).

    I chose to edit the source javascript as  it’s much easy to follow what’s going on. This means of course amending your HTML to refer to this tiny_mce_src.js, rather than to tiny_mce.js.

    After all this is finished I guess for completeness sake (and to save a bit of download time) I should apply the changes to the non-source (tiny_mce.js and editor_template.js).

    This means that the case block for FormatBlock should appear as follows (I’ve highlighted the new bits):

            case "FormatBlock":
                if (value == null || value == '') {
                    var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp");
                    if (elm)
                        this.execCommand("mceRemoveNode", false, elm);
                } else {
                    var classValue;

                    if (value.indexOf("p.") != -1 || value.indexOf("span.") != -1) {
                        value = value.replace(/[^a-z\.]/gi, '');
                        classValue = value.substring(value.indexOf(".") + 1);
                        value = value.substring(0,value.indexOf("."));

                        if (!this.cleanup.isValid(value))
                            return true;

                    } else {
                        if (!this.cleanup.isValid(value))
                            return true;
                    }
                    if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) {
                        value = value.replace(/[^a-z]/gi, '');
                    }
                    if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) {
                        var b = this.selection.getBookmark();
                        this.getDoc().execCommand("FormatBlock", false, '<p>');
                        tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value);
                        this.selection.moveToBookmark(b);
                    } else {
                        this.getDoc().execCommand("FormatBlock", false, value);
                        if (classValue)
                            this.execCommand("mceSetCSSClass", false, classValue);

                    }
                }
                tinyMCE.triggerNodeChange();
                break;
  • This allows the class prefixes to be stripped off, and employed. “classValue is a new variable that I’ve introduced for this purpose. Once the above has been done, these new formats should appear in the format menu, and (once you’ve added some CSS in the css for the application like that below, (example_bibliography_editor.css in my case) they should appear nicely in the editor:
p.author {
    font-size: large;
    background-color: #005555;
}

					
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: