Adding buttons to the advanced text editor

I need to add two buttons to the editor for the advanced text editor.  One for subscript and one for superscript.  Can someone point me in the right direction.  

I've spent several hours chasing this rabbit so forgive me if I seem so. :) 

I am a software engineer and while I could craft a solution myself I really would like to know what is blocking this simple task.  I shouldn't have to reinvent the wheel and introduce complexity for something that according to documentation from various sources including ckeditor's should be as simple as making a couple of edits.  

What is blocking the addition of buttons to the editor?  Multiple choice is one example of an h5p library that has the subscript and superscript buttons on the menu.  It looks like they're added via the semantics.json file.  Why doesn't the same method work for the advanced text library?  

The same is true for other instances of the editor that appear in the edit tab of different content types; there are subscript and superscript buttons on the menu and on others there are not.  Where/how do buttons get added to the editor's UI?  CKEditor config or the semantics for the library or somewhere else?  I'm working with the advanced text library and would like to know which configuration file needs to be edited.  I am looking at the network tab to see which file loads when I hit the pencil to edit the text.

This is the file that loads:

./sites/all/modules/contrib/h5p/modules/h5peditor/h5peditor/ckeditor/config.js

... But when I make changes to this file and reload, clearing the cache of course, there are no visual changes to the editor's UI.  In fact I can completely comment out this file, reload the page, click the pencil, confirm the changes were loaded but even with the entire file 'commented out' there is no visual change.  SO, I think something might be overriding it.  

 

icc's picture

I cannot tell you why the buttons aren't there in the first place, but I can show you how to add them to all CKEditor fields. 

Each field in the editor is controlled by the content type, so it decides which buttons to give the user. You can override the content type's settings through a special hook:

/**
 * Implements hook_h5p_semantics_alter().
 */
function yourthemeormodules_h5p_semantics_alter(&$semantics, $content_type, $major_version, $minor_version) {
  foreach ($semantics as $field) {
    // Go through list fields
    while ($field->type === 'list') {
      $field = $field->field;
    }
 
    // Go through group fields
    if ($field->type === 'group') {
      yourthemeormodules_h5p_semantics_alter($field->fields); // Check function name!
      continue;
    }
 
    // Check to see if we have the correct type and widget
    if ($field->type === 'text' && isset($field->widget) && $field->widget === 'html') {
      // Found a wysiwyg/CKEditor field. Add sub/sup buttons.
      if (!isset($field->tags)) {
        $field->tags = array();
      }
      if (!in_array('sub', $field->tags)) {
        $field->tags[] = 'sub';
      }
      if (!in_array('sup', $field->tags)) {
        $field->tags[] = 'sup';
      }
    }
  }
}

A similar approach is used for adding custom buttons: WYSIWYG Text Editor Buttons

Hopefully, in the future, there will be an easier way to customize this without so much frustration.

 

Thank you so much!  I am going to try this right away.  

papi Jo's picture

Thanks, very useful!

I tried using similar to the above for the font attributes, but with no luck, do you think this should be possible, my code is:

Any help appreciated

function h5ptable_h5p_semantics_alter(&$semantics, $content_type, $major_version, $minor_version) {
  foreach ($semantics as $field) {
    // Go through list fields
    while ($field->type === 'list') {
      $field = $field->field;
    }
  
    // Go through group fields
    if ($field->type === 'group') {
      h5ptable_h5p_semantics_alter($field->fields); // Check function name!
      continue;
    }
  
    // Check to see if we have the correct type and widget
    if ($field->type === 'text' && isset($field->widget) && $field->widget === 'html') {
      // Found a wysiwyg/CKEditor field. Add sub/sup buttons.
      if (!isset($field->font)) {
        $field->font = array();
      }
      if (!in_array('size', $field->font)) {
        $field->font[] = 'size';
      }
      if (!in_array('color', $field->font)) {
        $field->font[] = 'color';
      }
	  if (!in_array('background', $field->font)) {
        $field->font[] = 'background';
      }
    }
  }
}
icc's picture

This looks good, but instead of the ->font = array() try this instead:

if (!isset($field->font)) {
  $field->font = new stdClass();
}

// Only override if not already specified
if (!isset($field->font->size)) {
  $field->font->size = TRUE;
}
if (!isset($field->font->color)) {
  $field->font->color = TRUE;
}

thank you!

Thanks, that worked.

Strangley, this is working in my deve environment, but not in my live.  I receive the following error "ArgumentCountError: Too few arguments to function h5pbuttons_h5p_semantics_alter(), 1 passed in /var/app/current/sites/all/modules/h5pbuttons/h5pbuttons.module on line 16 and exactly 4 expected in h5pbuttons_h5p_semantics_alter() (line 7 of /var/app/current/sites/all/modules/h5pbuttons/h5pbuttons.module)."

line 7 is "function h5pbuttons_h5p_semantics_alter(&$semantics, $content_type, $major_version, $minor_version) {"

And line 16 is "      h5pbuttons_h5p_semantics_alter($field->fields); // Check function name!"

Any help appreciated

 

icc's picture

You're correct, you should change the line inside the function to say:
h5pbuttons_h5p_semantics_alter($field->fields, $content_type, $major_version, $minor_version);

Thanks for the quick reply, I have tried changing the code to the following, but I receive the following error: ParseError: syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ')' in drupal_load() (line 7 of /var/www/html/sites/all/modules/h5pbuttons/h5pbuttons.module). Any help appreciated.

<?php

/**
 * Implements hook_action_info().
 * Registers custom VBO actions as Drupal actions.
 */
function h5pbuttons_h5p_semantics_alter($field->fields, $content_type, $major_version, $minor_version) {
  foreach ($semantics as $field) {
    // Go through list fields
    while ($field->type === 'list') {
      $field = $field->field;
    }
   
    // Go through group fields
    if ($field->type === 'group') {
      h5pbuttons_h5p_semantics_alter($field->fields); // Check function name!
      continue;
    }
   
    // Check to see if we have the correct type and widget
    if ($field->type === 'text' && isset($field->widget) && $field->widget === 'html') {
      // Found a wysiwyg/CKEditor field. Add sub/sup buttons.
if (!isset($field->font)) {
  $field->font = new stdClass();
}
 
// Only override if not already specified
if (!isset($field->font->size)) {
  $field->font->size = TRUE;
}
if (!isset($field->font->color)) {
  $field->font->color = TRUE;
}
    }
  }
}
icc's picture

Sorry, I should have been a bit clearer, it's the second h5pbuttons_h5p_semantics_alter() you need to change, not the first, i.e. the one not starting with function