Customizing TinyMCE 4.0

Many of the TinyMCE settings have changed in version 4.0. There is a new default theme: Modern, and all the UI settings for the former Advanced theme (theme_advanced...) are deprecated.

One often used setting was theme_advanced_blockformats. It was renamed to block_formats and keeps the same formatting. To specify a different set of elements for the ‘blockformats’ drop-down (second toolbar row in the WordPress Visual editor), you can set a string of name=value pairs separated by a semicolon in the initialization object:

block_formats: "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3"

Another handy setting: theme_advanced_styles doesn’t exist any more. However there is a more powerful version: style_formats. Now it can replace or add items to the new “Formats” menu.The value is an array of objects each containing a name that is displayed as sub-menu and several settings: a CSS class name or an inline style, and optionally the wrapper element where the class or inline style will be set:

toolbar3: 'styleselect',
style_formats_merge: true,
style_formats: { name: 'Custom styles', [
  {title: 'Red bold text', inline: 'b', styles: {color: '#ff0000'}},
  {title: 'Red text', inline: 'span', styles: {color: '#ff0000'}},
  {title: 'Red header', block: 'h1', styles: {color: '#ff0000'}},
  {title: 'Example 1', inline: 'span', classes: 'example1'},
  {title: 'Example 2', inline: 'span', classes: 'example2'}
]}

The above code will add another sub-menu to “Formats” without replacing the default menu items. There is more information and an example on the TinyMCE website.

Server managed cache in the browser

Imagine browsing to a big web page with lots of images and scripts, and it loads in your browser almost instantly, nearly as fast as loading it from your hard drive. Now imagine you’re browsing a web site with about 60-70 of these pages and they all load very very fast. Sounds interesting? But how to do that? Prime the browser’s cache? Preload all components of the web pages somehow? Is that possible?

Well, yes and no. It is possible by using Gears. It can be set to store all “static” components (JS, CSS, images, etc.) of a web page or a whole web site and load them from the local storage every time they are requested by the browser. However the Gears team shifted their priorities to HTML 5.0 offline storage which was the main idea behind Gears in the first place. Unfortunately the HTML 5.0 specification for offline storage implements only some of the features that were available in Gears, so this type of caching (controlled by the user and managed by the server) is impossible.

But why server managed cache? Isn’t the standard browser caching good enough? Yes, it is good. It has evolved significantly during the 15 or so years since the beginning of the World Wide Web. However it just can’t do that.

Lets take a simplistic look at how the browser cache works:

  • We (the users) browse to a web page.
  • The Server tells the Browser: “Hey there, these few files (images, JS, CSS, etc.) are almost never updated, put them in your cache and don’t ask me to send them again for the next 10 years.”
  • The Browser thinks: “Hmm, put them in the cache you saying? I’ll think about it. You know, I’m a Web Browser. I need to load pages very very fast. I don’t want a huge cache with millions of files in it. That will slow me down. Lets see if the User would come back to this page ever again.”

If we keep going to the same web page eventually the Browser would change his mind: “Maybe that Server was right and I should put these files in my cache. That would speed up page loading. But what will happen if these files are updated… I better keep asking the Server to check if they have been updated so my cache is always fresh.”

Couple of years ago we implemented Gears as WordPress’ Turbo feature. We didn’t use it to make WordPress an offline app, we used it to create server managed cache. It worked great. Even the heaviest pages in the WordPress admin were loading considerably faster regardless of how often the users were visiting them.

The implementation was very simple: we had a manifest that listed all “static” files and couple of user options to enable and initialize the “super cache”. The rest was handled automatically by Gears. So in reality we discovered the perfect way of browser caching for web apps:

  • The User decides which web sites / web apps are cached and can add or remove them.
  • The server (i.e. the web app) maintains the cache, updating, adding, deleting files as needed.

The results were spectacular. We didn’t need to concatenate and compress scripts and stylesheets. We even stopped compressing TinyMCE which alone can load about 30-40 files on initialization. And page load time was from 0.5 to 1.5 sec. no matter how heavy the page was. For comparison before implementing this “super caching” pages were loading in 5 to 9 sec.

Why was it performing that well? Simple: it eliminated all requests to the server for the files that were cached. And that means all, even the “HEAD” requests. In our implementation the only file that was loaded from the server was the actual HTML. All other components of the web page were stored in Gears’ offline storage.

That also had the side benefit of eliminating a big chunk of traffic to the server. At first look it doesn’t seem like a lot, 30-40 requests for the web page components followed by 30-40 of HEAD requests per page every now and then (while the browser cache is hot), but think about it in global scope: several millions of these pages are loaded every hour.

