雖然已經有一些制式的製作方式:
等等的,皆可以透過 Quiz 關鍵字在 Facebook 查詢到許多跟測驗相關的應用。大部分是已經製作好流程的,只要填寫一下問題、結果,就可以很快地完成一張測驗表。然而,有時候要推服務時,可能會用到許多 Javascript API ,往往那些 Quiz 製造機只適合用來填寫文字跟圖片,這時候就還是得靠人工方式了!沒錯,就是要寫程式!此例以 PHP 跟 Javascript 為範例實作。
製作一個 Quiz 的流程,主要可以分成四部份:
- 顯示問題及收集答案
- 顯示結果前,詢問是否要邀請朋友參與
- 顯示結果和留言
- 將結果發佈至塗鴉牆
整體上可以簡化到兩步,就是顯示問題收集答案跟顯示結果,但這樣會使得最後一頁要做的事很多,我做了一兩個制式的測試,發現還有每一個問題就要換一個頁面,這種理由多半是要顯示廣告用的,使得每到一頁就多了一次廣告流量。我覺得分成四部份應該還滿恰當的,再細分下去有點不妥,除非是介面的設計或是問題太多。
在實作上,依上述分類可以分成 3 個頁面,第一個頁面負責顯示問題跟收集答案;第二個頁面則是提供使用者便利地點選朋友寄送邀請函;第三個就是顯示結果,以及留言的顯示,至於第四部分則可在第三頁搭配 Javascript 來提供發送,故可以少一個頁面。
流程:
- 新增與設定 App
- 顯示問題及收集答案
- 顯示邀請朋友參加的介面
- FBML 版
- <fb:fbml>
<fb:request-form action="?status=2" method="POST" invite="true" type="MyAppName" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/my_app_name/\" label=\"Authorize My Application\"") ?>"
<fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
</fb:request-form>
</fb:fbml>
- Iframe 版
- <fb:serverfbml style="width: 100%;">
<script type="text/fbml">
<fb:fbml>
<fb:request-form action="?status=2" method="POST" invite="true" type="XFBML" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/my_app_name/\" label=\"Authorize My Application\"") ?>"
<fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
</fb:request-form>
</fb:fbml>
</script>
</fb:serverfbml>
- 顯示結果後,提供 Post 到個人塗鴉牆(採用舊式申請 template 的方式,facebook 已打算在 2009/12/20 停用此功能,此例先保留給舊式範例,新式用法歡迎參考:發佈到個人塗鴉牆的樣版設定教學)
- FBML
- <script type="text/javascript">
var template_id = number_id;
var user_message_prompt = 'What do you think of this book?';
var user_message = {value: 'write your review here'};
var template_data={
'test_name':'Taipei' ,
'test_result':'OK',
'images':[{'src':'http://pad.thedigitalmovement.com/_blaise/2007-06-15-dgen-breakfast.jpg',
'href':'http://tw.yahoo.com/'}]
}
var body_general='';
var target_ids = '';
var continuation = function() {
// do something
};
Facebook.showFeedDialog( template_id, template_data, body_general, target_ids , continuation, user_message_prompt, user_message );
</script>
Iframe
- <script type="text/javascript">
FB_RequireFeatures(["XFBML"], function(){
FB.Facebook.init( 'appapikey' , '/path/xd_receiver.htm' , null );
var template_id = number_id;
var user_message_prompt = 'What do you think of this book?';
var user_message = {value: 'write your review here'};
var template_data={
'test_name':'Taipei' ,
'test_result':'OK',
'images':[{'src':'http://pad.thedigitalmovement.com/_blaise/2007-06-15-dgen-breakfast.jpg', 'href':'http://tw.yahoo.com/'}]
}
var body_general='';
var target_ids = '';
var continuation = function() {
// do something
};
FB.Connect.showFeedDialog( template_id, template_data, target_ids , body_general, null, FB.RequireConnect.require, continuation, user_message_prompt, user_message);
</script>
- 至於 template_id 部分,則是要先去製作樣版
- 新增留言板
- <fb:fbml>
<fb:comments xid="a_unique_id" showform="true" canpost="true" candelete="false">
<fb:title>請留下寶貴的意見</fb:title>
</fb:comments>
<fb:fbml>
常見問題:
- 什麼是 templates
- 無法顯示 templates
- 要特別留意傳給 templates 的資訊,連 images 變數中的 src 位置不存在也會導致不會顯示,當初以 IE 測試,發現很久都沒顯示訊息,改用 Firefox 才蹦出 src 位置不對的消息,另外,還可以參考下面連結的 showFeedDialog 的相關文章,有的跟隱私有關。
- 使用 fb:request-form 之 略過 / Cancel 問題
- 當第二頁採取呈現 Invite Friends 頁面時,當使用者點選 [略過] 或 [寄送邀請] 時,頁面將導向於 action 的位置,然而,有時我們會使用 GET 的方式來掌控頁面流程,但有些時候不希望將訊息暴露在瀏覽器的 url 資訊上,此時可以解決的方式是將資料改採用 POST 傳遞
- 留意的是當使用者點選 [略過] 或 [Cancel] 時,這份資訊卻不會送給 action 所指定的頁面,最簡單的處理方式,就是使用 SESSION 變數來處理
- 在進入第二頁時,將 $_SESSION['flag'] = 1
- 當使用者用了 [略過] 或 [Cancel] 時,就可在 action 所指向的 url 進行處理囉,例如得知此 flag 資訊,自動將 status 設成 2 。設定完後,可以再將 flag 清掉
- unset( $_SESSION['flag'] );
參考資訊:
簡單的 FBML 範例程式,需填寫 API Key 、Template ID 等設定:
<?php
// Copyright 2007 Facebook Corp. All Rights Reserved.
//
// Application: TEST
// File: 'index.php'
// This is a sample skeleton for your application.
//
require_once 'facebook.php';
$appapikey = 'your_app_api_key';
$appsecret = 'your_app_secret';
$facebook = new Facebook($appapikey, $appsecret);
$user_id = $facebook->require_login();
$template_id = 0123456789;
$status = isset( $_REQUEST['status'] ) ? intval( $_REQUEST['status'] ) : 0 ;
switch( $status )
{
case 1:
?>
<p style="width:100%;text-align:center;">
...等待結果運算...<br /><br /><a href="?status=2">觀看結果</a><br />
</p>
<fb:fbml>
<fb:request-form action="?status=2" method="POST" invite="true" type="MyQuizName" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/your_app_name/\" label=\"Authorize My Application\"") ?>" >
<fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
</fb:request-form>
</fb:fbml>
<?php
break;
case 2:
?>
<script>
function do_post()
{
var template_id = <?php echo $template_id; ?>;
var user_message_prompt = '想說的話:';
var user_message = {value: ''};
var template_data={
'test_name':'Tapie' ,
'test_result':'OK',
'images':[
{
'src':'http://pad.thedigitalmovement.com/_blaise/2007-06-15-dgen-breakfast.jpg',
'href':'http://tw.yahoo.com/'
}
]
}
var body_general='';
var continuation = function() {
// do something
};
Facebook.showFeedDialog( template_id, template_data, body_general, '', continuation, user_message_prompt, user_message );
}
</script>
<p style="width:100%;text-align:center;">
測試成果:100分<br /><a href="#" onclick="new Dialog().showMessage('測驗結果', '100分').onconfirm = do_post ; return false;">詳細資訊</a><br />
</p>
<?
break;
default:
?>
<form id="testForm" method="POST" action="?status=1">
<input type="hidden" id="Q_number" name="Q_number" value="1" />
<table width="100%">
<tr>
<td>Q1:你會製作表單嗎?</td>
</tr>
<tr>
<td>
<input type="radio" name="Q[0]" value="1" />會 <br />
<input type="radio" name="Q[0]" value="2" />不會
</td>
</tr>
<tr>
<td>
<button style="submit" onclick="document.getElementById('testForm').submit();">Submit</button>
</td>
</tr>
</table>
</form>
<?php
break;
}
exit;
?>
2009/10/28 筆記:
上述例子採用單一檔案(index.php)搭配參數(status)來決定目前的狀態(1:填寫答案,2:邀請朋友,3:顯示結果與張貼個人塗鴉牆),在部分情況會有一些問題,如新增留言板服務時等等的。
測試結果,建議可以改成 3 個頁面獨立運作比較乾淨,依序是 index.php 、 invite.php 和 result.php,程式碼範例如下:
- base.php
- 這個是下面這幾支程式的最上頭都要 include 進來的片段
- <?php
// Copyright 2007 Facebook Corp. All Rights Reserved.
//
// Application: TEST
// File: 'index.php'
// This is a sample skeleton for your application.
//
session_start();
require_once 'facebook.php';
$appapikey = 'your_app_api_key';
$appsecret = 'your_app_secret';
$facebook = new Facebook($appapikey, $appsecret);
$user_id = $facebook->require_login();
$template_id = 123456789;
?>
- index.php
- <?php
require( 'base.php' );
?>
<form id="test" name="test" method="POST" action="invite.php">
<table width="85%">
<tr>
<td><br /><hr width="70%" /></td>
</tr>
<tr>
<td>
Q1:請問太陽是否都從西邊出來?
</td>
</tr>
<tr>
<td>
<input type="radio" name="Q1" value="1" checked /> Yes <br />
<input type="radio" name="Q1" value="2" /> No <br />
</td>
</tr>
<tr>
<td><br /><hr width="70%" /></td>
</tr>
<tr>
<td>
Q2:請問月亮是否都從東邊出來?
</td>
</tr>
<tr>
<td>
<input type="radio" name="Q2" value="1" checked /> Yes <br />
<input type="radio" name="Q2" value="2" /> No <br />
</td>
</tr>
<tr>
<td>
<button>送出</button>
</td>
</tr>
</table>
</form>
- invite.php
- <?php
require( 'base.php' );
// 計算分數
$_SESSION['score'] = 0;
if( isset( $_REQUEST['Q1'] ) && $_REQUEST['Q1'] == 1 )
$_SESSION['score'] += 50;
if( isset( $_REQUEST['Q2'] ) && $_REQUEST['Q2'] == 2 )
$_SESSION['score'] += 50;
?>
<fb:fbml>
<fb:request-form action="result.php" method="POST" invite="true" type="MyQuizName" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/your_app_name/\" label=\"Authorize My Application\"") ?>" >
<fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
</fb:request-form>
</fb:fbml>
- result.php
- <?php
require( 'base.php' );
?>
<script>
var message = '你真厲害';
function do_post()
{
var template_id = <?php echo $template_id; ?>;
var user_message_prompt = '感言:';
var user_message = {value: ''};
var template_data={
'images':[
{
'src':'http://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Facebook.svg/200px-Facebook.svg.png',
'href':'http://www.facebook.com/'
}
] ,
'level' : message
}
var body_general='';
var continuation = function() {
// do something
};
Facebook.showFeedDialog( template_id, template_data, body_general, '', continuation, user_message_prompt, user_message );
}
</script>
<h1>測驗結果: <?php echo $_SESSION['score'] ; ?> 分</h1>
<a href="#" onclick="new Dialog().showMessage( '分數' , '<?php echo $_SESSION['score']; ?>' ).onconfirm = do_post;return false;">張貼至個人塗鴉牆</a>
<hr witdh="95%" />
<fb:comments xid="a_unique_id" showform="true" canpost="true" candelete="false">
<fb:title>請留言</fb:title>
</fb:comments>
除了要更改 base.php 中的資訊外,要記得在 result.php 中的 template 等資訊也要適當修改,我記得如果連 src 位置打錯或不存在時,此時就不會蹦出樣版喔,要分外留意啦