syntaxhighlightを追加

記事の画像ファイルはImageFieldで管理するようにしてあるため、本文への貼付けは、Wysiwygモジュール+Wysiwyg Fieldsモジュールで実現しています。

プログラムのソースコードなどを本文に記述する際はpreタグを手入力してマークアップはStylesheetで対応していました。
なお、WysiwygエディタにはCKEditorを使っています。
※CKEditorモジュールではなくCKEditorライブラリのみ

WysiwygモジュールでCKEditorライブラリを読み込み実現しているため、通常のCKEditorの設定は読み込まれません。
この点が、CKEditorモジュールとの違いになります。
そのため、CKEditorの設定をカスタマイズするようなボタングループやその配置、プラグインなどを利用する場合には、Wysiwygモジュールのhookモジュールを自作しなくてはなりません。

ボタンの表示に関するカスタマイズは、以前、自作した「custom」モジュールですでに実現済みでしたが、今回は、CKEditorのプラグインである「Syntaxhighlight」を追加しようと考えました。

これに関連して、CKEditorライブラリのバージョンを3.xから4.xに更新するために、Wysiwyg-7.x-2.2から7.x-2.x-devへupdateしました。
※WysiwygモジュールがサポートするCKEditorのバージョンはこちらに記載があります。
※Wysiwyg-7.x-2.2がサポートする最新バージョンは3.6.6.1、Wysiwyg-7.x-2.x-devがサポートする最新バージョンは4.4.1となっています。
Wysiwyg-7.x-2.2で最新バージョンの4.4.6を試してみましたが、たしかにCKEditorを認識できませんでした。
しかし、Wysiwyg-7.x-2.x-devでは最新バージョンの4.4.6を認識でき使えました。
恐らく、Wysiwyg-7.x-2.2(安定版)が3.xサポートで、Wysiwyg-7.x-2.x-dev(開発版)が4.xサポートではないかと思います。

よって、この環境でSyntaxhighlightプラグインを追加する作業を行いました。

まず、プラグインを追加するにはどうするのか?
本来ならCKEditorライブラリ以下のconfig.jsや別途custom_config.jsを作成してそれを使うように設定するといった方法になるかと思います。
しかし、Wysiwygモジュールは別にCKEditor用のconfig.jsを持っているのでライブラリ以下を変更しても影響はありません。
そのため、hookモジュールの自作が必要になります。

当初からはかなり月日が経過したこともあり、Wysiwyg+ckeditor用のhookモジュールの作成方法について記載されているサイトも多くなりました。
その中で一番条件が近いものを参考にしてトライしてみました。

参考にしたのは、ここここです。
リンク先のページしたにあるサンプルをダウンロードして、それを参考にSyntaxhightlight用を作成しましたが、Wysiwygモジュールのプロファイル設定画面「admin/config/content/wysiwyg/profile/」にチェックボタンを表示させるところまではできましたが、ツールバーにボタンを表示させることはできませんでした。

他に簡単な方法はないだろうかと探して、「syntax highlighter」と「syntaxhighlighter insert」モジュールで実現できそうだったのでインストールしてみました。
「syntax highlighter」モジュールには別途「Syntaxhighlighter 3.0.83」が必要です。http://alexgorbatchev.com/SyntaxHighlighter/download/download.php?sh_currentからダウンロードできます。
 

インストール

今回インストールしたのは以下のモジュールとライブラリです。
 

syntaxhighlighterモジュール syntaxhighlighter-7.x-2.0
syntaxhighlighter insertモジュール syntaxhighlighter_insert-7.x-1.1
sintaxhighlighterライブラリ Syntaxhighlighter 3.0.83

 

モジュールのダウンロード

モジュールはそれぞれ、通常のモジュールと同じ方法でアップロードマネージャを使ってインストール(ダウンロード)します。
 

Syntaxhighlighterライブラリの配置

次にダウンロードしたモジュールをEnableにする前に「Syntaxhighlighterライブラリ」をダウンロードし、「sites/all/libraries」に展開します。
この時、「sites/all/libraries/syntaxhighlighter_3.0.83/scripts」となるよに配置します。
 

モジュールの有効化

ライブラリの配置が終わったら、各モジュールをEnableにします。
Syntaxhighlighter Insertはサブモジュールが存在しますが、とりあえず、Syntaxhighlighter InsertとSyntaxhighlighter Insert WYSIWYGをEnableにすれば良いようです。
 

Syntaxhighlighterモジュールの権限の設定

あとは、Syntaxhighlighterの権限を適切に設定してください。
※作業しているユーザに権限を付与しないと、「admin/config/content/syntaxhighlighter」へアクセスできません。
 

Syntaxhighlighterモジュールの設定

次に、「ホーム」→「管理」→「環境設定」→「コンテンツ作成」の画面で「syntaxhighlighter」を選択すれば、Syntaxhighlighterのダイアログ画面の設定などが編集できます。
 

Wysiwyg Profilesの設定

最後に、「ホーム」→「管理」→「環境設定」→「コンテンツ作成」の画面で「Wysiwyg profiles」を選択し、当該テキストフォーマットの編集をクリックし、「BUTTONS AND PLUGINS」の画面で「Insert syntaxhighlighter tag」にチェックすれば、ツールバーに表示されます。

以下は、使用した結果です。「ckeditor_custom」モジュールの例です。

<?php

/**
 * @file ckeditor_custom.module
 *
 * Includes tweaks to ckeditor that can't be performed through config.
 */

/**
 * Implements hook_wysiwyg_editor_settings_alter()
 */
function ckeditor_custom_wysiwyg_editor_settings_alter(&$settings, $context) {

  // The $context variable contains information about the wysiwyg profile we're using
  // In this case we just need to check that the editor being used is ckeditor
  if ($context['profile']->editor == 'ckeditor') {

    // Specify the custom config file that defines our font styles
    $settings['customConfig'] = base_path() . drupal_get_path('module', 'ckeditor_custom') .
                                '/ckeditor_custom_config.js';

    // We are also going to specify a custom body id and class
    $settings['bodyId'] = 'ckeditor_custom_id';
    $settings['bodyClass'] = 'ckeditor_custom_class';

    // Make sure the toolbar is there
    if (!empty($settings['toolbar'])) {

      // These are our desired groupings. Buttons that aren't listed here will be
      // Grouped in one big group at the end
      $preferred_groupings[] = array('Source');
      $preferred_groupings[] = array('Bold', 'Italic', 'Underline', 'Strike');
      $preferred_groupings[] = array('JustifyLeft', 'JustifyCenter',
                                     'JustifyRight', 'JustifyBlock');
      $preferred_groupings[] = array('BulletedList', 'NumberedList', 'Outdent', 'Indent');
      $preferred_groupings[] = array('Undo', 'Redo');
      $preferred_groupings[] = array('Image', 'Link', 'Unlink', 'Anchor', '-');
      $preferred_groupings[] = array('TextColor', 'BGColor');
      $preferred_groupings[] = array('Superscript', 'Subscript', 'Blockquote');
      $preferred_groupings[] = array('HorizontalRule', 'break');
      $preferred_groupings[] = array('Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord');
      $preferred_groupings[] = array('ShowBlocks', 'RemoveFormat', 'SpecialChar', '/');
      $preferred_groupings[] = array('Format', 'Font', 'FontSize', 'Styles', 'Table');
      $preferred_groupings[] = array('SelectAll', 'Find', 'Replace');
      $preferred_groupings[] = array('Flash', 'Smiley');
      $preferred_groupings[] = array('CreateDiv', 'Maximize', 'SpellChecker', 'Scayt');

      // An array to hold our newly grouped buttons
      $new_grouped_toolbar = array();

      // Compare each desired groupings to the configured buttons in the toolbar
      // and add them if they are there
      foreach($preferred_groupings as $button_group){

        // array_intersect() compares two arrays and returns an array of values
        // That are present in both arrays.
        $matching_buttons = array_intersect($button_group, $settings['toolbar'][0]);

        if (!empty($matching_buttons)) {
          // If there are matching buttons, we add it as an array to our
          // $new_grouped_toolbar. We run $matching_buttons through array_values()
          // to reset the array keys back to starting from 0.
          $new_grouped_toolbar[] = array_values($matching_buttons);
        }

      }

      // For extra safety, we're going to find any remaining buttons that we
      // missed. To do this we need to flatten our grouped buttons and compare
      // that against the original toolbar to see if we missed anything
      $new_flattened_toolbar = array();

      // Flatten our grouped buttons
      foreach ($new_grouped_toolbar as $key => $group) {
        $new_flattened_toolbar = array_merge($new_flattened_toolbar, $group);
      }

      // Array diff returns the keys that are present in the first argument, but
      // not not present in the second
      $remaining_buttons = array_diff($settings['toolbar'][0], $new_flattened_toolbar);

      if (!empty($remaining_buttons)) {
        // reset the array keys and add it to the $new_grouped_toolbar
        $new_grouped_toolbar[] = array_values($remaining_buttons);
      }

      // Replace the toolbar with our new, grouped toolbar.
      $settings['toolbar'] = $new_grouped_toolbar;

    }
  }
}

このckeditor_custom.moduleファイルでツールバーボタンのグループと表示順序を設定しています。
また、ckeditorのカスタム設定として「ckeditor_custom_config.js」を読み込むようになっています。

以下が「ckeditor_custom_config.js」に記述している内容です。

/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.editorConfig = function( config )
{
  // config.styleSet is an array of objects that define each style available
  // in the font styles tool in the ckeditor toolbar
  config.stylesSet =
  [
        /* Block Styles */

        // Each style is an object whose properties define how it is displayed
        // in the dropdown, as well as what it outputs as html into the editor
        // text area.
        { name : 'Paragraph'   , element : 'p' },
        { name : 'Heading 2'   , element : 'h2' },
        { name : 'Heading 3'   , element : 'h3' },
        { name : 'Heading 4'   , element : 'h4' },
        { name : 'Float Right', element : 'div', attributes : { 'style' : 'float:right;' } },
        { name : 'Float Left', element : 'div', attributes : { 'style' : 'float:left;' } },
        { name : 'Preformatted Text', element : 'pre' },
  ];
  config.scayt_autoStartup =false;
  config.enterMode = CKEDITOR.ENTER_BR;
  config.shiftEnterMode = CKEDITOR.ENTER_P;
}

上記はスタイルブロックのカスタマイズと自動スペルチェックの無効化、さらに、EnterとShift+Enterを押した際の挿入されるタグを入れ替えています。

このファイルにツールバーの設定を記述してもできそうです。
 

補足

ツールバーに表示されるボタンの順序は、ckeditor_custom.moduleに含まれているボタンが先にツールバーに表示され、それに含まれていないWysiwyg Profileで有効にしたボタンがそのあとに表示されるようです。
なお、Wysiwyg Profileで無効にしたボタンは表示されないはずです。
CKEditor 4.Xを使用するとツールバーにWYSIWYG Fieldのボタンの画像が表示されませんが、マウスを合わせると「Image」と表示される箇所があります。
ボタンの画像が表示されないだけで機能は動作します。
あと記事を保存するとWYSIWYG Fieldのタグが変換され埋め込まれます。さらにFileFieldの内容が消去されてしまうようで、ボタンの表示の件についてもCKEditor 3.xに変更すると改善しました。

Drupalバージョン

Drupal 7.x