So, why not do the same with HTML 5.0 offline storage? Because it doesn’t work that way. The HTML 5.0 specification for offline storage is good only for… Offline storage. It’s missing a lot of the features Gears has. Yes, there is a workaround. We can “store offline” a skeleton of the web page and then load all the dynamic content with XHR (a.k.a. AJAX), but that method has other (quite annoying) limitations. Despite that we will try this method in WordPress for sure, but that discussion is for another post.

In short: the HTML 5.0 offline storage implementation is missing some critical features. For example a file that is stored there is not loaded from the storage when the browser goes to another page on the same website. Yes, it’s sad watching the browser load the same file again and again from the Internet when that file is already on the user’s hard drive.

What can we do about it? Don’t think there is anything that can be done short of changing, or rather enhancing the HTML 5.0 specification for offline storage. The XHR “hack” that makes this kind of caching possible with the current HTML 5.0 is still just a hack.

Can themes style the visual editor?

Short answer: yes. This has been available for quite some time but don’t think I’ve seen themes that do it. Things like typefaces, headings, image padding and borders, etc. can easily be set by the current theme making the visual editor… more WYSIWYG. All it takes is a stylesheet and a small function in the theme’s functions.php file:

add_filter('mce_css', 'my_editor_style');
function my_editor_style($url) {

  if ( !empty($url) )
    $url .= ',';

  // Change the path here if using sub-directory
  $url .= trailingslashit( get_stylesheet_directory_uri() ) . 'editor-style.css';

  return $url;
}

where editor-style.css will be applied to TinyMCE’s iframe.

There is also an option to define CSS classes that can be inserted by the user and to add the “Styles” drop-down selector to the editor toolbar. This is probably most useful for developers when creating a custom theme for a client as these classes would stop working if the theme is changed.

I’ve put together a small package with examples of how to enable this. If you are creating WordPress themes, download it or have a look, it’s quite simple. If not, perhaps ask the author of your theme to add it to the next update. 🙂

Update: as Dion points out in the comments, this is not meant for adding the whole “style.css” to the editor. That could bring problems and most of the styling won’t apply there anyways. It works best when a separate stylesheet is made specifically for use in the editor (editor-style.css in the example). It should contain a small subset from style.css, usually the part that is applied to the actual posts.

podPress and Popularity Contest

There have been couple of patches for the feeds in podPress by Tim Berger, Update and bugfix for the atom feed and Bypass of the RSS Feed does not work. Currently they are in the Development Version. If anybody wants to add more, please make a ticket on the plugins trac and drop me an email.

Also recently had a look at the Popularity Contest plugin. It works well in WordPress 2.7 and 2.8-bleeding only the activation fails. To make it compatible a small piece of code has to be added to the beginning: global $wpdb;

This should go just above the first “if” statement, so it looks like this:

// add this 
global $wpdb;

