Contact Form 7是一款好用的表单插件,由来已久,口碑甚好。使用Contact Form 7时,通常是在后台创建两套模版:表单模版和邮件模版,模版可以使用HTML和shortcode。本文介绍如何借助这些功能动态的生成表单元素和邮件模版,让用户填写表单时可以动态增加数据,而不仅限于模版预定义的数据。
本文将描述如何在Contact Form 7页面
- 引入自定义javascript
- 引入自定义样式
- 通过clone方法克隆部分表单,动态产生数据,这里以学校为例,用户点击添加学校按钮就可以输入多组学校信息,比如小学、中学、大学。
- 动态修改email模版,将动态产生的数据一起发送
- 如何借助WP-Mail-SMTP插件进行本地发送邮件测试
安装插件就不用介绍了,假设已经装好Contact Form 7和WP Mail SMTP插件,如果用服务器测试,则无需安装后者。
使用默认主题TwentyEleven主题测试。
最终效果
目录
源代码下载
[download id=45]
下载后,启用twentyeleven主题,文件放在主题主题根目录下,form_fun.php中的代码拷贝到主题的functions.php中,按照下面的方法创建form模版进行测试。
创建Contact From 7表单和邮件模版
打开Contact选项卡,会看到默认的表单Contact form 1,就以该表单为基础,添加一个可重复出现的学校字段
Form模版
<p>Your Name (required)<br /> [text* your-name] </p> <p>Your Email (required)<br /> [email* your-email] </p> <p>Subject<br /> [text your-subject] </p> <p>Your Message<br /> [textarea your-message] </p> <div class="repeater"> <p>毕业院校<br /> [text your-school_1] </p> <p>毕业时间<br /> [text your-graduation-time_1] </p> </div> <div class="more-rows"></div> <p class="add-more"><a href="#" id="add-new">添加学校</a></p> <input type="hidden" value="1" name="rownum" id="rownum"> <p>[submit "Send"]</p>
在默认表单结构上添加了下面的内容
<!-- 位于该div下的所有内容,可以通过点击添加学校按钮产生更多组 --> <div class="repeater"> <p>毕业院校<br /> [text your-school_1] </p> <p>毕业时间<br /> [text your-graduation-time_1] </p> </div> <!-- 新产生的表单元素会放在这个div中 --> <div class="more-rows"></div> <!-- 复制表单的按钮和记录复制个数的隐藏域--> <p class="add-more"><a href="#" id="add-new">添加学校</a></p> <input type="hidden" value="1" name="rownum" id="rownum">
Message Body模版
From: [your-name] <[your-email]> Subject: [your-subject] Message Body: [your-message] 学校信息: [UserSchool] --
[UserSchool]将会被程序动态替换成学校信息
创建一个page模版
复制page.php为page-contact.php,修改头部注释信息为
<?php /** * Template Name: Custom Contact Form */
这样就创建了一个名为Custom Contact From的page模版
创建表单页面
点击页面->新建页面,创建一个新的页面,名字随便起,但要在页面属性中选则使用我们刚刚创建的page模版,也就是Custom Contact Form
在编辑器中输入刚刚创建的表单的shortcode
[contact-form-7 id="21" title="Contact form 1"]
保存页面并查看,我们刚刚创建的表单就出现了,这是由Contact Form 7表单模版产生的表单结构,只是展示了预定义的内容,还不能动态生成新的表单元素。
增加动态产生表单的功能(js)
主要通过jquery实现,所以首先确保jquery正确引入。
在page-contact.php引入jquery,下面所述所有代码都要放在get_header()之前,因为引入脚本的wp_enqueue_script()函数是在wp_head()执行时运行的,而wp_head()在get_header()中执行,所以要在执行前加入。
//确保jquery加载,且不会重复加载 wp_enqueue_script('jquery');
接下来,引入克隆表单的javascript代码,希望把这段代码放在页面底部,所以挂载到wp_footer上
add_action('wp_footer', 'custom_form_script'); function custom_form_script(){ ?> <script type="text/javascript"> jQuery(document).ready( function($) { var cur_num = 1; $('#add-new').click(function(){ $('#rownum').val(parseInt($('#rownum').val())+1); var cloned = $(".repeater").clone(true, true).get(0); ++cur_num; cloned.className = "cloned"; cloned.id = "cloned_" + cur_num;// Change the div itself. $(cloned).find("input").each(function(index, element) { // And all inner elements. element.value=''; if(element.id) { var matches = element.id.match(/(.+)_\d+/); if(matches && matches.length >= 2) // Captures start at [1]. element.id = matches[1] + "_" + cur_num; } if(element.name) { var matches = element.name.match(/(.+)_\d+/); if(matches && matches.length >= 2) // Captures start at [1]. element.name = matches[1] + "_" + cur_num; } }); $(cloned).find("span.wpcf7-form-control-wrap").each(function(index, element) { var matches = element.className.match(/(.+)_\d+/); if(matches && matches.length >= 2) // Captures start at [1]. element.className = matches[1] + "_" + cur_num; }); $(cloned).appendTo($(".more-rows")); return false; }); }); </script> <?php }
流程如下:
- 给”添加学校“按钮(id是add-new)绑定click事件
- 这个click事件首先复制一份被包围在<div class="repeater"></div>中的内容,任何内容,如果你想重复更多的元素,尽管在Form模版中向这个div中添加内容,命名规则为[fieldname_1]
- 替换被克隆的表单元素的id和name,因为后面会POST数据,如果name相同就无法区分是哪一组数据了。用自增方式修改,这样第二组表单的命名会是[fieldname_2],第三组是[fieldname_3]等等。
- 找到存放动态产生的表单元素的div <div class="more-rows"></div>,改变这个div在模版中的位置可以更改新元素出现的地方,我希望新元素位于”添加学校“按钮之前
让可重复的部分更明显
毕业院校和毕业时间是可重复产生的,为了让它们与其它元素区分开来,加一些css样式,代码依然要写在get_header()之前
add_action('wp_head', 'custom_form_styles'); function custom_form_styles(){ ?> <style type="text/css"> .cloned,.repeater{ background:#E6E6E6; padding:1em;-webkit-border-radius: 10px;-moz-border-radius: 10px;border-radius: 10px; } .cloned{margin-top:2em;} .add-more{padding:1em 0; text-align:right} </style> <?php }
这样可重复的部分就与其它部分区分开了
现在提交表单,模版中预定义的内容可以发送,但点击添加学校按钮产生的内容无法发送,接下来用程序修改发送模版
动态修改Contact Form7 邮件模版
下面的代码放在functions.php中
add_action("wpcf7_before_send_mail", "wpcf7_custom_email_template"); function wpcf7_custom_email_template(&$wpcf7_data) { if ($wpcf7_data->id == 21) { $total_repeated = $wpcf7_data->posted_data['rownum']; $has_school = $wpcf7_data->posted_data['your-school_1'] ? true : false; if ($total_repeated > 0 && $has_school) { for ($i = 1; $i <= $total_repeated; $i++) { $more_fields .= "学校: [your-school_$i]\n毕业时间: [your-graduation-time_$i]\n\n"; } $wpcf7_data->mail = str_replace('[UserSchool]', $more_fields, $wpcf7_data->mail); } else { $wpcf7_data->mail = str_replace('[UserSchool]', '无', $wpcf7_data->mail); } } }
代码流程:
- 先判断一下提交的表单的id,这段代码应该仅修改我们自定义的表单,对其它正常的表单不产生影响,表单的id可以从shortcode中获得
[contact-form-7 id="21" title="Contact form 1"]
- $wpcf7_data->posted_data包含所有post的数据,动态产生的那些也在里面
- 为了让contact form 7发送动态数据,只需要将这些动态数据的名字用contact form 7的shortcode格式加到$wpcf7_data->mail变量中即可,用str_replace替换邮件模版中预定义的[UserSchool]达到目的。
这样,就可以接收到动态产生的表单信息了。
本地测试
想本地测试的话需要配置SMTP,用WP-Mail-SMTP插件完成,例如通过gmail发送邮件,需要你有gmail的邮箱。
填写好后,就可以在本地测试发送邮件了,在表单中填写数据,测试一下结果吧。
结语
本文介绍了在Contact Form 7中用javascript动态产生表单数据,并在邮件中发送的方法。可重复的表单元素只是其中一种,还可以添加任意Form和Mail模版中未定义的表单,只要使用action wpcf7_before_send_mail定制化发送过程就可以正确发送数据了。
博主你好,怎样修改contact form 7生成的表单样式,我想修改一下表单的外观
直接在主题样式表里写css就行,用浏览器的审查工具看一下最终生成的表单的html代码,就能找到需要的css selector
其实我想修改文本框的样式,但是文本框是短代码,我无法引用CSS,要引用就要自己重新写一个input,怎样直接修改短代码生成的模板?谢谢博主的回复
短代码只是输入手段,最终生成的还是html,而且生成的结果是可预期的,只需要用firebug或者chrome inspector看一下结构就行。
给你看官方文档
http://contactform7.com/styling-contact-form/
sola, 晕死了,这几天有人不停的在网站上恶意发消息,通过contact form 7,ip每次不一样。这怎么办呀?
是机器人spam可以装Contact Form 7 Honeypot,是人工的这个就没办法了,你的表单用akismet过滤了吗?
美女,你有没有试过收件人改为腾讯企业邮箱,我试过2个腾讯企业邮箱就是收不到邮件,而Gmail或者QQ什么的都能收到..
这个Contact Form 7发送的邮件再哪可以看到记录
没有记录。你可以装插件http://wordpress.org/plugins/contact-form-7-to-database-extension/
这个插件能把发送的邮件记录到数据库里,但我感觉它解决不了你的问题。
contact form7的邮件肯定是发出去了,qq为什么没收到,不好说。
你可以先用你服务器上的webmail程序向qq邮箱发邮件,确认不是服务器的问题。
如果服务器没事,contact form 7就是发不过去,可以装smtp插件,用服务器smtp发送,或者用第三方的smtp,比如163或者google
还有,要注意from地址,最好别用wordpress默认的,在服务器上创建一个email账户,把from地址改成这个。
搞定了,装了个smtp插件插件。
再问个问题:
我使用Advanced Custom Fields创建了一个自定义字段(summary-info),想自定义控制summary-info输出内容的字节个数,找了些资料都不行,请教下,谢谢
试过PHP的mb_strimwidth或者css的text-overflow ellipsis吗?
SOLA,请问如何在contact page的页面中添加一个指定的widget呢?
<?php
$category_id = get_cat_ID( $cat_name='%1$s');
$q = 'cat=' . $category_id;
if (have_posts()) : $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'cat' => '$q',
'meta_key' => 'wpfp_favorites',
'orderby' => 'meta_value_num',
'paged' => $paged,
'order' => DESC
);
query_posts($args);
while (have_posts())
: the_post(); update_post_caches($posts); ?>
这个方法应该可以实现,但我不知道哪里出错了?
感觉你在兜圈子,既然已经在archive页面了,为啥还要通过category name来获取id?使用get_query_var(‘cat’)就可以了。
进一步讲,你只是改变一下orderby之类的参数,没必要把cat id这种重新查询一遍吧,只需要增加你要变的参数,其它的保持不变就行了,也就是说根本没必要知道cat id是什么。
参考一下官方文档
这是只改变需要改变的,保留不需要改变的
看一下http://codex.wordpress.org/Function_Reference/query_posts
在functions.php中改的话,看一下http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts
这个问题研究了十几天星期,现在文章排序是:
<?php if (have_posts()) : $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'cat' => '7',
'meta_key' => 'wpfp_favorites',
'orderby' => 'meta_value_num',
'paged' => $paged,
'order' => DESC
);
query_posts($args);
while (have_posts())
: the_post(); update_post_caches($posts); ?>
这个比方说就是现实分类ID为7的,按wpfp_favorites值来排序,可以实现。
但是一直都想不通,怎么样可以让用户点击任何一个分类或子类后进入的archive.php页面,也能够实现按wpfp_favorites来排序。
怎么让cat后面的7变为一个变量就不懂了。后来我看到在进入archive.php页面时候,发现顶部有怎么一句:
if (is_category()) {
printf( __('Archive for the ‘%1$s’Category', 'inove'), single_cat_title('', false) );
// If this is a tag archive
} elseif (is_tag()) {
printf( __('Posts Tagged ‘%1$s’', 'inove'), single_tag_title('', false) );
这句话可以显示类别名称,比如ID为7的分类叫“影视原声”,那顶部就会显示Archive for the ‘影视原声’。但这只是个类别名字啊,怎么让这个类别名字变成ID号,成1个替代'cat' => '7'当中7的变量,好久好久了 太难了
想改变全局排序需要在functions.php中写代码,直接用钩子修改。比如这里的代码
http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_orderby
如果改变了全局排序,其他按最新排序的好像也变了。
改变全局排序的时候,写上条件判断不就行了,比如is_tag(), is_category()之类的