WordPress教程

创建WordPress后台选项界面(五)—— 在后台使用Ajax

依然以CC Comment插件为例,展示如何在WordPress后台使用Ajax。CC Comment插件允许在后台设置->常规选项卡中填写抄送的邮箱,现在要使用Ajax方式验证填写的邮箱是否合法。

步骤概述:

  • 创建验证email的功能
  • 创建以Ajax方式发送数据的脚本,写在外部js文件中
  • 引入外部js文件
  • 注册Ajax的action和callback

功能描述:

在设置->常规中填写CC Comments的抄送email时,当鼠标点击到input之外的地方,就会开始验证,验证时先显示Checking email…,如果验证成功则显示Email OK,一切过程不需要刷新页面

检查email

创建验证email的功能

function cccomm_email_check() {
	$email = isset( $_POST['cccomm_cc_email'] ) ? $_POST['cccomm_cc_email'] : null;
	$msg = 'invalid';
	if( $email ) {
		if( is_email($email) ) {
			$msg = 'valid';
		}
	}
	echo $msg;
	die();
}

cccomm_email_check()函数检测email是否合法:

从POST数组中查找ID为cccomm_cc_email的input是否有填写email,如果有,就用is_email()函数检测email是否合法。email合法就打印信息valid,否则为invalid。

最后必须用die()终止函数运行,否则可能会返回奇怪的结果。

创建以Ajax方式发送数据的脚本

使用jQuery的Ajax功能发送数据,新建一个文件cc_comment.js,将脚本放在这个文件中。

jQuery(document).ready( function($) {
	$("input[name='cccomm_cc_email']").blur( function() {
		$.ajax({
			type: "POST",
			data: "cccomm_cc_email=" + $(this).val() + "&action=cccomm_email_check_action",
			url: ajaxurl,
			beforeSend: function() {
				$('#emailInfo').html('Checking email...');	
			},
			success: function( $data ) {
				if( $data == 'valid'){
					$('#emailInfo').html('Email OK');	
				} else {
					$('#emailInfo').html('You have entered an invalid email');	
				}
			}
		});
	});
});

1. WordPress中的jQuery运行在noConflict模式下,所以用jQuery代替$符号。只要在ready事件中将$符号作为参数传给function,则可以在function内部使用$符号而不必担心冲突。

2. 使用$.ajax发送数据,以POST方式(type)发送,数据(data)是一个url参数,cccomm_cc_email为用户填写的email,传给WordPress一个action参数cccomm_email_check_action,让WordPress区分不同的Ajax call

3. 将Ajax请求发送给ajaxurl,ajaxurl是已经定义好的url地址,也就是wp-admin/admin-ajax.php

4. 在发送数据之前(beforeSend),向用户显示“Checking email…”信息,表示正在检测email合法性。emailInfo是一个span,应该写在field中,如下

function cccomm_setting_field() {
	?>
	<input type="text" name="cccomm_cc_email" id="cccomm_cc_email"
	value="<?php echo get_option('cccomm_cc_email'); ?>" />
	<span id="emailInfo"></div>
	<?php
}

5. 数据成功返回(success)的话,根据返回的数据向用户展示结果,如果返回valid,表示验证成功,告知用户“Email OK”,反之则告知“You have entered an invalid email”。

后台处理功能和发送数据的js功能创建完毕,但这些功能还处于游离状态,WordPress不知道它们的存在,现在要告诉WordPress引入这些功能。

引入外部js文件

add_action('admin_print_scripts-options-general.php', 'cccomm_email_check_script');

function cccomm_email_check_script() {
	wp_enqueue_script('cc-comments', plugins_url('cc_comment.js', __FILE__), array('jquery'));
}

1. 要引入外部js文件,应该使用wp_enqueue_script()函数

2. 将引入外部js文件的功能挂在到admin_print_scripts hook上,但我们只希望在设置->常规(General)这个页面引入脚本,所以进一步选择hook admin_print_scripts-options-general.php

3. 该脚本要依赖jquery,所以在wp_enqueue_script函数中以array('jquery')告知该脚本要依赖jquery才能执行,请WordPress加载jquery后再加载这个外部js文件

注册Ajax的action和callback

add_action('wp_ajax_cccomm_email_check_action', 'cccomm_email_check');

万事俱备,只欠东风。WordPress唯一还不知道的事就是应该执行server端哪个函数来处理Ajax请求,这时需要使用一个hook来告知——wp_ajax_[action handle]

