В продолжение темы того, что решил пользоваться преимущественно Визуальным редактором (хочется простоты и наглядности), нашел плагин SyntaxHighlighter TinyMCE Button версии 0.7.8.4 от 2011-12-24.
Плагин успешно добавляет кнопки "pre" и "code" на панель Визуального редактора WordPress. Меня в частности интересовала только кнопка code, чтобы не вводить постоянно самостоятельно квадратные скобки []
и вспоминать имена настроек плагина SyntaxHighlighter Evolved.
В итоге, вместо желаемых квадратных скобок, после использования кнопки "code" вставлялся тег <pre>
, что меня абсолютно не устраивало.
Пришлось искать в исходниках где выводится код. Причем в настройках SyntaxHighlighter TinyMCE Button был выбран именно SyntaxHighlighter Evolved. Более того, после нажатия на кнопку "code" выдавалось предупреждение "Load All Brushes" или по-русски - загрузить все языковые файлы подсветки синтаксиса.
Моя версия WordPress для истории: 3.3.2.
Все файлы, которые я переделал находятся в следующей папке:
/wp-content/plugins/syntaxhighlighter-tinymce-button/sh-tinymce-button-box
Сначала я исправил файл window.php. Он отвечает за вывод появляющегося окна после нажатия на кнопку "code". Удалил многократную загрузки параметров через get_option
и добавил новые кнопки:
- toolbar
- autolinks
- collapse
- light
Как видно самое необходимое. Хотя уверен, что буду использовать только "collapse".
Для дальнейшей проверки я также добавил скрытые значения формы с параметрами по-умолчанию, заданными в настройках SyntaxHighlighter Evolved.
Файл window.php
<?php
//Load bootstrap file
require_once( dirname( dirname(__FILE__) ) .'/sh-tinymce-button-bootstrap.php');
global $wpdb;
//Check for rights
if ( !is_user_logged_in() || !current_user_can('edit_posts') )
wp_die(__("You are not allowed to access this file.", "shtb_adv_lang"));
$shtb_box_url = plugin_dir_url( __FILE__ );
$shtb_adv_setting_opt = get_option('shtb_adv_setting_opt');
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SHTB CodeBox</title>
<!-- <meta http-equiv="Content-Type" content="<?php// bloginfo('html_type'); ?>; charset=<?php //echo get_option('blog_charset'); ?>" /> -->
<script language="javascript" type="text/javascript" src="<?php echo get_option('siteurl'); ?>/wp-includes/js/tinymce/tiny_mce_popup.js"></script>
<script language="javascript" type="text/javascript" src="<?php echo get_option('siteurl'); ?>/wp-includes/js/tinymce/utils/form_utils.js"></script>
<script language="javascript" type="text/javascript" src="<?php echo $shtb_box_url; ?>tinymce.js?ver=0.7.8.1"></script>
<base target="_self" />
</head>
<body id="link" onLoad="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('shtb_adv_codebox_code').focus();" style="display: none">
<?php
$syntaxhighlighter_settings = get_option('syntaxhighlighter_settings');
/* cay 1
if ($shtb_adv_setting_opt['using_syntaxhighlighter'] == 'syntaxhighlighter_evolved' && function_exists('SyntaxHighlighter') && $syntaxhighlighter_settings['loadallbrushes'] == 0) {
_e("<div style=\"margin-bottom:5px\">WARNING!: \"Load All Brushes\" option must be enabled on the \"SyntaxHighlighter\" setting panel.</div>", "shtb_adv_lang");
}
*/
?>
<!-- <form onsubmit="insertLink();return false;" action="#"> -->
<form name="shtb_adv_codebox" action="#">
<table border="0" cellpadding="4" cellspacing="0">
<tr>
<td nowrap="nowrap"><label for="shtb_adv_codebox_language">
<?php _e("Select language", "shtb_adv_lang"); ?>
</label></td>
<td><select id="shtb_adv_codebox_language" name="shtb_adv_codebox_language">
<?php
/* cay 2
if ($shtb_adv_setting_opt['using_syntaxhighlighter'] == 'wp_syntaxhighlighter' && function_exists('wp_sh_register_menu_item') && is_array(get_option('wp_sh_language3')) && is_array(get_option('wp_sh_language2'))) {
$wp_sh_setting_opt = get_option('wp_sh_setting_opt');
if ($wp_sh_setting_opt) {
$wp_sh_version = $wp_sh_setting_opt['lib_version'];
} else {
$wp_sh_version = get_option('wp_sh_version');
}
if ($wp_sh_version == '3.0') {
$shtb_adv_language = get_option('wp_sh_language3');
} elseif ($wp_sh_version == '2.1') {
$shtb_adv_language = get_option('wp_sh_language2');
}
if (is_array($shtb_adv_language)) {
asort($shtb_adv_language);
echo "\n";
foreach ($shtb_adv_language as $key => $val) {
if ($val[1] == 'true' || $val[1] =='added') {
echo ' <option value="'.$key.'">'.$val[0]."</option>\n";
}
}
echo "\n";
}
} else {
*/
$shtb_adv_language = get_option('shtb_adv_languages');
if (is_array($shtb_adv_language)) {
asort($shtb_adv_language);
echo "\n";
foreach ($shtb_adv_language as $key => $val) {
if ($val[1] == 'true' || $val[1] =='added') {
echo ' <option value="'.$key.'">'.$val[0]."</option>\n";
}
}
echo "\n";
}
/* cay 3 } */
?>
</select>
</td>
</tr>
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_linenumbers">
<?php _e("Display line numbers", "shtb_adv_lang"); ?>
</label></td>
<?php
/* cay 4
if ($shtb_adv_setting_opt['using_syntaxhighlighter'] == 'wp_syntaxhighlighter' && function_exists('wp_sh_register_menu_item')) {
$wp_sh_setting_opt = get_option('wp_sh_setting_opt');
if (is_array($wp_sh_setting_opt)) {
if ($wp_sh_setting_opt['gutter'] == "false") {
$shtb_adv_codebox_linenumbers_check = ' ';
} else {
$shtb_adv_codebox_linenumbers_check = 'checked="checked" ';
}
} elseif (get_option('wp_sh_gutter') == 0) {
$shtb_adv_codebox_linenumbers_check = ' ';
} else {
$shtb_adv_codebox_linenumbers_check = 'checked="checked" ';
}
} elseif ($shtb_adv_setting_opt['using_syntaxhighlighter'] == 'syntax_highlighter_compress' && function_exists('shc_install')) {
$shc_opt = get_option('shc_opt');
if ($shc_opt[shc_gutter] == 0) {
$shtb_adv_codebox_linenumbers_check = ' ';
} else {
$shtb_adv_codebox_linenumbers_check = 'checked="checked" ';
}
} elseif ($shtb_adv_setting_opt['using_syntaxhighlighter'] == 'syntaxhighlighter_evolved' && function_exists('SyntaxHighlighter')) {
$syntaxhighlighter_settings = get_option('syntaxhighlighter_settings');
*/
if ($syntaxhighlighter_settings['gutter'] == 0) {
$shtb_adv_codebox_linenumbers_check = '';
$shtb_adv_codebox_linenumbers_default = '0';
} else {
$shtb_adv_codebox_linenumbers_check = 'checked="checked"';
$shtb_adv_codebox_linenumbers_default = '1';
}
/* cay 5
} else {
if ($shtb_adv_setting_opt['gutter'] == "0") {
$shtb_adv_codebox_linenumbers_check = ' ';
} else {
$shtb_adv_codebox_linenumbers_check = 'checked="checked" ';
}
}
*/
?>
<td><input name="shtb_adv_codebox_linenumbers" id="shtb_adv_codebox_linenumbers" type="checkbox"<?php echo $shtb_adv_codebox_linenumbers_check; ?> />
<input name="shtb_adv_codebox_linenumbers_default" id="shtb_adv_codebox_linenumbers_default" type="hidden" value="<?php echo $shtb_adv_codebox_linenumbers_default; ?>" /></td>
</tr>
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_starting_linenumber">
<?php _e("Starting line number", "shtb_adv_lang"); ?>
</label></td>
<?php
/* cay 6
if ($shtb_adv_setting_opt['using_syntaxhighlighter'] == 'wp_syntaxhighlighter' && function_exists('wp_sh_register_menu_item')) {
$wp_sh_setting_opt = get_option('wp_sh_setting_opt');
if (is_array($wp_sh_setting_opt)) {
if ($wp_sh_setting_opt['gutter'] == "ture" || get_option('wp_sh_gutter') == 1) {
$shtb_adv_codebox_starting_linenumber_value = $wp_sh_setting_opt['first_line'];
} else {
$shtb_adv_codebox_starting_linenumber_value = $shtb_adv_setting_opt['first_line'];
}
} else {
$shtb_adv_codebox_starting_linenumber_value = $shtb_adv_setting_opt['first_line'];
if (!preg_match("/^[0-9]+$/", $shtb_adv_codebox_starting_linenumber_value)) {
$shtb_adv_codebox_starting_linenumber_value = "1";
}
}
} elseif ($shtb_adv_setting_opt['using_syntaxhighlighter'] == 'syntaxhighlighter_evolved' && function_exists('SyntaxHighlighter')) {
$syntaxhighlighter_settings = get_option('syntaxhighlighter_settings');
*/
$shtb_adv_codebox_starting_linenumber_default = $syntaxhighlighter_settings['firstline'];
if ($syntaxhighlighter_settings['gutter'] == 1) {
$shtb_adv_codebox_starting_linenumber_value = $syntaxhighlighter_settings['firstline'];
} else {
$shtb_adv_codebox_starting_linenumber_value = $shtb_adv_setting_opt['first_line'];
}
/* cay 7
} else {
$shtb_adv_codebox_starting_linenumber_value = $shtb_adv_setting_opt['first_line'];
}
*/
?>
<td><input name="shtb_adv_codebox_starting_linenumber" id='shtb_adv_codebox_starting_linenumber' type="text" value="<?php echo $shtb_adv_codebox_starting_linenumber_value; ?>" />
<input name="shtb_adv_codebox_starting_linenumber_default" id="shtb_adv_codebox_starting_linenumber_default" type="hidden" value="<?php echo $shtb_adv_codebox_starting_linenumber_default; ?>" /></td>
</tr>
<!-- cay 1 -->
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_toolbar">
<?php _e("Display the toolbar", "shtb_adv_lang"); ?>
</label></td>
<?php
if ($syntaxhighlighter_settings['toolbar'] == "0") {
$shtb_adv_codebox_toolbar_check = '';
$shtb_adv_codebox_toolbar_default = '0';
} else {
$shtb_adv_codebox_toolbar_check = 'checked="checked"';
$shtb_adv_codebox_toolbar_default = '1';
}
?>
<td><input name="shtb_adv_codebox_toolbar" id='shtb_adv_codebox_toolbar' type="checkbox"<?php echo $shtb_adv_codebox_toolbar_check; ?> />
<input name="shtb_adv_codebox_toolbar_default" id="shtb_adv_codebox_toolbar_default" type="hidden" value="<?php echo $shtb_adv_codebox_toolbar_default; ?>" /></td>
</tr>
<!-- cay 2 -->
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_autolinks">
<?php _e("Automatically make URLs clickable", "shtb_adv_lang"); ?>
</label></td>
<?php
if ($syntaxhighlighter_settings['autolinks'] == "0") {
$shtb_adv_codebox_autolinks_check = '';
$shtb_adv_codebox_autolinks_default = '0';
} else {
$shtb_adv_codebox_autolinks_check = 'checked="checked"';
$shtb_adv_codebox_autolinks_default = '1';
}
?>
<td><input name="shtb_adv_codebox_autolinks" id='shtb_adv_codebox_autolinks' type="checkbox"<?php echo $shtb_adv_codebox_autolinks_check; ?> />
<input name="shtb_adv_codebox_autolinks_default" id="shtb_adv_codebox_autolinks_default" type="hidden" value="<?php echo $shtb_adv_codebox_autolinks_default; ?>" /></td>
</tr>
<!-- cay 3 -->
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_collapse">
<?php _e("Collapse code boxes", "shtb_adv_lang"); ?>
</label></td>
<?php
if ($syntaxhighlighter_settings['collapse'] == "0") {
$shtb_adv_codebox_collapse_check = '';
$shtb_adv_codebox_collapse_default = '0';
} else {
$shtb_adv_codebox_collapse_check = 'checked="checked"';
$shtb_adv_codebox_collapse_default = '1';
}
?>
<td><input name="shtb_adv_codebox_collapse" id='shtb_adv_codebox_collapse' type="checkbox"<?php echo $shtb_adv_codebox_collapse_check; ?> />
<input name="shtb_adv_codebox_collapse_default" id="shtb_adv_codebox_collapse_default" type="hidden" value="<?php echo $shtb_adv_codebox_collapse_default; ?>" /></td>
</tr>
<!-- cay 4 -->
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_light">
<?php _e("One line mode", "shtb_adv_lang"); ?>
</label></td>
<?php
if ($syntaxhighlighter_settings['light'] == "0") {
$shtb_adv_codebox_light_check = '';
$shtb_adv_codebox_light_default = '0';
} else {
$shtb_adv_codebox_light_check = 'checked="checked"';
$shtb_adv_codebox_light_default = '1';
}
?>
<td><input name="shtb_adv_codebox_light" id='shtb_adv_codebox_light' type="checkbox"<?php echo $shtb_adv_codebox_light_check; ?> />
<input name="shtb_adv_codebox_light_default" id="shtb_adv_codebox_light_default" type="hidden" value="<?php echo $shtb_adv_codebox_light_default; ?>" /></td>
</tr>
<!-- cay # -->
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_highlighted_lines">
<?php _e("Highlighted Lines", "shtb_adv_lang"); ?>
</label></td>
<td><input name="shtb_adv_codebox_highlighted_lines" id='shtb_adv_codebox_highlighted_lines' type="text" />
<br />
<?php _e("Example: 2,5-10,12", "shtb_adv_lang"); ?></td>
</tr>
<tr>
<td nowrap="nowrap" valign="top"><label for="shtb_adv_codebox_html_script">
<?php _e("HTML script", "shtb_adv_lang"); ?>
</label></td>
<?php
if ($shtb_adv_setting_opt['html_script'] == "0") {
$shtb_adv_codebox_html_script_check = '';
/* cay 7 */
$shtb_adv_codebox_html_script_default = '0';
} else {
$shtb_adv_codebox_html_script_check = 'checked="checked"';
/* cay 8 */
$shtb_adv_codebox_html_script_default = '1';
}
?>
<td><input name="shtb_adv_codebox_html_script" id='shtb_adv_codebox_html_script' type="checkbox"<?php echo $shtb_adv_codebox_html_script_check; ?> />
<input name="shtb_adv_codebox_html_script_default" id="shtb_adv_codebox_html_script_default" type="hidden" value="<?php echo $shtb_adv_codebox_html_script_default; ?>" /></td>
</tr>
<tr>
<td nowrap="nowrap" valign="top" colspan="2"><label for="shtb_adv_codebox_code">
<?php _e("Your Code:", "shtb_adv_lang"); ?>
</label>
<br />
<textarea id="shtb_adv_codebox_code" name="shtb_adv_codebox_code" style="width: 340px; height: 110px" /></textarea>
</td>
</tr>
</table>
<div class="mceActionPanel">
<div style="float: left">
<input type="submit" id="insert" name="insert" value="<?php _e("Insert", "shtb_adv_lang"); ?>" onClick="insertSHTBADVCODEBOXcode();" />
</div>
<div style="float: right">
<input type="button" id="cancel" name="cancel" value="<?php _e("Cancel", "shtb_adv_lang"); ?>" onClick="tinyMCEPopup.close();" />
</div>
</div>
</form>
</body>
</html>
Данная строка:
$shtb_adv_setting_opt = get_option('shtb_adv_setting_opt');
Возвращает следующий массив с параметрами:
Array (
[using_syntaxhighlighter] => syntaxhighlighter_evolved
[insert] => 1
[codebox] => 1
[button_window_size] => 100
[button_row] => 1
[gutter] => 1
[first_line] => 1
[html_script] => 0 )
Следующая строка:
$syntaxhighlighter_settings = get_option('syntaxhighlighter_settings');
Возвращает данный массив:
Array (
[shversion] => 2
[theme] => default
[gutter] => 1
[toolbar] => 1
[autolinks] => 1
[smarttabs] => 1
[wraplines] => 1
[classname] =>
[firstline] => 1
[padlinenumbers] => false
[tabsize] => 4
[title] =>
[loadallbrushes] => 0
[collapse] => 0
[light] => 0 )
Именно эти массивы я и использовал, чтобы добавить новые поля в форму.
После этого я перешел к редактированию файла tinymce.js
.
Сначала заменил вывод тега <pre>
, но стал писать эту запись и понял, что удаляются символы сдвига "tab" и решил вернуть. Также в настройках SyntaxHighlighter Evolved включил все-таки следующий параметр:
- Always load all language files (for directly using
<pre>
tags rather than shortcodes)
Добавил переменные, в которые записал значения параметров по-умолчанию, исправил функции сравнения.
Могу сейчас уже что-то упустить, поэтому лучше смотреть исходник.
Файл tinymce.js
function init() {
tinyMCEPopup.resizeToInnerSize();
}
function getCheckedValue(radioObj) {
if(!radioObj)
return "";
var radioLength = radioObj.length;
if(radioLength == undefined)
if(radioObj.checked)
return radioObj.value;
else
return "";
for(var i = 0; i < radioLength; i++) {
if(radioObj[i].checked) {
return radioObj[i].value;
}
}
return "";
}
function insertSHTBADVCODEBOXcode() {
var langname_ddb = document.getElementById('shtb_adv_codebox_language');
var langname = langname_ddb.value;
var linenumbers = document.getElementById('shtb_adv_codebox_linenumbers').checked;
var starting_linenumber = document.getElementById('shtb_adv_codebox_starting_linenumber').value;
var highlight_lines = document.getElementById('shtb_adv_codebox_highlighted_lines').value;
var html_script = document.getElementById('shtb_adv_codebox_html_script').checked;
/* cay 2 */
var linenumbers_def = document.getElementById('shtb_adv_codebox_linenumbers_default').value;
var starting_linenumber_def = document.getElementById('shtb_adv_codebox_starting_linenumber_default').value;
var html_script_def = document.getElementById('shtb_adv_codebox_html_script_default').value;
var toolbar = document.getElementById('shtb_adv_codebox_toolbar').checked;
var toolbar_def = document.getElementById('shtb_adv_codebox_toolbar_default').value;
var autolinks = document.getElementById('shtb_adv_codebox_autolinks').checked;
var autolinks_def = document.getElementById('shtb_adv_codebox_autolinks_default').value;
var collapse = document.getElementById('shtb_adv_codebox_collapse').checked;
var collapse_def = document.getElementById('shtb_adv_codebox_collapse_default').value;
var light = document.getElementById('shtb_adv_codebox_light').checked;
var light_def = document.getElementById('shtb_adv_codebox_light_default').value;
/* cay 2 # */
var code = document.getElementById('shtb_adv_codebox_code').value.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/</g,'<').replace(/\r\n/g,'<br />');
code = code.replace(/\n|\r/g,'<br />');
code = code.replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#039;');
/* cay 1 */
var tagtext = '<pre class="brush: ' + langname;
classAttribs = '';
if (linenumbers != linenumbers_def)
classAttribs += '; gutter: ' + linenumbers;
if (starting_linenumber != starting_linenumber_def)
classAttribs += '; firstline: ' + starting_linenumber;
if (highlight_lines != "") {
lines = '';
if (highlight_lines.indexOf(',') > -1 || highlight_lines.indexOf('-') > -1) {
var parts = highlight_lines.split(',');
var i, j;
var parts_length = parts.length;
for (i = 0; i < parts_length; ++i) {
if (i > 0) {
lines += ', ';
}
if (parts[i].indexOf('-') > -1) {
var items = parts[i].split('-');
var first = true;
for (j = parseInt(items[0]); j < parseInt(items[1]); ++j) {
if (i > 0 || first == false) {
lines += ', ';
}
lines += j;
if (first) {
first = false;
}
}
} else {
lines += parts[i];
}
}
} else {
lines = highlight_lines;
}
classAttribs += '; highlight: [' + lines + ']';
}
if (html_script != html_script_def)
classAttribs += '; htmlscript: ' + html_script;
if (toolbar != toolbar_def)
classAttribs += '; toolbar: ' + toolbar;
if (autolinks != autolinks_def)
classAttribs += '; autolinks: ' + autolinks;
if (collapse != collapse_def)
classAttribs += '; collapse: ' + collapse;
if (light != light_def)
classAttribs += '; light: ' + light;
if (highlight_lines != "" && highlight_lines.match(/[^,0-9]/)) {
alert("Please input a linenumber or comma-separated linenumbers to the 'Highlighted Lines' column");
return;
} else if (code == '') {
alert("Your code is empty");
} else {
tinyMCEPopup.editor.execCommand('mceInsertContent', false, tagtext+classAttribs+';">'+code+'</pre><br />');
}
/* cay 1 # */
/* cay 2
var tagtext = '<pre class="brush: ';
classAttribs = langname;
if (linenumbers)
classAttribs = classAttribs + '; gutter: true';
else
classAttribs = classAttribs + '; gutter: false';
if (starting_linenumber)
classAttribs = classAttribs + '; first-line: ' + starting_linenumber;
else
classAttribs = classAttribs;
if (highlight_lines)
classAttribs = classAttribs + '; highlight: [' + highlight_lines + ']';
else
classAttribs = classAttribs;
if (html_script)
classAttribs = classAttribs + '; html-script: true';
else
classAttribs = classAttribs;
if(starting_linenumber.match(/[^0-9]+/)){
alert("Please input number to the 'Starting Line Number' column");
return;
} else if(highlight_lines != "" && highlight_lines.match(/[^,0-9]/)){
alert("Please input a linenumber or comma-separated linenumbers to the 'Highlighted Lines' column");
return;
} else if (code == '') {
alert("Your code is empty");
} else {
tinyMCEPopup.editor.execCommand('mceInsertContent', false, tagtext+classAttribs+'">'+code+'</pre>');
}
*/
tinyMCEPopup.close();
return;
}
Я также добавил функцию, которая распознает дефис в номерах строк и составляет строку из чисел через запятую. Например, указываем в номерах строк "4-6", в коде будет "4, 5, 6". Мне показалось, что это удобно.
Теперь остался последний файл editor_plugin.js
(при 100% отображения в настройках), в котором я просто изменил высоту появляющегося окна после нажатия на кнопку "code":
ed.addCommand('shtb_adv_codebox_cmd', function() {
ed.windowManager.open({
file : url + '/window.php',
width : 364 + ed.getLang('shtb_adv_codebox.delta_width', 0),
/* cay 1 height : 430 + ed.getLang('shtb_adv_codebox.delta_height', 0), */
height : 420 + ed.getLang('shtb_adv_codebox.delta_height', 0), /* cay 2 */
inline : 1
}, {
plugin_url : url // Plugin absolute URL
});
});
Результат
Потратил несколько часов на все эти переделки и только ради того, чтобы мне было удобно. Не знаю, насколько это рациональная трата времени, но уверен, что 2-й раз над этой проблемой сидеть уже не буду.
Теперь код всегда отображается правильно, не важно сколько раз я переключусь между Визуальным и HTML редактором.