How to add a new tab to page editor

I remembered that once I done this, yesterday I found where, but that code was… bad.
So today I little improved it and I’m going to share. Before I want to explain what I do.

First of all, there are 3 main things to do:

  1. Add the tab title beside the standard 2
  2. Add something to the content of the tab
  3. Make the content appear when our tab title is clicked, and disapper when standard tab titles are clicked

Most of things need js so we also need to enqueje js in the right pages (post.php and post-new.php).

1st point can’t be done via PHP, because the markup for those buttons are directly echoed from wp_editor function, without be processed by any filter.
So only chance is add them via javascript.

2nd point, can be easily done via PHP, using a function hooking the_editor filter.

3rd point again is done via javascript.

For all the code I created a simple plugin containing 3 file:

  • gmet.php – the main plugin file
  • gmet.js – the file containing javascript
  • gmet-content.php – this file contain the tab content

I created anotther file for the tab content in this way is easy to customize it, without digging into code.


gmet.php

<?php namespace GMET;
/*
 * Plugin Name: GM Editor Tab
 * Author: Giuseppe Mazzapica
 * Author URI: http://wordpress.stackexchange.com/users/35541/g-m
 *
 * Text Domain: gmet
 */


\add_action('admin_init', '\GMET\init'); 

function init() {
  \load_plugin_textdomain( 'gmet', false, dirname( \plugin_basename( __FILE__ ) ) );
  \add_action('admin_enqueue_scripts', '\GMET\scripts');
  \add_filter('the_editor', '\GMET\content');
}

function scripts( $page ) {
  if ( $page === 'post.php' || $page === 'post-new.php' ) {
    $custom_css = "#content-gmet.active { 
      border-color: #ccc #ccc #f4f4f4; background-color: #f4f4f4; color: #555;
    }";
    wp_add_inline_style( 'colors', $custom_css );
    \wp_enqueue_script('gmet', \plugins_url('/gmet.js', __FILE__ ) );
    \wp_localize_script( 'gmet', 'gmetData', array(
      'tabTitle' => __('My Custom Tab', 'gmet')
    ) );
  }
}

function content( $content ) {
  preg_match("/<textarea[^>]*id=[\"']([^\"']+)\"https://wordpress.stackexchange.com/", $content, $matches);
  $id = $matches[1];
  // only for main content
  if( $id !== "content" ) return $content;
  ob_start();
  include( \plugin_dir_path( __FILE__ ) . 'gmet-content.php' );
  return $content . ob_get_clean();
}

There are only 3 functions: the first setup the hooks, the second add the javascript in the page, the third is responsible to add the content on the tab page.


gmet.js

(function($) {

  $(document).ready(function() {
    var $bar = $('<div></div>');
    $bar.addClass('quicktags-toolbar');
    $wrap = $('#gmet_content_wrap');
    $wrap.children().css('padding', '5px 15px');
    $wrap.prepend($bar);
    $('#wp-content-editor-tools #content-html').before(
      '<a id="content-gmet" class="wp-switch-editor">' + gmetData.tabTitle + '</a>'
    );
  });

  $(document).on('click', '#content-gmet', function(e) {
    e.preventDefault();
    var id = 'content';
    var ed = tinyMCE.get(id);
    var dom = tinymce.DOM;
    $('#wp-content-editor-container, #post-status-info').hide();
    dom.removeClass('wp-content-wrap', 'html-active');
    dom.removeClass('wp-content-wrap', 'tmce-active');
    $(this).addClass('active');
    $('#gmet_content_wrap').show();
  });

  $(document).on('click', '#content-tmce, #content-html', function(e) {
    e.preventDefault();
    $('#content-gmet').removeClass('active');
    $('#gmet_content_wrap').hide();
    $('#wp-content-editor-container, #post-status-info').show();
  });

})(jQuery);

Again 3 tasks: on document ready I setup some css and, most important, I add our tab title markup to the editor. Second task run when user click on our tab title: the standard editor is hidden an our content is shown. To hidden standard editor I copyed and pasted som code from wp-admin/js/editor.js. Last task is the easiest, when standard tab titles are clicked I hide our tab content and remove the class ‘active’ that from tab title.


gmet-content.php

<div id="gmet_content_wrap" class="wp-editor-container">
  <!-- Everything you want to output should go inside this div -->
  <h3>Hi there</h3>
  <p>
    <input type="text" class="regular-text" name="gmet_text" placeholder="Example" />
  </p>
  <p>
   <textarea name="gmet_textarea" cols="100" id="gmet_textarea" rows="10"></textarea>
  </p>
</div>

This file contain what is shown in aour tab. This is only an example, customize it as you want, only remember to add everything iside the wrapper div.

Now, just create a folder inside your plugins directory, save all 3 files inside it, and then go to your dasboard and activate the plugin.

All files are available as Gist here.

Leave a Comment