雖然已經有一些制式的製作方式:

等等的,皆可以透過 Quiz 關鍵字在 Facebook 查詢到許多跟測驗相關的應用。大部分是已經製作好流程的,只要填寫一下問題、結果,就可以很快地完成一張測驗表。然而,有時候要推服務時,可能會用到許多 Javascript API ,往往那些 Quiz 製造機只適合用來填寫文字跟圖片,這時候就還是得靠人工方式了!沒錯,就是要寫程式!此例以 PHP 跟 Javascript 為範例實作。

製作一個 Quiz 的流程,主要可以分成四部份:

  1. 顯示問題及收集答案
  2. 顯示結果前,詢問是否要邀請朋友參與
  3. 顯示結果和留言
  4. 將結果發佈至塗鴉牆

整體上可以簡化到兩步,就是顯示問題收集答案跟顯示結果,但這樣會使得最後一頁要做的事很多,我做了一兩個制式的測試,發現還有每一個問題就要換一個頁面,這種理由多半是要顯示廣告用的,使得每到一頁就多了一次廣告流量。我覺得分成四部份應該還滿恰當的,再細分下去有點不妥,除非是介面的設計或是問題太多。

在實作上,依上述分類可以分成 3 個頁面,第一個頁面負責顯示問題跟收集答案;第二個頁面則是提供使用者便利地點選朋友寄送邀請函;第三個就是顯示結果,以及留言的顯示,至於第四部分則可在第三頁搭配 Javascript 來提供發送,故可以少一個頁面。

流程:

  1. 新增與設定 App
  2. 顯示問題及收集答案
    • 一般的 HTML Code
  3. 顯示邀請朋友參加的介面
    • 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>
  4. 顯示結果後,提供 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 部分,則是要先去製作樣版
  5. 新增留言板
    • <fb:fbml>
              <fb:comments xid="a_unique_id" showform="true" canpost="true" candelete="false">
                      <fb:title>請留下寶貴的意見</fb:title>
              </fb:comments>
      <fb:fbml>  

常見問題:

  • 什麼是 templates
    • 這是一個預先刻劃好的樣版,可重複使用,只需要填寫關鍵字就行了!最大好處是可以很漂亮的排好擺在塗鴉牆上,而搭配關鍵字的變動,就可以拿來當做測試結果的顯示,好比如 A 得 90 分、 B 得 75 分等等,就只要把關鍵字弄成可變動囉!詳細部份可以到 http://developers.facebook.com/tools.php?templates 玩玩,可以為自己的應用程式製作專屬的樣版,而上述就是一個使用樣版的塗鴉牆例子。
    • 採用舊式申請 template 的方式,facebook 已打算在 2009/12/20 停用此功能,此例先保留給舊式範例,新式用法歡迎參考:發佈到個人塗鴉牆的樣版設定教學
  • 無法顯示 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 位置打錯或不存在時,此時就不會蹦出樣版喔,要分外留意啦


    全站熱搜

    changyy 發表在 痞客邦 留言(22) 人氣()