Web プログラミング演習 特別編 いいね ボタンの実装
いいね ボタン ( 英語では Like) Facebook で, 他の人のコンテンツ ( コメント 写真など ) の支持を表明するためのボタン クリックすると, 自分の Facebook のタイムラインに支持したことが記録される ( コメントを同時投稿することも可能 ) 友達のニュースフィードに表示 コンテンツ毎にクリックしたユーザ数がカウントされる コンテンツに対するポジティブフィードバック 友達へのお勧めも兼ねている Facebook コンテンツ以外 ( 一般のサイト ) にも設置可能 ウェブマーケティングにも利用されている
Facebook の いいね の仕組み 外部コンテンツの場合 コンテンツに埋込み <iframe src="...... /> Facebook サイトで生成した外部コンテンツ用の HTML コード 一般サイト コンテンツに埋込み <iframe src="...... /> 外部コンテンツ用 HTML コード 一般サイト Facebook サイト Facebook サイトでユーザを一元管理しているので, 訪問者のユーザ ID 取得やクリックユーザ数のカウントが可能
この演習での いいね の仕組み <div> <input type="..."/> </div> 自サイトで生成した HTML,JavaScript ユーザ ID の入力 コンテンツ提供者のサイト ユーザ ID で振り分け 訪問者ごとにサイトが異なる ( 別々のユーザ管理 ) ユーザ数のカウントはできない. 訪問者が誰かはユーザに入力してもらう Basic 認証 訪問者のサイト Basic 認証 訪問者のサイト #!/usr/bin/perl use CGI;... コメント投 稿用 CGI #!/usr/bin/perl use CGI;... コメント投 稿用 CGI
演習 % cd myblog like.png( ボタンの画像 ) を作成する サンプルはここ like.js を作成する 内容はここ 先頭の myurl( 個別エントリページ用 PHP), mytitle( ブログのタイトル ) は各自のブログサイトのものに変更 いいね ボタンを配置する PHP(index.php, entry.php) を次ページのように変更する
index.php, entry.php の変更 head 領域内で like.js を読み込む <script type="text/javascript" src="like.js">//</script> エントリー出力部分を変更する ( 各自のデザインに合わせて ) エントリーにlink 要素 (<link>...</link>) が含まれていたら,aタグを使ってリンクを生成する div 要素を作り, その中に いいね ボタンを置く. クリックされた時にはlike(this, id) が呼ばれるようにする <div> <input type="image" src="like.png" alt=" いいね " onclick="like(this, $id)"/> </div> サンプルはここ
いいね ボタンを押した時に自分のエントリを追加する CGI % cd mng % cp entries.xml entries.bak ( 誤って XML ファイルを壊してしまった時のためのバックアップ ) like.cgi を作成 内容はここ 作成後の手続き ( 実行許可を与える ) % chmod +x like.cgi
ブラウザによる確認 いいね ボタンの表示の確認 自分のブログサイトの index.php, entry.php にアクセスすると, いいね ボタンが表示される いいね ボタンをクリックした時に, ユーザ ID とコメントを入力して投稿するためのフォームが表示される いいね ボタンをクリック
ブラウザによる確認 いいねエントリの追加の確認 他の人のブログサイトにある いいね ボタンをクリックする Web プログラミング演習のサイトでも OK ユーザ ID( 自分の演習室 ID,s185xxx) とコメントを入力して投稿 ユーザ認証を求めてきたら,mng ディレクトリにアクセスする時の ID, パスワードを入力 ( Perl/CGI による ( その 2) で設定したもの ) 自分のブログサイトに新しいエントリが追加されたことを確認
like.js の解説 (1) function like(btn, id){ いいね ボタンがクリックされた時の処理(btnはクリックされたボタン,idは var like = btn.parentnode; 親要素 (div) の取得クリックされたエントリーのid 属性 ) var form = like.getelementsbytagname("form")[0]; divの中にあるform 要素を取得 if(!form){ form 要素が存在しなければひとつ作成して,divに追加する form = document.createelement("form"); form.method = "POST"; form 要素のmethodはPOST form.onsubmit = like_submit; submitボタン ( 投稿 ) を押した時にはlike_submit 関数を呼び出す form.innerhtml = "<input type='hidden' name='url' value='"+myurl +"?id="+id+"'/>"; form.innerhtml += "<input type='hidden' name='title' value='"+mytitle+"'/>"; form.innerhtml += "<div> ユーザID:<input type='text' name='uid'/></div>"; form.innerhtml += "<div> コメント :<input type='text' name='comment'/></div>"; form.innerhtml += "<input type='submit' value=' 投稿 '/>"; like.appendchild(form); 入力用フォームの作成 } (urlとtitleは隠し要素) form.style.display = "block"; form 要素を表示する ( 隠れている場合があるため ) }
like.js の解説 (2) function like_submit(evt){ 投稿 ボタンがクリックされた時の処理 var form = evt.target; form 要素の取得 var uid = form.uid.value; ユーザIDの取得 var act = "http://webdesign.center.wakayama-u.ac.jp/~"+uid+"/myblog/mng/like.cgi"; } form.action = act; form.style.display = "none"; form.submit(); return true; ユーザ ID から投稿用 cgi の URL を作成して form のアクションとする form 要素を隠す投稿用 cgi を実行
like.cgi の解説 (1) regist.cgi と異なる部分 ($sec,$min,$hour,$mday,$mon,$year) = localtime; $str = sprintf("%04d.%02d.%02d %02d:%02d", ($year+1900), ($mon+1), $mday, $hour, $min); $e=$doc->createelement("date"); $e->appendchild($doc->createtextnode($str)); $entry->appendchild($e); date 要素の中身は, 現在日時とする $str = decode("utf8"," いいね (").param("title").decode("utf8"," より )"); $e=$doc->createelement("title"); title 要素の中身は, $e->appendchild($doc->createtextnode($str)); いいね( ブログ名より ) $entry->appendchild($e); とする $e=$doc->createelement("category"); $e->appendchild($doc->createtextnode(decode("utf8"," いいね "))); $entry->appendchild($e); category 要素の中身は, いいね とする
like.cgi の解説 (2) $e=$doc->createelement("body"); $e->appendchild($doc->createtextnode(param("comment"))); $entry->appendchild($e); $e=$doc->createelement("link"); $e->appendchild($doc->createtextnode(param("url"))); $entry->appendchild($e); body 要素の中身は いいね で入力したコメント link 要素を作成する中身は いいね をクリックした個別エントリーへの URL
Cookie HTTP のやり取りの中で, サーバからブラウザにデータ ( 名前と文字列の組 ) を送る仕組み HTTP レスポンスのヘッダに Cookie データを含める ブラウザは, サーバ, 名前, 文字列をセットとして記録する ( ユーザが許可している場合 ) 以降, ブラウザがそのサーバのページにアクセスする際には, 名前と文字列の組がサーバに送信される. サーバ側のセッション管理 ( 同一ユーザからの連続アクセスの把握など ) に利用されることが多い 注 : ブラウザ ( あるいはユーザ ) が自由にデータ文字列を変更できる 一般的には暗号化し, ユーザの改変が判別できるようにする
Cookie を使ってユーザ ID を記録させる いいね ボタンをクリックする度にユーザ ID を入力するのは面倒 一度いいねエントリを投稿したら, ユーザ ID を Cookie に記録させる like.cgi の実行時にサーバからブラウザに Cookie としてユーザ ID 情報を送信する Cookie の名前は mybloguid とする いいね ボタンがクリックされた時に,Cookie にユーザ ID が記録されていたら, ユーザ ID を入力済み 変更不可とする
演習 (Cookie の利用 ) mng/like.cgi の修正 HTTP レスポンスのヘッダーに Cookie を追加する print header(-type=>"text/html; charset=utf-8"); 修正 自分の演習室 ID $cookie = cookie(-name=>'mybloguid', -value=>'s175xxx'); print header(-type=>"text/html; charset=utf-8", -cookie=>$cookie);
演習 (Cookie の利用 ) like.js の修正 getcookie 関数を追加する ( 内容はここ ) 引数で指定された名前を持つ Cookie が記録されていたらそのデータ文字列を, 無ければ空文字列を返す関数 like 関数の中で,mybloguid という名前の Cookie が空文字列でなければ, ユーザ ID が設定されていた場合の処理を行う var uid = getcookie("mybloguid"); if(uid!= ""){ form.uid.value = uid; form.uid.disabled = true; } form.style.display = "block"; 追加するコード
次回の予定 XSLT による動的ページ生成