blog-banner

Leveraging CKeditor Template to Theme Drupal Contents

  • CKEditor
  • Drupal 7
  • Drupal Planet

CKEditor Templates Drupal 8

WYSIWYG (a.k.a HTML Editor) has become a De facto for quickly formatting and publishing content from dynamic sites like Drupal. This is certainly a time saver and prevents from getting hands dirty with HTML.

In this connection, CKEditor has been a pioneer and around in the use and development cycle for a decade (the first release was in March 2003, in the name FCKeditor).

This solid and interesting tool plays well with the Drupal content publishing system via Wysiwyg module. The recent CKEditor, version 4.2.x brings something more interesting to our desk. I'm talking about Templates plugin in specific.

Note: As of now this version of CKEditor requires dev version 2.x-dev of Wysiwyg contrib module.

Our project requirements were to create a Newsletter sending site with Drupal as a base. (Having admired by Mailchimp, I considered this project as a trimmed version of the same).

Essentially we put together contrib modules - Simplenews, Mandrill, Wysiwyg (with CKEditor), Mime Mail and Media to get started. 

  • Simplenews for managing newsletter and subscription 
  • Mandrill for sending out emails via Web services
  • Wysiwyg for composing newsletter contents
  • and Media for Image handling 

Sounds cool! Isn't it?

Simplenews module offers a new content type newsletter. Essentially the body content of this node type is what is sent out a newsletter to subscribers on cron run. The newsletter content is to be composed using CKEditor buttons (and plugins). Each newsletter category had its own template (specific layout and Typography).

We initially thought of having dummy newsletter nodes for all templates in place and cloning the same whenever the actual newsletter to be sent. Along the way, we noticed the Templates addition in CKEditor.

We thought it would be cool to have newsletter templates integrated with CKEditor button (like the Media module does for Image). On further analysis, we found that it would be possible to have our custom templates as well.

From official documentation, it was found that adding the below snippet will add custom templates to CKEditor.

(Though the doc page says it is for 3.x but works well for 4.x as well),

// Register a template definition set named "default".
CKEDITOR.addTemplates( 'default',
{
    // The name of the subfolder that contains the preview images of the templates.
    imagesPath : CKEDITOR.getUrl( CKEDITOR.plugins.getPath( 'templates' ) + 'templates/images/' ),

    // Template definitions.
    templates :
        [
            {
                title: 'My Template 1',
                image: 'template1.gif',
                description: 'Description of My Template 1.',
                html:
                    '

Template 1

' +
                    '

Type your text here.

'
            },
            {
                title: 'My Template 2',
                html:
                    '

Template 2

' +
                    '

Type your text here.

'
            }
        ]
});

The above snippet to be added to mytemplates.js. In your CKEditor's config.js file need to mention that template file to use is as mytemplates.js.

Code for the same is below,

config.templates_files = [ '/mytemplates.js' ];

But Wysiwyg module didn't make use of config.js. However to suggest Wysiwyg to consider config.js we had to use the below hook_wysiwyg_editor_settings_alter() implementation in the custom module. 

/**
 * Implements hook_wysiwyg_editor_settings_alter().
 */
function mymodule_wysiwyg_editor_settings_alter(&$settings, $context) {
  if ($context['profile']->editor == 'ckeditor') {
    // load template file content
    $data = array(
      'myModule' => array(
        'template_a' => theme('mymodule_email_template_a'),
        'template_b' => theme('mymodule_email_template_b'),
      ),
    );
    drupal_add_js($data, 'setting');        
    // Example of setting customConfig option. Just note it gets overridden by values in $settings.
    $settings['customConfig'] = 'config.js';
  }
}

As we can see, the above implementation suggests obeying the 'config.js' configuration file found in the root folder of CKEditor library. 

In addition a call to drupal_add_js() can be noted. We used the same to pass the templates HTML to CKEditor as JavaScript variables. In fact, these can be programmed directly in mytemplates.js too.

But passing from the backend offers the following advantages,

  • Clean HTML in template file/theme function (instead of having it as a Javascript's concatenated strings)
  • To add dynamic stuff (tokens for instance to view email in a browser, add an unsubscribe link, etc.)
  • To leverage the Intercepts and Overrides of Drupal framework (preprocess function for instance)

After all these steps the updated mytemplates.js looks as below,

/**
 * Define custom templates for Winprijzen and Gratis newsletter
 */
CKEDITOR.addTemplates('default', {
    // The name of the subfolder that contains the preview images of the templates.
    imagesPath : CKEDITOR.getUrl( CKEDITOR.plugins.getPath( 'templates' ) + 'templates/images/' ),
    // Template definitions.
    templates :
        [
            {
                title: 'Template A',
                image: 'template_a.gif',
                description: 'Description of Template A',
                html: Drupal.settings.myModule.template_a
            },
                  {
                title: 'Template B',
                image: 'template_b.gif',
                description: 'Description of Template B',
                html: Drupal.settings.mdModule.template_b
            }
        ]
});

Now clicking the Templates Button in CKEditor will offer to select custom templates, similar to the above snapshot.

Get awesome tech content in your inbox