4

I wish to enforce a site-wide set of attributes to content produced via CKEditor.

For example, if someone inserts a table, I want the class 'myclass' automatically added as follows:

<table class='myclass'>...</table>

I want to do this for a large number of tags.

I have tried achieving this by modifying twig templates like table.html.twig, however CK editor content does not appear to apply any template, it only renders the entire post with field.html.twig.

What is the best - or generally accepted- way to accomplish this? I could modify the CKEditor Module directly but that would be modifying core which is not ideal.

This is a drupal 8 site.

  • You need to create a custom ckeditor plugin, which in D8 requires you to build a custom module to insert the plugin – No Sssweat Jul 27 '16 at 6:00
4

You can tackle this problem from both sides, with a ckeditor plugin as @Sssweat suggested and on the drupal side with a filter plugin.

This is an example from core which adds classes to tags. This code looks for the attribute 'data-align', but you can also look for tags:

namespace Drupal\filter\Plugin\Filter;
use Drupal\Component\Utility\Html;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
/**
 * Provides a filter to align elements.
 *
 * @Filter(
 *   id = "filter_align",
 *   title = @Translation("Align images"),
 *   description = @Translation("Uses a <code>data-align</code> attribute on <code>&lt;img&gt;</code> tags to align images."),
 *   type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
 * )
 */
class FilterAlign extends FilterBase {
  /**
   * {@inheritdoc}
   */
  public function process($text, $langcode) {
    $result = new FilterProcessResult($text);
    if (stristr($text, 'data-align') !== FALSE) {
      $dom = Html::load($text);
      $xpath = new \DOMXPath($dom);
      foreach ($xpath->query('//*[@data-align]') as $node) {
        // Read the data-align attribute's value, then delete it.
        $align = $node->getAttribute('data-align');
        $node->removeAttribute('data-align');
        // If one of the allowed alignments, add the corresponding class.
        if (in_array($align, array('left', 'center', 'right'))) {
          $classes = $node->getAttribute('class');
          $classes = (strlen($classes) > 0) ? explode(' ', $classes) : array();
          $classes[] = 'align-' . $align;
          $node->setAttribute('class', implode(' ', $classes));
        }
      }
      $result->setProcessedText(Html::serialize($dom));
    }
    return $result;
  }
}

The scaffolding of a custom filter module is very simple. See the tutorial:

https://www.lullabot.com/articles/creating-a-custom-filter-in-drupal-8

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.