Adding Code Snippets using CKEditor - D8

To be able to embed code snippet using your favorite WYSIWYG editor in Drupal 8, you will need to do the following.

1. Download Code Snippet plugin

The plugin can be downloaded from https://ckeditor.com/addon/codesnippet.

Download and extract the plugin into your web/libraries folder.

2. Implement CKEditor button plugin

The easiest way to do this is by using Drupal Console to generate the boilerplate. If you are doing Drupal 8 and are not yet familiar with Drupal Console, I would highly suggest you to check it out.

Option 1

To generate the CKEditor button plugin use the following command:

drupal generate:plugin:ckeditorbutton [options]

So in our case, if we have a custom module named custom_module, we will use the following options:

drupal generate:plugin:ckeditorbutton  \
--module="custom_module"  \
--class="CodeSnippetCKEditorButton"  \
--label="Code snippet ckeditor button"  \
--plugin-id="codesnippet"  \
--button-name="Code Snippet"  \
--button-icon-path="libraries/codesnippet/icons/codesnippet.png"

Things to note:

  • --module: The name of the custom module implementing the plugin
  • --class: Plugin Class name
  • --label: Plugin label
  • --plugin-id: This corresponds to the CKEditor plugin name. It is the first argument of the CKEDITOR.plugins.add() function in the plugin.js file. In our case, it is codesnippet.
  • --button-name: This corresponds to the CKEditor button name. They are the first argument of the editor.ui.addButton() or editor.ui.addRichCombo() functions in the plugin.js file.
  • --button-icon-path: Button icon path. This is the path to the icon/image of the button. If you looked inside codesnippet folder, you will see the icon reference on the above path.

 

Option 2

If you don't have Drupal Console configured, you can copy the following snippet into a new file in the following path: /web/modules/custom/custom_module/src/Plugin/CKEditorPlugin/CodeSnippetCKEditorButton.php

<?php

namespace Drupal\custom_module\Plugin\CKEditorPlugin;

use Drupal\ckeditor\CKEditorPluginBase;
use Drupal\editor\Entity\Editor;

/**
 * Defines the "codesnippet" plugin.
 *
 * NOTE: The plugin ID ('id' key) corresponds to the CKEditor plugin name.
 * It is the first argument of the CKEDITOR.plugins.add() function in the
 * plugin.js file.
 *
 * @CKEditorPlugin(
 *   id = "codesnippet",
 *   label = @Translation("Code snippet ckeditor button")
 * )
 */
class CodeSnippetCKEditorButton extends CKEditorPluginBase {


  /**
   * {@inheritdoc}
   *
   * NOTE: The keys of the returned array corresponds to the CKEditor button
   * names. They are the first argument of the editor.ui.addButton() or
   * editor.ui.addRichCombo() functions in the plugin.js file.
   */
  public function getButtons() {
    // Make sure that the path to the image matches the file structure of
    // the CKEditor plugin you are implementing.
    return [
      'CodeSnippet' => [
        'label' => t('Code snippet ckeditor button'),
        'image' => 'libraries/codesnippet/icons/codesnippet.png',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getFile() {
    // Make sure that the path to the plugin.js matches the file structure of
    // the CKEditor plugin you are implementing.
    return libraries_get_path('codesnippet') . '/plugin.js';
  }

  /**
   * {@inheritdoc}
   */
  public function isInternal() {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function getDependencies(Editor $editor) {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getLibraries(Editor $editor) {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getConfig(Editor $editor) {
    return [];
  }

}

3. Configure text filter to show the CKEditor button

Let's configure Full HTML text filter to show the Code Snippet button.

Go to admin/config/content/formats/manage/full_html. Or Configuration -> Content authoring -> Text formats and editors -> Configure (Full HTML). Move the Code Snippet button into the Active toolbar.

Code Snippet CKEditor button

4. (Optional) Include the highlight CSS and JS file.

To be able to use syntax highlighting on your code snippets, you will need to include the highlight plugin. On libraries.yml file of the active theme, include the js and css for the highlight.

global-styling:
  css:
    theme:
      /libraries/codesnippet/lib/highlight/styles/solarized_dark.css: {}
  js:
    js/scripts.js: {}
    /libraries/codesnippet/lib/highlight/highlight.pack.js: {}
  dependencies:
    - core/jquery
    - core/drupal
    - core/drupalSettings
    - core/jquery.once

I have specified solarized_dark.css theme on the example above, but you can choose from the available styles found in web/libraries/codesnippet/lib/highlight/styles folder.

── styles
    ├── arta.css
    ├── ascetic.css
    ├── atelier-dune.dark.css
    ├── atelier-dune.light.css
    ├── atelier-forest.dark.css
    ├── atelier-forest.light.css
    ├── atelier-heath.dark.css
    ├── atelier-heath.light.css
    ├── atelier-lakeside.dark.css
    ├── atelier-lakeside.light.css
    ├── atelier-seaside.dark.css
    ├── atelier-seaside.light.css
    ├── brown_paper.css
    ├── brown_papersq.png
    ├── dark.css
    ├── default.css
    ├── docco.css
    ├── far.css
    etc...

5. (Optional) Instantiate the highlighter plugin using hljs.initHighlightingOnLoad();

From your custom JS file do the following.

(function($){
  Drupal.behaviors.codesnippetHighlighter = {
    attach: function(context, settings) {
      hljs.initHighlightingOnLoad();
    }
  }
})(jQuery);