在WordPress后端的TinyMCE模式窗口中调用PHP函数

我正在使用为TinyMCE插件注册的静态.js文件。 单击新按钮,它会打开模态窗口,其中包含一个表单,用于生成短代码。 问题是我需要从PHP函数中填充一些表单字段。 我一直在看这篇文章几个小时,但没有找到一个可行的解决方案。 现在我的php函数是一个Shortcode,所以我需要将它改编为常规的旧函数。 但是最大的挑战是弄清楚如何安排这个,以便.js文件可以在表单中使用该函数。 这是基本的东西。 首先,.js文件的一些块:

(function(){ // creates the plugin tinymce.create('tinymce.plugins.myshortcode', { // creates control instances based on the control's id. createControl : function(id, controlManager) { if (id == 'myshortcode') { // creates the button var button = controlManager.createButton('myshortcode', { title : 'My Shortcode', // title of the button image : '../wp-content/plugins/my-shortcode/js/images/myshortcode.png', // path to the button's image onclick : function() { // triggers the thickbox var width = jQuery(window).width(), H = jQuery(window).height(), W = ( 720 < width ) ? 720 : width; W = W - 80; H = H - 80; tb_show( 'My Shortcode', '#TB_inline?width=' + W + '&height=' + H + '&inlineId=myshortcode-form' ); } }); return button; } return null; } }); // registers the plugin. tinymce.PluginManager.add('myshortcode', tinymce.plugins.myshortcode); jQuery(function(){ var form = jQuery(' \ \ The HTML Web Form all goes in here.\ \ '); var table = form.find('table'); form.appendTo('body').hide(); form.find('#myshortcode-submit').click(function(){ var options = { 'att1' : '', 'att2' : '', 'att3' : '', 'att4' : '', }; var shortcode = '[myshortcode'; for( var index in options) { var value = table.find('#myshortcode-' + index).val(); if ( value !== options[index] && value != null ) shortcode += ' ' + index + '="' + value + '"'; } shortcode += '] content here. [/myshortcode]'; tinyMCE.activeEditor.execCommand('mceInsertContent', 0, shortcode); tb_remove(); }); }); })() 

但是在那个地方,它说“HTML Web Form就在这里”,我需要有几个基于PHP函数生成的字段。 到目前为止我只写了两个中的一个,正如我所说,它目前被写为短代码,所以我需要改变它(不确定最好的方法来做到这一点,因为这里有其他重大问题)。 但这里是:

 add_shortcode('rolescapsdropdown', 'sc_rolescapsdropdown'); function sc_rolescapsdropdown($attr) { global $wp_roles; $all_roles = $wp_roles->roles; $editable_roles = apply_filters('editable_roles', $all_roles); $user = new WP_User( 1 ); $capslist = $user->allcaps; $dropdown = ''; foreach($editable_roles as $role=>$theroles){ $dropdown .= ''.$role.''; } foreach($capslist as $cap=>$caps){ if($cap !== 'administrator' && $cap !== 'level_0' && $cap !== 'level_1' && $cap !== 'level_2' && $cap !== 'level_3' && $cap !== 'level_4' && $cap !== 'level_5' && $cap !== 'level_6' && $cap !== 'level_7' && $cap !== 'level_8' && $cap !== 'level_9' && $cap !== 'level_10'){ $dropdown .= ''.$cap.''; } } $dropdown .= ''; return $dropdown; } 

我希望避免在这里学习Ajax。 但我尝试将.js文件设为.php文件并将JavaScript包装在标签中,但随后所有TinyMCE按钮都消失了,显然它不会让我使用.php文件来注册插件。

更新1

我有一个想法是尝试将Web表单移动到php文件,只需要注册TMCE插件的.js文件调用它,但我不知道这是否有效,也不知道如何获取。 js文件识别外部php文件中表单的存在。

更新2

根据ScottA的帮助,以下是我试图解决这个问题的方法:

我已将此添加到具有以下forms的静态.js文件中:

 $.get( "ajax/test.php", function( data ) { var options = data.options; for(row in options) { $("#option-list").append("" + options[row].name + ""); // debug for unexpected results console.log(data.options); } }, "json" ); 

我在名为“ajax”的子目录中创建了这个test.php文件:

 function rolescapsdropdown() { global $wp_roles; $all_roles = $wp_roles->roles; $editable_roles = apply_filters('editable_roles', $all_roles); $user = new WP_User( 1 ); $capslist = $user->allcaps; $all_options = $editable_roles . $capslist; $all_options[]['value'] = $value; $all_options[]['name'] = $name; echo json_encode( array('options' => $all_options) ); } 

我将此HTML添加到静态.js文件中的表单:

  

我得到的是一个空白的模态窗口。 当我包含$.get函数时,根本没有显示任何HTML。

更新3

仍然得到一个空白的模态窗口。 我将它转换回短代码以查看它输出的内容。 这个…

 add_shortcode('rolesdropdown', 'sc_rolesdropdown'); function sc_rolesdropdown() { global $wp_roles; $all_roles = $wp_roles->roles; $editable_roles = apply_filters('editable_roles', $all_roles); $user = new WP_User( 1 ); $capslist = $user->allcaps; foreach ($editable_roles as $role=>$theroles){ $all_options = $role; } foreach ($capslist as $cap=>$caps){ $all_options .= $cap; } echo json_encode( array('options' => $all_options) ); } 

在页面上输出:

{ “选项”: “trollswitch_themesedit_themesactivate_pluginsedit_pluginsedit_usersedit_filesmanage_optionsmoderate_commentsmanage_categoriesmanage_linksupload_filesimportunfiltered_htmledit_postsedit_others_postsedit_published_postspublish_postsedit_pagesreadlevel_10level_9level_8level_7level_6level_5level_4level_3level_2level_1level_0edit_others_pagesedit_published_pa​​gespublish_pagesdelete_pagesdelete_others_pagesdelete_published_pa​​gesdelete_postsdelete_others_postsdelete_published_postsdelete_private_postsedit_private_postsread_private_postsdelete_private_pagesedit_private_pagesread_private_pagesdelete_userscreate_usersunfiltered_uploadedit_dashboardupdate_pluginsdelete_pluginsinstall_pluginsupdate_themesinstall_themesupdate_corelist_usersremove_usersadd_userspromote_usersedit_theme_optionsdelete_themesexportbe_trollexec_phpedit_others_phpadministrator”}

但是当在后端的模态窗口中时,当$.get正在调用包含该函数的文件时,窗口只是空白。

我刚才有同样的问题,这就是我解决它的方法。 首先,我们需要将一些PHP值传递给JavaScript文件。 由于无法使用wp_localize_script (我们没有将脚本admin_head ),我们将直接在admin_head打印它:

 foreach( array('post.php','post-new.php') as $hook ) add_action( "admin_head-$hook", 'admin_head_js_vars' ); /** * Localize Script */ function admin_head_js_vars() { $img = plugins_url( '/js/images/myshortcode.png', __FILE__ ); ?>     

有了这个,按钮创建看起来像:

 title: b5f_mce_config.tb_title, // title of the button image: b5f_mce_config.button_img, // path to the button's image 

现在,我们将添加一个Ajax操作:

 add_action( 'wp_ajax_b5f_tinymce_shortcode', 'b5f_tinymce_shortcode' ); function b5f_tinymce_shortcode() { $do_check = check_ajax_referer( '_nonce_tinymce_shortcode', 'security', false ); if( !$do_check ) echo 'error'; else include_once 'my-form.php'; exit(); } 

回到JS(注意我的例子基于此 ):

 jQuery(function($) { /* Used in Ajax and Callback */ var table; /** * Get the ThickBox contents wit Ajax */ var data_alt = { action: 'b5f_tinymce_shortcode', security: b5f_mce_config.ajax_nonce }; $.post( b5f_mce_config.ajax_url, data_alt, function( response ) { if( 'error' == response ) { $('

Ajax error

') .appendTo('body').hide(); } else { form = $(response); table = form.find('table'); form.appendTo('body').hide(); form.find('#mygallery-submit').click(b5f_submit_gallery); } } ); /** * Callback for submit click */ function b5f_submit_gallery() { // Options defined in admin_head var shortcode = '[my_shortcode]'; // inserts the shortcode into the active editor tinyMCE.activeEditor.execCommand('mceInsertContent', 0, shortcode); // closes Thickbox tb_remove(); } });

最后,Ajax附带的文件myform.php可以包含任何WordPress函数:

  

你说你不想学习AJAX,但你不应该害怕。 jQuery的$.get()函数使得从外部文件获取和处理数据变得非常容易。 如果您的PHP函数驻留在单独的文件中,您可以对该文件进行$ .get()调用,并在同一个jQuery函数中填充该表单。

你的jQuery可以像下面这样简单:

 $.get( "ajax/test.php", function( data ) { $( ".result" ).html( data ); }); 

假设你的文件,test.php返回了一个JSON数组,甚至是你在URL中传递的基于纯文本的参数(即:“ajax / test.php?userid = 1&get = name”),你可以使用jQuery来填充表单。

你的jQuery:

 $.get( "ajax/test.php?userid=1&get=name", function( data ) { $( "#myform input.firstname").val( data.firstname ); $( "#myform input.lastname").val( data.lastname ); }, "json" ); 

test.php看起来像:

  "Burt", "lastname" => "Bartigan" )); ?> 

你说你不想使用AJAX,但这是你解决这个问题的最简单方法。

有关$ .get()的更多信息;

有关PHP json函数的更多信息

– 编辑 –

要回答以下评论:

你的PHP:

 $all_options[]['value'] = $value; $all_options[]['name'] = $name; // or however you can best get it // from the database into an array echo json_encode( array('options' => $all_optoins) ); 

你的jQuery:

 $.get( "ajax/test.php", function( data ) { var options = data.options; for(row in options) { // append will place this inside the  

你的HTML: