WordPress 3.9 TinyMCE 4 自定义短代码失效修复
2025-03-03 13:48:07
WordPress 3.9 TinyMCE 4 可视化编辑器中自定义短代码失效的解决办法
升级到 WordPress 3.9 后,以前在 TinyMCE 编辑器中用来显示自定义短代码的下拉列表不见了。原来 functions 文件里的代码,还有 Javascript 文件里的代码都需要改。
问题原因
WordPress 3.9 版本对 TinyMCE 编辑器进行了重大升级,升级到了 TinyMCE 4。这次升级改变了编辑器 API 的调用方式,导致原先用于创建自定义下拉菜单的代码不再有效。 主要原因是 TinyMCE 4 不再支持 createListBox
方法。
解决方案
要让自定义短代码下拉菜单重新工作,我们需要对代码做一些修改,主要是替换旧的 TinyMCE API 并适配新的API:
方案一: 使用 addCommand
和 addMenuItem
(推荐)
这种方法更符合 TinyMCE 4 的 API 设计,也更简洁。
-
修改
functions.php
(可选) :原来的
functions.php
文件中的代码基本不需要改变,能继续使用。为让代码更加规范,可以将函数名改成更具有性的名称。例如:function register_kleen_shortcodes_dropdown( $buttons ) { array_push( $buttons, "kleen_shortcodes" ); // 使用更具性的按钮 ID return $buttons; } function add_kleen_shortcodes_dropdown( $plugin_array ) { $plugin_array['kleen_shortcodes'] = get_template_directory_uri() . '/js/mybuttons.js'; // 使用更具描述性的插件 ID return $plugin_array; } function kleen_shortcodes_dropdown() { if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) { return; } if ( get_user_option('rich_editing') == 'true' ) { add_filter( 'mce_external_plugins', 'add_kleen_shortcodes_dropdown' ); add_filter( 'mce_buttons', 'register_kleen_shortcodes_dropdown' ); } } add_action('init', 'kleen_shortcodes_dropdown');
-
修改
mybuttons.js
:这是主要需要修改的地方。我们需要使用
addCommand
来插入短代码,使用addMenuItem
来创建下拉菜单项。(function() { tinymce.PluginManager.add('kleen_shortcodes', function( editor, url ) { // 与 functions.php 中的插件 ID 对应 var shortcodes = { 'Tabs Wrapper': '[tabs_wrap][/tabs_wrap]', 'Tab Content': '[tab_content title=""][/tab_content]', 'Accordion Wrapper': '[accordion_wrap][/accordion_wrap]', 'Accordion Content': '[accordion_content title=""][/accordion_content]', 'Button Link': '[button_link][/button_link]', 'Column 1/2': '[one_half][/one_half]', 'Column 1/2 Last': '[one_half_last][/one_half_last]', 'Column 1/3': '[one_third][/one_third]', 'Column 1/3 Last': '[one_third_last][/one_third_last]', 'Column 1/4': '[one_fourth][/one_fourth]', 'Column 1/4 Last': '[one_fourth_last][/one_fourth_last]', 'Column 1/2 Center': '[one_half_center][/one_half_center]', 'Column 1/2 Center Last': '[one_half_center_last][/one_half_center_last]', 'Column 1/3 Center': '[one_third_center][/one_third_center]', 'Column 1/3 Center Last': '[one_third_center_last][/one_third_center_last]', 'Column 1/4 Center': '[one_fourth_center][/one_fourth_center]', 'Column 1/4 Center Last': '[one_fourth_center_last][/one_fourth_center_last]', 'Column 3/4': '[three_fourth][/three_fourth]', 'Column 3/4 Last': '[three_fourth_last][/three_fourth_last]', 'Column 2/3': '[two_third][/two_third]', 'Column 2/3 Last': '[two_third_last][/two_third_last]', 'Highlight Text': '[highlight][/highlight]', 'Blockquote': '[blockquote][/blockquote]', 'Recent Post': '[post_recent posts="2"]', 'Recent Sermons': '[recent_sermons posts="2"]', 'Staff List': '[staff_category posts="4" staff_category=""]', 'Check List': '[check_list][/check_list]', 'Times List': '[times_list][/times_list]', 'Arrow List': '[arrow_list][/arrow_list]', 'Horizontal Rule Center': '[horizontal_rule_center][/horizontal_rule_center]' }; // 添加菜单按钮 editor.addButton( 'kleen_shortcodes', { //和 mce_buttons 数组内的按钮 id 对应 type: 'menubutton', // 改成 menubutton text: 'Kleen Shortcodes', // 菜单显示的文字 icon: false, // 可以设置一个图标,也可以不设置 menu: Object.keys(shortcodes).map(function(key) { // 遍历生成菜单项 return { text: key, //每个下拉的文本 onclick: function() { var content = shortcodes[key]; // 使用更简洁的 insertContent 插入短代码 editor.insertContent(content); } }; }) }); }); })();
tinymce.PluginManager.add
: 第一个参数'kleen_shortcodes'
应该与functions.php
中add_kleen_shortcodes_dropdown
函数里设置的插件 ID 一致。editor.addButton
: 创建一个菜单按钮(menubutton
)。menu
: 这个属性定义了下拉菜单中的项目。 使用Object.keys(shortcodes).map
循环生成菜单项。onclick
: 直接使用editor.insertContent(content)
插入对应短代码, 代码简洁了不少。
方案二: 使用 addButton
和 type: 'listbox'
(不推荐, 但可以作为旧代码升级参考)
如果想尽可能保留原来的 JavaScript 代码结构, 那么这种方案修改幅度最小。 但需要注意的是, 官方文档不再建议使用listbox
。
-
functions.php
: 与方案一相同, 可以选择性修改。 -
mybuttons.js
:(function() { tinymce.PluginManager.add('kleen_shortcodes', function( editor, url ) { var shortcodes = { 'Tabs Wrapper': '[tabs_wrap][/tabs_wrap]', 'Tab Content': '[tab_content title=""][/tab_content]', 'Accordion Wrapper': '[accordion_wrap][/accordion_wrap]', 'Accordion Content': '[accordion_content title=""][/accordion_content]', 'Button Link': '[button_link][/button_link]', 'Column 1/2': '[one_half][/one_half]', 'Column 1/2 Last': '[one_half_last][/one_half_last]', 'Column 1/3': '[one_third][/one_third]', 'Column 1/3 Last': '[one_third_last][/one_third_last]', 'Column 1/4': '[one_fourth][/one_fourth]', 'Column 1/4 Last': '[one_fourth_last][/one_fourth_last]', 'Column 1/2 Center': '[one_half_center][/one_half_center]', 'Column 1/2 Center Last': '[one_half_center_last][/one_half_center_last]', 'Column 1/3 Center': '[one_third_center][/one_third_center]', 'Column 1/3 Center Last': '[one_third_center_last][/one_third_center_last]', 'Column 1/4 Center': '[one_fourth_center][/one_fourth_center]', 'Column 1/4 Center Last': '[one_fourth_center_last][/one_fourth_center_last]', 'Column 3/4': '[three_fourth][/three_fourth]', 'Column 3/4 Last': '[three_fourth_last][/three_fourth_last]', 'Column 2/3': '[two_third][/two_third]', 'Column 2/3 Last': '[two_third_last][/two_third_last]', 'Highlight Text': '[highlight][/highlight]', 'Blockquote': '[blockquote][/blockquote]', 'Recent Post': '[post_recent posts="2"]', 'Recent Sermons': '[recent_sermons posts="2"]', 'Staff List': '[staff_category posts="4" staff_category=""]', 'Check List': '[check_list][/check_list]', 'Times List': '[times_list][/times_list]', 'Arrow List': '[arrow_list][/arrow_list]', 'Horizontal Rule Center': '[horizontal_rule_center][/horizontal_rule_center]' }; editor.addButton('kleen_shortcodes', { type: 'listbox', // 虽然不推荐,但为了兼容,这里保留 text: 'Kleen Shortcodes', icon: false, fixedWidth: true, // 让宽度固定 onselect: function(e) { // 当选择某个选项 var selectedValue = this.value(); if (selectedValue) { //值存在 var content = shortcodes[selectedValue]; editor.insertContent(content); //使用 insertContent 插入 } }, values: Object.keys(shortcodes).map(function(key) { //生成选项 return {text: key, value: key}; }) }); }); })();
- 删除了
createControl
。 - 修改
tinymce.create
为tinymce.PluginManager.add
,参数和上面一致。 - 使用
editor.addButton
注册按钮, 使用type: 'listbox'
来创建一个列表框. - 通过
values
属性配置下拉列表的选项,把文本和值设置成一致. - 使用
onselect
事件来插入短代码,this.value()
可以获取选中的值.
安全建议
无论采用哪种方案,都建议:
- 备份: 在修改任何代码之前,请务必备份你的
functions.php
和mybuttons.js
文件。 - 测试: 修改完成后,请彻底测试所有短代码,确保它们在 WordPress 编辑器中能正常工作。
进阶使用技巧
- 增加图标
可以在addButton
中设置icon
属性, 从而为按钮增加图标。 首先在主题文件夹的images
这类目录下放入一个你希望的 icon, 命名为shortcode-icon.png
(或者其他你希望的文件名),然后在addButton
设置,例如:
editor.addButton( 'kleen_shortcodes', { //和 mce_buttons 数组内的按钮 id 对应
type: 'menubutton',
text: 'Kleen Shortcodes',
icon: 'shortcode-icon', //引入图标,不需要写完整路径和文件后缀名
image: url + '/../images/shortcode-icon.png', // 使用绝对路径,确保图标能找到, url 指向 js 文件的路径,所以这里需要用 ../images/ 找到图片
menu: // 保持不变
...
icon
使用的是 TinyMCE 内置的图标名称。如果想使用自定义的图标,则设置image
参数即可.
2. 分组菜单
如果短代码非常多,可以给他们进行分组,让菜单更整洁。 例如:
editor.addButton( 'kleen_shortcodes', {
type: 'menubutton',
text: 'Kleen Shortcodes',
icon: false,
menu: [
{
text: '布局', // 一级菜单
menu: [ //二级菜单
{text: 'Column 1/2', onclick: function() { editor.insertContent('[one_half][/one_half]'); }},
{text: 'Column 1/2 Last', onclick: function() { editor.insertContent('[one_half_last][/one_half_last]'); }},
// 其他布局短代码...
]
},
{
text: '内容',
menu: [
{text: 'Tabs Wrapper', onclick: function() { editor.insertContent('[tabs_wrap][/tabs_wrap]'); }},
{text: 'Tab Content', onclick: function() { editor.insertContent('[tab_content title=""][/tab_content]'); }},
// 其他内容短代码
]
},
//其他分组
]
});
通过以上步骤,就能完美解决 WordPress 3.9 版本 TinyMCE 编辑器中自定义短代码下拉菜单失效的问题, 使短代码功能重新工作。