// existing code
if (!isset($wpdb)) {
	require('../../wp-blog-header.php');
	...

Tried to contact the author and send him this fix so he can add it to the plugin.

Troubleshooting TinyMCE in WordPress 2.7

One of the many improvements in WordPress 2.7 is the updated configuration of the visual editor, TinyMCE. It was optimized to support caching better and to load faster.

The compression whitin WordPress is gone and all editor components are included as standard Javascript, CSS and HTML files. However a lot of servers compress these files automatically. If your server doesn’t do that, the first loading of the write/edit page will be slower, but after that the editor loads a lot faster than before, as all files are in the browser’s cache on the hard disk. And if the “Turbo” is turned on in WordPress and Gears enabled, the speed increase is even bigger as the browser does not have to check if any file has been updated.

In my (non-scientific) tests the loading time of the Add New Post screen went from about 5 – 8 sec. to about 1 – 2 sec. depending on the Internet connection and the computer speed.

The removal of the compression whitin WordPress also improves compatibility with some unusual server configurations and fixes some hard to catch errors, for example when there are php errors or output starts in the current theme’s functions.php file.

Currently the editor’s settings together with all Javascript files are included directly in the HTML head section of the page, making it a lot easier to troubleshoot.

There are a few steps that would help with the troubleshooting if the editor doesn’t start or work properly:

  1. Make sure the “Disable the visual editor when writing” checkbox in your profile is not selected.
  2. Whitelist or set your blog as “trusted” in your firewall and antivirus program.
  3. Disable Gears, clear your browser’s cache, quit it, start it again, go back to the write page and force-reload it several times, while holding down Shift (Firefox) or Ctrl (IE). In Safari select Clear Cache (from the Safari menu on Mac).
  4. Try another browser and/or another computer.
  5. Disable all plugins, clear the cache, restart the browser and try again.
  6. Delete both wp-admin and wp-includes directories and upload fresh copies from the WordPress installation package.
  7. And finally install Firefox or Opera, note any Javascript errors, especially the first one and try searching on the support forum for a solution. If no solution exists, open a new thread including the error.

PodPress in WordPress 2.6

Yesterday had a quick look at podPress, the premier plugin for podcasting. It has a small incompatibility with the new Post Revisions feature introduced in WordPress 2.6.

PodPress seems to be in the middle of a large update. I’ve used the “experimental” version (8.9) of the plugin and emailed the proposed fix to the authors, however for the more impatient here is the patch:

function post_edit($post_id) {
	GLOBAL $post;
	if($this->justposted) {
		return;
	}
	$this->justposted = true;

	if ( isset($_POST['post_ID']) && (int) $_POST['post_ID'] )
		$post_id = (int) $_POST['post_ID'];

	$this->settings_item_save($post_id, $_POST);
}

It goes in podpress/podpress_admin_class.php, around line 51. What it does is to make sure the custom post meta fields used by podPress are attached to the actual Post, not one of the revisions.

Thank you!

I am deeply honoured to be chosen as WordPress.org core committer. That was a very nice surprise on the eve of the 2.6 release 🙂

Thanks a lot guys. I’ll do my best (and try not to mess anything up on trac).

WordPress 2.6: quick tips

The new WordPress 2.6 perfects most of the features introduced in 2.5 and adds several big enhancements. A nice security enhancement is the full support for SSL in the the admin area, ensuring all data sent from the browser to the server and back is encrypted.

To take full advantage of it, everybody should enter not one but three “Secret Keys” in their wp-config.php file. More details are available on Ryan’s blog.

Another security improvement is the disabling by default of the Atom Publishing and the XML-RPC protocols. This is more of a “locking of the back door when we know nobody is coming through there” kind of thing, not a “security guards with dogs”. However these protocols are used by the off-line blog editors and by some plugins, so if you have one of these, make sure to enable the protocol you need from the Settings screen.

A new improvement is the ability to add captions to all images. Just enter some text in the Caption field on the Insert Image dialog and a caption will be added both in the editor and on the blog. To show the captions on the blog correctly, a few CSS styles may need to be added to your current theme’s style.css file. These styles are in both the Default and Classic themes’ style.css and are as follows:


.aligncenter,
div.aligncenter {
    display: block;
    margin-left: auto;
    margin-right: auto;
}

.alignleft {
    float: left;
}

.alignright {
    float: right;
}

.wp-caption {
    border: 1px solid #ddd;
    text-align: center;
    background-color: #f3f3f3;
    padding-top: 4px;
    margin: 10px;
    -moz-border-radius: 3px;
    -khtml-border-radius: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
}

.wp-caption img {
    margin: 0;
    padding: 0;
    border: 0 none;
}

.wp-caption p.wp-caption-text {
    font-size: 11px;
    line-height: 17px;
    padding: 0 4px 5px;
    margin: 0;
}

Of course these styles can be edited to suit your theme. A nice way of editing CSS styles is to use FireFox with FireBug. When changing styles there, it would show you immediately how the look changes, and when everything looks good, just copy/paste the edited styles to your style.css file (don’t forget to check them in Internet Explorer, Safari and Opera too).

Editing image captions should be very intuitive. Clicking on the Edit button that pops up when you click on an image in the editor would open the newly enhanced Edit Image dialog that has the same options as the Insert Image one. It would let you align, resize, change the title, link or caption for the image. There is also an advanced tab that has more options.

Images with captions can also be aligned with the Align Left, Align Center, Align Right buttons on the editor’s toolbar. In FireFox and Internet Explorer, the images and the captions can be resized by dragging the corners, however that’s not recommended since most images don’t look very well after using this method. Best is to select the right size image when inserting it.

Trying to move an image that has a caption by dragging it doesn’t work (yet). Currently there’s no support for dragging in the editor. Since all modern browsers seem to support dragging better, it won’t be long before that will work well too.

Another nice enhancement is the “Turbo” (top-right corner on the dashboard). Behind it is a new browser plugin – Gears. Currently it only works in FireFox and Internet Explorer, soon in Safari.

In WordPress, Gears captures all “static” files (images, css and JavaScript) from the admin area to the computer’s Hard Disk. This eliminates needless connections to the server when these files are needed. That makes page loading quite “snappier” for people with fast connections and much faster when Internet is congested or the connection is slow.

After enabling Gears it would download about 200 small files (just over 1MB in total) to your Hard Disk. Any errors during the download usually mean that some files in WordPress haven’t been installed properly. The best way to fix this is to delete the wp-admin and wp-includes directories and upload fresh copies from the installation package.