这里,唯一要保证的就是wp_ajax_[action handle]]中的action handle要与$.ajax方法中的action参数保持一致,即

add_action('wp_ajax_cccomm_email_check_action', 'cccomm_email_check');

data: "cccomm_cc_email=" + $(this).val() + "&action=cccomm_email_check_action",

红色部分要保持一致

这样WordPress知道如果传递的action是cccomm_email_check_action,就应该调用server端的cccomm_email_check()函数处理Ajax发送过来的数据。

至此,Ajax就可以在后台正常使用了。

示例代码下载

[download id=42]

参考资料

AJAX in Plugins

36条评论

  1. 现在的弹出窗口 里面显示的内容是“wp-login.php”的内容,即账号和密码的输入框等。

    我只是想让里面的内容 换成其他。

    比如,自定义的About.php页面里2张图片,那就让弹窗口显示这2张图片而已。意思就是让弹窗口显示其他页面里的内容,而不是登陆页面的内容!

    1. 你说的自定义的About.php,是什么东西!一个自己写的脚本?page?还是page模板?如果你不知道get_permalink()这个函数怎么用,看下文档,再退一步,从浏览器中把完整的url地址拷贝进去总行吧

      1. 谢谢成功了 用了$link = '<a href="' . esc_url( get_permalink( get_page_by_title( 'About' ) ) )

        真心感谢你,如果以后网络上有需要人力或苦力做的事,请找我!

        1. Sola
          这个是显示作者头像的<?php echo get_avatar( get_the_author_email(), '60');?>
          用户点击后头像后就可以显示该作者的文章了,怎么样可以在用户点击头像的时候判断他是否登录?就和判断子类的那个thickbox一样

        2. 道理相同

          if( is_user_logged_in()) {
             echo get_avatar( get_the_author_email(), '60');
          } else {
            //显示未登录用户需要看到的内容,比如一个thickbox链接
          }
        3. 没 是在点击头像的时候判断,就和子类一样。
          点击头像的时候如果登录了 那就跳到作者的作品总共有哪些<a href="<?php echo get_author_posts_url(get_the_author_meta( 'ID' )); ?>">如果没登录就提示thickbox

        4. 我给你说的方法就是要实现你描述的这个东西,估计我上次给你的代码你没看懂,所以才不明白我在说啥。如果你觉得我嫌你烦,就不要问我,我没义务帮别人还被人怪罪。

        5. 没 你误解我了 我不是拿个意思,过度的为他人所想 也是一种罪过。我对你是很尊敬和感激的

        6.  “过度的为他人所想 也是一种罪过”,哈,其实我也是这种性格,看你的留言我才发现原来这样确实会让别人有压力感,以后要改一下,一起改一下吧。

  2. 终于,终于,翻遍了互联网的各大著名博客及文章资料和wordpress子类的程序在哪也没找到,终于在Sola这得到了珍贵打答案!

    恳求、跪拜 Sola大神、大人,给小人、鄙人、不知廉耻的在下指点一二吧。
    我就是想,用户看得到分类有哪些,但是要点击的话就需要登录。
    就是希望点击<?php wp_list_cats("hide_empty=0&child_of=1");?>这个子类的时候可以判断下是否登录,在这泪奔的求Sola大爷给小人一点帮助啊!

    1. 别说的这么夸张吧,我只能给你个简单的示例代码,别的恕我没时间折腾
      这个东西我想了下,比较简单的解决方法是如果用户没登陆,目录的链接直接就是登陆地址,再加上thickbox效果,当用户点击目录时,直接弹出灯箱弹窗,显示登录界面,登陆后自动跳转到那个目录。如果用户已经登录了,那目录链接直接就显示目录url,这样不用使用ajax了。示例代码你到这里下载
      https://www.solagirl.net/download/43
      请使用wp默认安装测试,这是twentyeleven的child theme,放到themes目录下,到后台外观下激活主题就行了,显示目录的代码写在sidebar.php里。

      如果有问题自己研究吧,不同的wp安装,会出啥问题不好说,反正代码就摆在那。

      另外,不要用wp_list_cats函数,这个家伙已经被废弃了,可能会在以后的版本中移除,要使用wp_list_categories()

    2. 尊崇Sola爷的指导,小的很快的就实现了该梦幻功能。当thickbox效果显示在屏幕当中时,那个心情是万分的激动啊!
      甚有以身相许感慨之意,但顿然感悟觉的爷会云到:“相你妹啊!”。故而小人无意不敢为之,但感激之情甚于言表啊!

      小的斗胆,在与爷的指导代码奋战数小时之后,无奈,斗不过爷的代码。斗胆冒死,地贴脸的前来再次向Sola爷请教!

      小的,在登录之后加了判断用户等级,如果等级不够就弹出和登录时一样的灯箱弹窗,效果很好!
      但小的不知道该怎么去改这个灯箱弹窗里面的内容,怕改了这个会影响到前面验证是否登陆的那个灯箱弹窗。

      1. 顶部黑色框框里的文字是a标签里的title决定的,灯箱的主题内容是href中写的那个地址的页面决定的,你可以再改动一下代码,就很明显了
        找到代码

        $link = '<a href="' . esc_url( wp_login_url( get_term_link($category) ) ) . '" class="thickbox" ';

        替换成

        $link = '<a href="' . esc_url( wp_login_url( get_term_link($category) ) ) . '&TB_iframe=1&width=640&height=500" class="thickbox" ';
        1. 怎么指定 灯箱的主题内容href 连接到的是比如 我新建的模板页面 About.php啊?

        2. 一般的是<a href="about.php"></a>

          这个要怎么改啊?
          $link = '<a href="' . esc_url( wp_login_url( get_term_link($category) ) ) . '&TB_iframe=1&width=640&height=500" class="thickbox" ';

          $link = '<a href="' . about.php . '&TB_iframe=1&width=640&height=500" class="thickbox" ';

        3. 我知道 我们很菜鸟 真的 求你 最后指点一下
          怎么更换a 标签 href="about.php"

          $link = '<a href="' . esc_url( wp_login_url( get_term_link($category) ) ) . '&TB_iframe=1&width=640&height=500" class="thickbox" ';让他连接到about.php

        4. 我是个监控员 文化程度相对于你们来说 并没有多高 从来都没和程序之类的东西接触过, 但因为某些特殊原因,不得不临时搞一下网站,我已经很努力的去做了,作为1个从来没和计算机什么代码打过交道的普通人做的这个地步已经算很不错了,但就算再怎么努力,我想这个你也知道,程序员不是一时半会就能做的,也是需要长年的学习和丰富的程序实践经验。

          首先,真的很真心的感谢你对我的提示指点。可能由于我的提问次数稍微有点过多,和提问的质量不是很高,而导致了你对我的抵触情绪,故而让我去从头开始学习PHP语言。我已经28了,我也知道快30岁的人不可能和年轻人一样,有那股冲劲,除了每天繁杂有时候还会到凌晨的工作以外还要去学习PHP,这是件很难办到的事情,对于我来说。

          所以当我很有幸的在这得到了你的帮助我,我真的是非常的开心,同时也感觉你挺好的一个人,现在也是如此。
          不过说真的,我快30岁了 再来学习PHP很困难了,真心希望你能最后帮我这个小忙,谢谢了!

        5. 不是我不帮你,真心的没法帮,你说的更换地址的需求很不明确,我看不懂,所以只能告诉你用什么方法去实现你的要求,而且我最近还要工作,真心没那么多时间去猜测需求再解决问题。还有年纪不比你小,不过我可以告诉你php的基础语法用不了一个小时就能看懂,我也不是学计算机出身,这些东西都是毕业以后自学的,真的没那么难。为什么觉得30岁就不能学习呢,我也是奔三的人,还是每天学啊。另外,不要总叫我爷,偶只是一小女子。

  3. <?php wp_list_cats("hide_empty=0&child_of=1");?> 这个是显示子类的

    怎么在用户点击子类的时候判断是否登录,如果未登录就提示

    1. 不管点啥都是用is_user_logged_in()来判断,只不过你要找对写这个函数的地方。
      我不明白为啥点分类就要提示,如果是禁止未登录用户查看分类页面,那只要在分类页面模板中用is_user_logged_in()来判断,如果未登录就显示提示,否则显示分类页面内容。
      非要点击某个分类菜单的时候判断,执行一个Ajax请求就行了,后台脚本用is_user_logged_in()函数判断状态,然后返回,如果未登录用js弹出提示框。但你禁止未登录用户访问的页面也必须用is_user_logged_in()保护起来

  4. 这个是显示子类的

    怎么在用户点击子类的时候判断是否登录,如果未登录就是提示

  5. 是点击分别标签的时候 判断
    用户点击分类1,如果是为登录的话 就提示说是未登录

评论已关闭。