1

I want to add a custom style to the wordpress tiny mce. There are tons of tutorials for just adding a simple option like "highlight" which will add a span with a "highlight" class. Like: https://torquemag.io/2016/09/add-custom-styles-wordpress-editor-manually-via-plugin/

But what I need is an option to add additional data, like if you add a link. You mark the words, hit the link button, an input for the url shows up.

What I want to achieve? A custom style "abbriation" (https://get.foundation/sites/docs/typography-base.html). The solution I'm thinking of is, the user marks the word, chooses the abbriation style, an input for the descriptions shows up. fin.

Hope you can help me out!

1 Answer 1

3

So I have something similar in most of my WordPress projects. I have a TinyMCE toolbar button that has a couple of fields that output a bootstrap button.

What you need to do is create your own TinyMCE "plugin" and to achieve this you need two parts:

  1. A javascript file (your plugin)
  2. A snippet of PHP to load your javascript (plugin) into the TinyMCE editor.

First we create the plugin:

/js/my-tinymce-plugin.js

( function() {
    'use strict';

    // Register our plugin with a relevant name
    tinymce.PluginManager.add( 'my_custom_plugin', function( editor, url ) {

        editor.addButton( 'my_custom_button', {
            tooltip: 'I am the helper text',
            icon: 'code', // @link https://www.tiny.cloud/docs/advanced/editor-icon-identifiers/
            onclick: function() {

                // Get the current selected tag (if has one)
                var selectedNode = editor.selection.getNode();

                // If we have a selected node, get the inner content else just get the full selection
                var selectedText = selectedNode ? selectedNode.innerHTML : editor.selection.getContent();

                // Open a popup
                editor.windowManager.open( {
                    title: 'My popup title',
                    body: [

                        // Create a simple text field
                        {
                            type: 'textbox',
                            name: 'field_name_textbox',
                            label: 'Field label',
                            value: selectedText || 'I am a default value' // Use the selected value or set a default
                        },

                        // Create a select field
                        {
                            type: 'listbox',
                            name: 'field_name_listbox',
                            label: 'Field list',
                            value: '',
                            values: {
                                'value': 'Option 1',
                                'value-2': 'Option 2'
                            }
                        },

                        // Create a boolean checkbox
                        {
                            type: 'checkbox',
                            name: 'field_name_checkbox',
                            label: 'Will you tick me?',
                            checked: true
                        }
                    ],
                    onsubmit: function( e ) {
                        // Get the value of our text field
                        var textboxValue = e.data.field_name_textbox;

                        // Get the value of our select field
                        var listboxValue = e.data.field_name_listbox;

                        // Get the value of our checkbox
                        var checkboxValue = e.data.field_name_checkbox;

                        // If the user has a tag selected
                        if ( selectedNode ) {
                            // Do something with selected node
                            // For example we can add a class
                            selectedNode.classList.add( 'im-a-custom-class' );
                        } else {
                            // Insert insert content
                            // For example we will create a span with the text field value
                            editor.insertContent( '<span>' + ( textboxValue || 'We have no value!' ) + '</span>' );
                        }
                    }
                } );
            }
        } );

    } );

} )();

Now we add and modify the below snippet to your themes functions.php file.

/functions.php

<?php
add_action( 'admin_head', function() {
    global $typenow;

    // Check user permissions
    if ( !current_user_can( 'edit_posts' ) && !current_user_can( 'edit_pages' ) ) {
        return;
    }

    // Check if WYSIWYG is enabled
    if ( user_can_richedit() ) {

        // Push my button to the second row of TinyMCE actions
        add_filter( 'mce_buttons', function( $buttons ) {
            $buttons[] = 'my_custom_button'; // Relates to the value added in the `editor.addButton` function
            return $buttons;
        } );

        // Load our custom js into the TinyMCE iframe
        add_filter( 'mce_external_plugins', function( $plugin_array ) {

            // Push the path to our custom js to the loaded scripts array
            $plugin_array[ 'my_custom_plugin' ] = get_template_directory_uri() . '/js/my-tinymce-plugin.js';
            return $plugin_array;
        } );
    }
} );

Make sure to update the file name and path if you it's different to this example!

WordPress uses TinyMCE 4 and the documentation for this is lacking so finding exactly what you need can be painful.

This is merely a starting point and has not been tested.

Hope this helps!


EDIT

The below code should help you with the insertion of an "abbreviations" tag and title attribute.

( function() {
    'use strict';

    tinymce.PluginManager.add( 'my_custom_plugin', function( editor, url ) {

        editor.addButton( 'my_custom_button', {
            tooltip: 'Insert an abbreviation',
            icon: 'plus',
            onclick: function() {

                var selectedNode = editor.selection.getNode();
                var selectedText = selectedNode ? selectedNode.innerHTML : editor.selection.getContent();

                editor.windowManager.open( {
                    title: 'Insert an abbreviation',
                    body: [

                        {
                            type: 'textbox',
                            name: 'abbreviation',
                            label: 'The abbreviated term',
                            value: selectedText
                        },

                        {
                            type: 'textbox',
                            name: 'title',
                            label: 'The full term',
                            value: ''
                        }

                    ],
                    onsubmit: function( e ) {

                        var abbreviation = e.data.abbreviation;
                        var title = e.data.title.replace( '"', '\"' );

                        if ( selectedNode && selectedNode.tagName === 'ABBR' ) {
                            selectedNode.innerText = abbreviation;
                            selectedNode.setAttribute( 'title', title );
                        } else {
                            editor.insertContent( '<abbr title="' + title + '">' + abbreviation + '</abbr>' );
                        }
                    }
                } );
            }
        } );

    } );

} )();
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you SO MUCH! You're awesome, feel hugged. That's exactly what I've been looking for. Thanks for sharing.
Sorry Levi, but I can do what ever I want, it just doesn't show the new button. Any hint what I am missing? Even if I just copy & paste your direct code, just nothing will happen :S
nevermind. it was me, I overwrote it with the pagebuilder hooks im using. stupid little me. Your solution works perfectly fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.