TinyMCE – dodawanie przycisków w trybie fullscreen

WordPress od dłuższego czasu posiada pełnoekranowy tryb tworzenia wpisów, pozwalający skupić się na pisaniu (w niektórych edytorach taki tryb nazywa się „Zen mode” lub po prostu „Distraction Free”). Warto zatem nauczyć się dodawać własne przyciski do edytora w tym trybie – warto od razu podkreślić, że dodawanie przycisków do edytora w wersji pełnoekranowej rządzi się trochę innymi prawami niż w wypadku zwykłego edytora TinyMCE.

Zacznijmy od szkieletu wtyczki:

add_action('admin_head', 'wordup_add_fullscreen_button');
add_action('admin_enqueue_scripts', 'wordup_add_css');

function wordup_add_fullscreen_button() {
  global $typenow;
  // sprawdzamy czy user ma uprawnienia do edycji postów/podstron
  if ( !current_user_can('edit_posts') && !current_user_can('edit_pages') ) 
    return;
  // weryfikujemy typ wpisu
  if( ! in_array( $typenow, array( 'post', 'page' ) ) )
    return;
  // sprawdzamy czy user ma włączony edytor WYSIWYG
  if ( get_user_option('rich_editing') == 'true') {
     add_filter( 'wp_fullscreen_buttons', 'wordup_add_button_to_fullscreen_editor' );
  }
}

function wordup_add_button_to_fullscreen_editor( $buttons ){
    return $buttons;
}

function wordup_add_css() {
    wp_enqueue_style('wordup-tinymce', plugins_url('/style.css', __FILE__));
}

W zasadzie powyższy kod jest bardzo podobny do kodu, którego używaliśmy przy tworzeniu zwykłych wtyczek dla TinyMCE. Główna różnica to linijka:

add_filter( 'wp_fullscreen_buttons', 'wordup_add_button_to_fullscreen_editor' );

Która odpowiada za dodanie naszego przycisku – jak widać korzystamy z filtra wp_fullscreen_buttons zamiast standardowego mce_buttons.

Największe różnice pojawiają się przy definiowaniu przycisku – nasz przycisk dodajemy poprzez stworzenie odpowiedniej tablicy asocjacyjnej:

function wordup_add_button_to_fullscreen_editor( $buttons ){
    $buttons['IKONA'] = array(
        'title' => 'NAZWA',
        'onclick' => "AKCJA",
        'both' => false
    );

    return $buttons;
}

Jak widać powyżej definicja przycisku zawiera nazwę jego ikonki, która jest też nazwą przycisku i jego identyfikatorem na liście przycisków edytora pełnoekranowego. Pole title to po prostu podpowiedź, która wyświetli się po najechaniu na nasz przycisk. W polu onclick określamy kod JavaScript, który wykona się po kliknięciu przycisku – zatem nie korzystamy z zewnętrznego pliku JS, tylko od razu określamy zachowanie przycisku. Ostatnie pole – both to flaga, która określa czy nasz przycisk będzie widoczny w obu trybach edytora – wizualnym i tekstowym czy tylko wizualnym.

Zacznijmy od podstawowej wersji przycisku działającego tylko w trybie wizualnym:

function wordup_add_button_to_fullscreen_editor( $buttons ){
    $buttons['icon dashicons-wordpress'] = array(
        'title' => 'WordPress button',
        'onclick' => "tinyMCE.activeEditor.insertContent('Hello World!');",
        'both' => false
    );

    return $buttons;
}

Skorzystałem w powyższym kodzie z faktu, że szkielet mojej wtyczki od razu dołącza kod od obsługi ikonek z Dashicons. Dlatego też nazwałem swoją wtyczkę jako icon dashicons-wordpress. Dostęp do samego edytora uzyskujemy poprzez obiekt tinyMCE.activeEditor, który jest aliasem obiektu tinyMCE.editors[0]. Po załadowaniu wtyczki nasz edytor pełnoekranowy prezentuje się następująco:

tinymce-fullscreen-1

Co jednak, jeżeli chcemy by nasz przycisk pojawił się w trybie tekstowym edytora pełnoekranowego? Wydawać by się mogło, że wystarczy zamienić flagę both na true:

function wordup_add_button_to_fullscreen_editor( $buttons ){
    $buttons['icon dashicons-wordpress'] = array(
        'title' => 'WordPress button',
        'onclick' => "tinyMCE.activeEditor.insertContent('Hello World!');",
        'both' => true
    );

    return $buttons;
}

Po takiej zmianie rzeczywiście nasz przycisk się pojawi na drugiej zakładce, ale po kliknięciu nie będzie działał – wynika to z faktu, że tryb tekstowy nie jest edytorem TinyMCE i wymaga dodatkowej obsługi w naszym kodzie JavaScript akcji kliknięcia. Prawidłowy kod obsługi edytora tekstowego wygląda następująco:

function wordup_add_button_to_fullscreen_editor( $buttons ){
    $buttons['icon dashicons-wordpress'] = array(
        'title' => 'WordPress button',
        'onclick' => "if(tinyMCE.activeEditor) {
          tinyMCE.activeEditor.insertContent('Hello World!');
        } else {
          var cursor = jQuery('#content').prop('selectionStart');
          if(!cursor) cursor = 0;
          var content = jQuery('#content').val();
          var textBefore = content.substring(0,  cursor );
          var textAfter  = content.substring( cursor, content.length );
          jQuery('#content').val( textBefore + 'Hello World!' + textAfter );
        }",
        'both' => true
    );

    return $buttons;
}

Przede wszystkim sprawdzamy czy obiekt tinyMCE.activeEditor istnieje – po przełączeniu na edytor tekstowy obiekt ten jest pusty co pozwala łatwo rozpoznać tryb edytora pełnoekranowego. Wtedy korzystamy z API JavaScript, które umożliwia nam odczytanie pozycji kursora w polu textarea, które w wypadku edytora pełnoekranowego ma ID content. Na podstawie pozycji kursora dzielimy zawartość pola tekstowego na dwa ciągi znaków – przed i po kursorze, wstawiamy pomiędzy nimi nasz tekst i taki wynikowy tekst umieszczamy ponownie w polu tekstowym.