0

I have looked for days and cannot find an example of what I need to do. I wish to reformat the HTML output ckeditor uses for blockquote.

CKEditor output for quote:

<blockquote><p>Content</p></blockquote>

I wish it to output to something like:

<div class="name"><blockquote>Content</blockquote></div>

If I am able to do this, it has a lot of potential uses for every format provided in many sites for me. Does anyone know how to do this?

*Edit: My preference is to do this in PHP within a module if possible rather than JavaScript.

6
  • You would need to write your own CKEditor plugin with the CKEditor API that provides the blockquote wrapping youd want to have.
    – Kevin
    Feb 28 '19 at 16:21
  • @Kevin Can you provide a link to this documentation? I have never done that before. Any help here is appreciated, thank you!
    – user28555
    Feb 28 '19 at 17:24
  • drupal.org/node/1793710 - thats one piece. The rest of the documentation lies int he CKEditor plugin docs for your version of CKEditor.
    – Kevin
    Feb 28 '19 at 17:44
  • 1
    Another option would be to create a custom text format filter where you can use PHP to modify the DOM output. Example module: api.drupal.org/api/examples/… Mar 3 '19 at 3:06
  • 1
    @user1399437 - Answer is posted. Happy to help. :) Mar 10 '19 at 17:56
0

Here is a PHP-only, module-based example that defines a custom filter. The filter creates a DOMDocument object from the HTML output so you can iterate over the elements and alter them. This approach of course will only alter the tags when they are output to the browser, not inside CKEditor (you will absolutely need a plugin for this, as Kevin suggested).

Once you have created the filter you will need to enable it for your text format in Configuration > Text Formats.

If you've never created a Drupal module before, all of the basics are here: Creating custom modules (Drupal 7).

Example mymodule.module file:


/**
 * Implements hook_filter_info().
 */
function mymodule_filter_info() {
  $filters['mymodule'] = array(
    'title' => t('Blockquote filter'),
    'description' => t('Alter <em>blockquote</em> tags.'),
    'process callback' => '_mymodule_process_callback',
  );
  return $filters;
}

/**
 * Callback function.
 */
function _mymodule_process_callback($text, $filter, $format, $langcode, $cache, $cache_id) {
  return _mymodule_filter_html($text);
}

/**
 * Helper function. Handles the actual processing.
 *
 * @param string $string
 *   HTML content to filter from.
 * @return string
 *   HTML with tags altered, if any; else the original HTML.
 */
function _mymodule_filter_html($string) {

  // Suppress errors on HTML5 elements.
  libxml_use_internal_errors(true);

  // filter_dom_load() is a Drupal API function that loads the whole text
  // string into a DOMDocument object.
  $dom = filter_dom_load($string);

  // This flag will tell us if the HTML was altered.
  $altered = FALSE;

  // Process blockquote elements.
  foreach ($dom->getElementsByTagName('blockquote') as $tag) {

    // Do your processing here. Look up examples for wrapping elements
    // using `DOMDocument`.

    $altered = TRUE;
  }

  // If any tags were altered, dump the new DOM to HTML.
  if ($altered) {
    // filter_dom_serialize() is another Drupal API function that serializes
    // the DOMDocument back to XHTML.
    return filter_dom_serialize($dom);
  }
  return $string;
}
0

You could do this easily with jQuery, check the .wrap() method:

$('blockquote').wrap('<div class="name"></div>');

The wrap() method will wrap elements into another element.

If you want to do it as custom CKEditor plugin I would look at an existing plugin that does something similar and modify it to get the markup you want. I found a Drupal module with a custom plugin that add a wrapper element to blockquote: https://www.drupal.org/project/ckeditor_blockquote_attribution

4
  • 1
    It's better to do this outside of Javascript. Depending on how this site is built, this now puts a dependency on the theme to load jQuery and other relevant libraries just to do this. Forking and modifying the blockquote plugin to fit the use case requires no extra effort on the frontend to do anything.
    – Kevin
    Feb 28 '19 at 16:44
  • I do not want to do this with JQuery, I want to do this in the code in PHP to redo the formatting output of the tag structure.
    – user28555
    Feb 28 '19 at 17:23
  • You will not be able to accomplish this with just PHP either. You would need to build a CKEditor plugin (which is all JS) to get specifically crafted markup. The only PHP part would be describing this new plugin to WYSIWYG module or CKEditor module.
    – Kevin
    Feb 28 '19 at 17:35
  • Updated answer with an example you could use as a base.
    – ipwa
    Feb 28 '19 at 17:48

Your Answer

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