バーチャルマシン上でwebサーバーを構築した際のメモ。
MovableTypeを動かすことくらいまではできます。
※セキュリティや負荷など考慮していないので、実運用には向いていません。

VMware Player のダウンロード
http://downloads.vmware.com/jp/d/info/desktop_downloads/vmware_player/3_0

Fedora 14 デスクトップ版
http://fedoraproject.org/get-fedora
※Liveメディアではなく物理メディアの方をダウンロード

Fedoraのインストール
http://www.kkaneko.com/rinkou/linux/fedorainstall.html

VMwareのネットワークをブリッジに設定

Apache、PHP、MySQLインストール
http://blog.servered.net/2009/05/fedora-10-apachemysql.html

MySQL設定
http://fedorasrv.com/mysql.shtml

FTPサーバーインストール
http://fedorasrv.com/vsftpd.shtml

[システム]→[管理]→[ファイヤーウォール]
FTPなど信頼するにチェック

SELinux を Permissive モードに
http://vertex.air-nifty.com/blog/2006/09/fedora_core_vsf_20b9.html

phpMyAdminをインストール
http://pinoki.la.coocan.jp/wiki/?Linux%2FInstall%2FphpMyAdmin%A4%CE%A5%A4%A5%F3%A5%B9%A5%C8%A1%BC%A5%EB

gccを入れる
http://oshiete.goo.ne.jp/qa/2517200.html

CPANでPerlモジュール追加
http://diary.sshida.com/20080624-2-diary.html
http://memorva.jp/memo/linux/perl_cpan.php

imageMagicはyumでインストール
http://forum.tsukaeru.net/viewtopic.php?t=1817

もっかい SELinux を Permissive モードへ。

あとはよしなに。

FlashDevelopにクラスパスを通していないと、コーディングの時、Progressionのクラスがコード補完されません。

FlashDevelopのグローバルクラスパスにパスを通して、コーディング環境を整えます。

1. FlashDevelopの[ツール] -> [グローバルクラスパスの編集]でパネルを開く。

2.追加ボタンから下記フォルダを追加する。

 Windows 7
 C:\Users\ユーザー名\AppData\Local\Adobe\Flash CS4\ja\Configuration\Progression\Libraries

以上でFlashDevelopを再起動すればコード補完されるようになります。

下記サイトに書かれているように
http://blog.codefidelity.com/?p=16

<script type="text/javascript">
	function LightboxDelegate(url,caption) {
		var objLink = document.createElement('a');
		objLink.setAttribute('href',url);
		objLink.setAttribute('rel','lightbox');
		objLink.setAttribute('title',caption);
		Lightbox.prototype.start(objLink);
	}
</script>

という関数をJS側で用意し、
FLASHからExternalInterfaceでアクセスすれば
Lightboxを開かせることができる。

しかしLightboxの start(obj); のように、動作をスタートする関数やAPIが用意されていればいいが、されていなかった場合はどうすればいいか。
下記のようにjQueryのtrigger関数を使って、リンクをクリックしたことにすればLightboxを作動させることができる。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
	function callLightbox(url) {
 		var objLink = document.getElementById("test");
		objLink.href = url;
 		$('#test').trigger('click');
 	}
</script>

<a id="test" href="http://google.co.jp">test</a>

ステージング環境を簡単に作りたい時、シェルでrsyncを使えばすぐにできる。

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ステージングもどきテスト</title>
</head>
<body>
<h1>ステージングもどきテスト</h1>
<a href="rsync.php">アップする</a>
</body>
</html>

rsync.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ステージングもどきテスト</title>
</head>
<body>
<h1>ステージングもどきテスト</h1>
<?php
$output = shell_exec('rsync  -av --delete /var/www/html/virtual/test/ /var/www/html/virtual/public/');
echo "<pre>$output</pre>";
?>
</body>
</html>

iPhoneサイトのモックアップ用にフリックとピンチのJSを作ったのでメモ。
かなり急いで作ったからスパゲッティになってしまった。

写真を見せるギャラリーサイトを想定。
フリックで別の写真へ移動し、ピンチで拡大する。

※別途YUIライブラリ ver:3.0.0が必要です

JavaScript

document.onscroll = function(){
	if(window.pageXOffset > 5)scrollTo(0,1);
}

YUI().use('anim', function(Y) {
		//アニメーションインスタンス生成
    var collectionAnim = new Y.Anim({
        node: '#collection',
        duration: 1,
        easing: Y.Easing.easeOut
    });
		//イベント登録
    var colectionLoaded = function(e) {
			//フェードイン
			collectionAnim.set('to', { opacity:1 });
			collectionAnim.run();
			
			var PHOTO_WIDTH = 320;
			var PHOTO_HEIGHT = 427;
			var PHOTO_MAX = 6;
			var SCROLL_X_MIN = - PHOTO_WIDTH * (PHOTO_MAX - 1);
			
			var startX = 0;//#collectionのタッチ時のx座標
			var nowX = 0;//#collectionのタッチ中のx座標
			var scroll = 0;//タッチの移動距離
			var target = 0;//#collectionの移動先
			var startTouch = 0;//タッチ時のタッチ位置のx座標
			var nowTouch = 0;//タッチ中のタッチ位置のx座標
			var startDis = 0;//タッチ時の2タッチ間の距離
			var nowDis = 0;//タッチ中の2タッチ間の距離
			var startPhotoWidth = 0;//タッチ時の写真幅
			var startPhotoHeight = 0;//タッチ時の写真高さ
			var touchCount = 0;//タッチ数
			var photoCount = 0;//現在表示している写真のカウント
			var collectionElement = document.getElementById("collection");
			var zoom = false;//拡大中フラグ
			var moving = false;//移動中フラグ
			
			//タッチイベントリスナー登録
			collectionElement.addEventListener('touchstart', touchHandler, false);
			collectionElement.addEventListener('touchmove', touchHandler, false);
			collectionElement.addEventListener('touchend', touchHandler, false);
			collectionElement.addEventListener('touchcancel', touchHandler, false);
			
			//タッチイベント処理
			function touchHandler(e) {
				e.preventDefault();
				
				if (e.type == "touchstart") {
					document.getElementById("touchstatus").innerHTML = "タッチスタート";
					//タッチ数が1の時でピンチしていない時で移動中じゃないとき
					if (e.touches.length == 1 && zoom == false && moving == false) {
						touchCount = 1;
						startTouch = e.touches[0].pageX;
						scroll = 0;
						startX = collectionElement.offsetLeft;
						document.getElementById("touchmove").innerHTML = "startTouch:" + startTouch + "
startX:" + startX;
					}
					//タッチ数が2(ピンチ)の時で移動中じゃないとき
					if (e.touches.length == 2 && moving == false) {
						touchCount = 2;
						zoom = true;
						var touch1 = e.touches[0];
						var touch2 = e.touches[1];
						//3平方の定理で最初の距離を取得
						startDis = Math.sqrt(Math.pow((touch1.pageX - touch2.pageX), 2)+Math.pow((touch1.pageY - touch2.pageY), 2));
						var targetPhoto = document.getElementById("photo"+photoCount);
						startPhotoWidth = targetPhoto.offsetWidth;
						startPhotoHeight = targetPhoto.offsetHeight;
					}
				}else if (e.type == "touchmove") {
					document.getElementById("touchstatus").innerHTML = "タッチ移動";
					document.getElementById("touchx").innerHTML = e.touches[0].pageX;
					document.getElementById("touchy").innerHTML = e.touches[0].pageY;
					//タッチ数が1の時でピンチしていない時で移動中じゃないとき
					if (e.touches.length == 1 && zoom == false && moving == false) {
						touchCount = 1;
						nowTouch = e.touches[0].pageX;
						scroll = nowTouch - startTouch;
						target = startX + scroll;
						//ステージからはみ出ないようにする
						if(target > 0){
							target = 0;
						}else if(target < SCROLL_X_MIN){
							target = SCROLL_X_MIN;
						}
						collectionElement.style.left = target + "px";
						document.getElementById("touchmove").innerHTML = "nowTouch:" + nowTouch + "
scroll:" + scroll + "
target:" + target;
					}
					//タッチ数が2(ピンチ)の時で移動中じゃないとき
					if (e.touches.length == 2 && moving == false) {
						touchCount = 2;
						var touch1 = e.touches[0];
						var touch2 = e.touches[1];
						//3平方の定理で現在の距離を取得
						nowDis = Math.sqrt(Math.pow((touch1.pageX - touch2.pageX), 2)+Math.pow((touch1.pageY - touch2.pageY), 2));
						//倍率
						var magnifications = nowDis / startDis;
						var targetPhoto = document.getElementById("photo"+photoCount);
						if(startPhotoHeight * magnifications > PHOTO_HEIGHT){
							//拡大
							targetPhoto.style.width = startPhotoWidth * magnifications + "px";
							targetPhoto.style.height = startPhotoHeight * magnifications + "px";
							//位置調整
							collectionElement.style.left = -(PHOTO_WIDTH * photoCount + (startPhotoWidth * magnifications - PHOTO_WIDTH) / 2) + "px";
							collectionElement.style.top = -(startPhotoHeight * magnifications - PHOTO_HEIGHT) / 2 + "px";
							
							zoom = true;
						}else{
							//等倍
							targetPhoto.style.width = PHOTO_WIDTH + "px";
							targetPhoto.style.height = PHOTO_HEIGHT + "px";
							//正常位置
							collectionElement.style.left = -PHOTO_WIDTH * photoCount + "px";
							collectionElement.style.top = 0 + "px";
							zoom = false;
						}
						
						document.getElementById("touchmove").innerHTML = "2タッチ間の距離:" + nowDis + "
倍率" + magnifications;
					}
				}else if (e.type == "touchend" || e.type == "touchcancel") {
					document.getElementById("touchstatus").innerHTML = "";
					//タッチ数が1の時でピンチしていない時で移動中じゃないとき
					if(touchCount == 1 && zoom == false && moving == false){
						if(scroll < 0){
							photoCount++
							if(photoCount >= PHOTO_MAX - 1){photoCount = PHOTO_MAX - 1;}
						}else{
							photoCount--
							if(photoCount <= 0){photoCount = 0;}
						}
						moving = true;
						collectionAnim.set('to', { xy: [-photoCount * PHOTO_WIDTH, 0] });
						collectionAnim.run();
						collectionAnim.on('end', function(){moving = false;});
						document.getElementById("touchend").innerHTML = "photoCount:" + photoCount;
					}
					touchCount = 0;
				}
			}
				
    };
    Y.on('load', colectionLoaded);
		
});

HTML

<div id="collection">
 	<ul>
 	<li class="item"><img id="photo0" src="01.jpg" width="320" height="417" /></li>
 	<li class="item"><img id="photo1" src="02.jpg" width="320" height="417" /></li>
 	<li class="item"><img id="photo2" src="03.jpg" width="320" height="417" /></li>
 	<li class="item"><img id="photo3" src="04.jpg" width="320" height="417" /></li>
 	<li class="item"><img id="photo4" src="05.jpg" width="320" height="417" /></li>
 	<li class="item"><img id="photo5" src="06.jpg" width="320" height="417" /></li>
 	</ul>
 </div><!--#collection-->
<div id="debug">
 	ステータス: <span id="touchstatus"></span>
 	X: <span id="touchx"></span>
 	Y: <span id="touchy"></span>
 	<span id="touchint"></span>
 	<span id="touchmove"></span>
 	<span id="touchend"></span>
 </div>

CSS

#collection{
	opacity:0;
	width: 9999px;
	position: absolute;
}

#collection li{
	float: left;	
}

#debug{
	display: none;
	position: absolute;
	left: 0px;
	top: 0px;
	color: #FFF;
}

サンプル
http://www.kazy.jp/note/2010/04/yui/

ソース
http://www.kazy.jp/note/2010/04/yui/kazy_jp-note-2010-04-yui.zip



Tweener.addTween($(EntryPoint)object$(ExitPoint), {
	x:$$(x=0)
	, y:$$(y=0)
	, scaleX:$$(scaleX=1)
	, scaleY:$$(scaleY=1)
	, rotation:$$(rotation=0)
	, alpha:$$(alpha=1)
	, _blur_blurX:$$(blurX=0)
	, _blur_blurY:$$(blurY=0)
	, _blur_quality:$$(blurquality=1)
	, _color:$$(color=0xffffff)
	, delay:$$(delay=0)
	, time:$$(time=1)
	, transition:$$(transition="linear","easeInExpo","easeOutExpo") 
	, onComplete:$$(onComplete=onCompleteHandler)
})
/**
 * $$(name=name)
 */
public function set $$(name)(value:$$(type=String,Number,Boolean)):void { _$$(name) = value; }
public function get $$(name)():$$(type) { return _$$(name); }
private var _$$(name):$$(type);
for (var $$(var=i,x,y):int = $$(min=0); $$(var) < $$(max=n); $$(var)++) $(CSLB){
$(EntryPoint)
}
package {
	
	/**
	 * $$(class=class)
	 * @author	$(DefaultUser)
	 * @version	$$(version=0.1)
	 * @since	$$(#DateTime#=yyyy/MM/dd)
	 */
	public class $$(class) $(CSLB){
		//-------------------------------------
		// CONSTANTS
		//-------------------------------------
		
		//-------------------------------------
		// PROPERTY
		//-------------------------------------
		
		//-------------------------------------
		// CONSTRUCTOR
		//-------------------------------------
		/**
		 * $$(class)
		 */
		public function $$(class)():void 
		{
			$(EntryPoint)
		}
		//-------------------------------------
		// METHODS
		//-------------------------------------
		/**
		 * _initialize
		 */
		private function _initialize():void 
		{
			
		}
		/**
		 * _finalize
		 */
		private function _finalize():void 
		{
			
		}
		//-------------------------------------
		// EVENT HANDLER
		//-------------------------------------
		
	}
}

gadget.xml

アプリの基本情報や、埋め込むHTMLを記述する


<?xml version="1.0" encoding="UTF-8"?>

<Module>
	<ModulePrefs title="クリック ゲーム">
	<Require feature="opensocial-0.8" />
	<Require feature="flash" />
	</ModulePrefs>
	<Content type="html"><![CDATA[
	
<div id="externalContainer"><h1>クリック ゲーム</h1></div>
	<script type="text/javascript" src="http://kazy.jp/mixiApp/clickGame/js/gadget.js" charset="utf-8"></script>
	<div style="width:900px; height:100px; overflow:auto; border:1px solid #CCCCCC;">
	<span id="error" style="color:#F00;"></span>
	<span id="trace"></span>
	</div>
	<a href="javascript:void(0);" onclick="removeAppData(); return false;">自分のスコアデータを削除</a> <a href="javascript:void(0);" onclick="inviteMyFriends(); return false;">友達を招待する</a>
	
	]]></Content>
	</Module>

gadget.js

mixiアプリのAPIへはJSでアクセスする。
基本的な関数は下記の通り。


//定数
var GAME_SWF_PATH = "http://kazy.jp/mixiApp/clickGame/swf/clickGame.swf";
var GAME_PATH = "http://mixi.jp/run_appli.pl?id=11425";
var ACTIVITY_IMG_PATH = "http://kazy.jp/mixiApp/clickGame/images/activityIcon.gif"
//
var myscore = 0;
var myDisplayName;
/**
 * FLASH表示
 */
function showFlash() {
	gadgets.flash.embedFlash(
	GAME_SWF_PATH, "externalContainer", "8.0.0",
		{
			id : "externalswf",
			width : 900,
			height : 370,
			quality : 'high',
			wmode : 'transparent',
			allowScriptAccess : 'always' // swfからのaccessを許可
		}
	);
	
	//Vewerとマイミクのスコアをリクエスト
	requestScoreInfo();
	
}
/**
 * Vewerとマイミクのスコアをリクエスト.
 */
function requestScoreInfo() {

	//リクエストパラメータ
	var params = {};
	params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.HAS_APP];
	params[opensocial.DataRequest.PeopleRequestFields.MAX] = 1000;
	params[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;
	params[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
	
	//リクエスト生成
	var req = opensocial.newDataRequest();
	
	//基本情報をリクエスト
	var idspec = opensocial.newIdSpec(params);
	req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER),"viewer");
	req.add(req.newFetchPeopleRequest(idspec, params),"friends");

	//スコアをリクエスト
	var scoreIdspec = opensocial.newIdSpec(params);
	req.add(req.newFetchPersonAppDataRequest("VIEWER", ["score"]),"ViewerScore");
	req.add(req.newFetchPersonAppDataRequest(scoreIdspec, ["score"]),"FriendsScore");
	
	//コールバック
	req.send(responseScoreInfo);

}

/**
 * Vewerとマイミクのスコア情報を処理.
 */
function responseScoreInfo(dataResponse) {

	if (dataResponse.hadError()) {
		//エラー処理
		document.getElementById("error").innerHTML = dataResponse.getErrorMessage();
		return;
	} else {
		//通常処理
		document.getElementById("trace").innerHTML = "Vewerとマイミクのスコア情報取得成功";
		var viewerData = dataResponse.get('viewer').getData();
		var friendsData = dataResponse.get('friends').getData();
		var viewerScore = dataResponse.get("ViewerScore").getData();
		var friendsScore = dataResponse.get("FriendsScore").getData();
		var count = 0;
		var checkFlg = false;
		
		var dataArray = new Array();
		
		//マイミク情報を配列に追加
		friendsData.each(function (person) {			
			var data = {};
			data.mixiid = person.getId()
			data.displayName = person.getDisplayName()
			data.thumbnailUrl = person.getField(opensocial.Person.Field.THUMBNAIL_URL)
			dataArray.push(data);
			count++;
		});
		
		//マイミクのスコアを配列に追加
		for (var friendsId in friendsScore) {
			var score = friendsScore[friendsId].score;
			for (var i = 0; i < count; i++) {
				//idが一致すれば代入する
				if (friendsId == dataArray[i].mixiid) {					
					dataArray[i].score = score;
				}
			}
			//配列追加完了
			checkFlg = true;
		}
		
		//friendsScoreがnullでforを逃れた場合
		if (!checkFlg) {
			//すべて0を入れる
			for (var i = 0; i < count; i++) {
				dataArray[i].score = 0;
			}
		}
		
		//nullがあれば0を入れる 
		for (var i = 0; i < count; i++) {
			if (dataArray[i].score == null) {
				dataArray[i].score = 0;
			}
		}
		
		//Viewerのスコアを抽出
		for (var viewerId in viewerScore) {
			myscore = viewerScore[viewerId].score;
		}
		
		//自分のデータを追加		
		var myData = {};
		myData.mixiid = viewerData.getId();
		myData.displayName = viewerData.getDisplayName();
		myDisplayName = viewerData.getDisplayName();
		myData.thumbnailUrl = viewerData.getField(opensocial.Person.Field.THUMBNAIL_URL);
		myData.score = myscore;
		dataArray.push(myData);
		
		//FLASHへデータを受け渡す
		thisMovie("externalswf").setData(dataArray);
		
	}
}

/**
 * スコアの更新.
 */
function updateScore(gscore) {
	//自己最高スコアよりも高ければ更新
	if (parseInt(gscore) > parseInt(myscore)) {
		document.getElementById("trace").innerHTML += "
自己新記録 " + gscore.toString() + "に更新"; 		sendActivity( myDisplayName + "が自己新記録を"+gscore.toString()+"に伸ばしました",null); 		var max = gscore; 		myscore = gscore;//ゲームを継続した場合の対応 	} else { 		var max = myscore; 	} 	//更新リクエスト 	var req = opensocial.newDataRequest(); 	req.add(req.newUpdatePersonAppDataRequest("VIEWER", "score", max)); 	//送信コールバック 	req.send(function (data) { 		if (data.hadError()) { 			document.getElementById("error").innerHTML = data.getErrorMessage(); 		}else{ 			document.getElementById("trace").innerHTML += "
スコア更新成功" } }); } /** * スコアデータ削除. */ function removeAppData() { var req = opensocial.newDataRequest(); req.add(req.newRemovePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, ["score"]),"response"); req.send(function (data) { var response = data.get("response").getData(); if (response.hadError()) { document.getElementById("error").innerHTML = response.getErrorCode(); }else{ document.getElementById("trace").innerHTML += "
スコアデータ削除成功" } }); } /** * FLASHコンテナへのパス. */ function thisMovie(movieName) { var isIE = navigator.appName.indexOf("Microsoft") != -1; return (isIE) ?window[movieName] : document[movieName]; } /** * アクティビティ送信. */ function sendActivity(title, body) { var mp = {}; mp[opensocial.MediaItem.Field.TYPE] = opensocial.MediaItem.Type.IMAGE; var mediaItem = opensocial.newMediaItem("image/gif", ACTIVITY_IMG_PATH, mp); var ap = {}; ap[opensocial.Activity.Field.TITLE] = title; //ap[opensocial.Activity.Field.BODY] = body; ap[opensocial.Activity.Field.URL] = GAME_PATH; ap[opensocial.Activity.Field.MEDIA_ITEMS] = [mediaItem]; var activity = opensocial.newActivity(ap); opensocial.requestCreateActivity(activity,opensocial.CreateActivityPriority.HIGH,function (response) { if (response.hadError()) { document.getElementById("error").innerHTML = response.getErrorCode(); } else { document.getElementById("trace").innerHTML += "
アプリ更新情報へ通知成功" } }); } /** * マイミク招待. */ function inviteMyFriends() { opensocial.requestShareApp("VIEWER_FRIENDS",null,function (response) { if (response.hadError()) { document.getElementById("error").innerHTML = response.getErrorCode(); } else { document.getElementById("trace").innerHTML += "
マイミク招待パネル表示完了" } }); } //初期関数をonLoadハンドラに登録 gadgets.util.registerOnLoadHandler(showFlash);

あとはFLASHとExternalInterfaceでやりとりすれば、簡単なmixiアプリが完成。

実装例:CLICK GAME

もちろんFLASHを使わず、HTML5やJSだけでも作ることはできる。

例えば、FLASHが外部画像を読み込む場合、FLASHはディレクトリにどんなファイルがあるのか分からないので、ファイルのリストをXMLなどに持つことになるが、更新の際に画像ファイルのアップとXMLの更新が必要でめんどくさいし、ミスも起こりやすい。
なので自動的にXMLを吐き出してくれるPHPを作った。

ソース

<?php
	//GETで受け取ったフォルダ名を適応
	if($_GET["dir"]){
		//上位階層へのパスであればエラーにする
		if (ereg("../", $_GET["dir"])){
			$erorr="セキュリティ上、上位階層は表示できません";
		}
		//ルートパスであればエラーにする
		if($_GET["dir"][0] == "/"){
			$erorr="セキュリティ上、ルートパスは使えません";
		}
		//末尾に"/"がついていなければつける
		if(substr($_GET["dir"], -1, 1) != "/"){
			$_GET["dir"] = $_GET["dir"] . "/";
		}
		$path = $_GET["dir"];
	}else{
		$path = "./";
	}
	//フォルダを開く
	if ($dir = @opendir($path) ) {
		//繰り返しディレクトリ内のファイルを読む
		while(false !== ($file = readdir($dir))) {
			//is_dirは参照が狂うので、パスで指定
			$filePath = $path . $file;
			if (is_dir($filePath)){
				if($file != "." && $file != ".."){
					$dirs[] = $file;
				}
			}else{
				$files[] = $file;
			}
		}
 	}else if($erorr == false){
 		$erorr="ディレクトリを開けませんでした";
 	}
 	//以下出力部分
 	print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
?>
<info>
<?php
	if($erorr){
		print "\t<erorr message=\"" . $erorr . "\" />\n";
 	}else{
?>
	<dirs>
<?php
	if($dirs){
		foreach($dirs as $value){
			print "\t\t<dir name=\"" . $value . "\" />\n";
		}
	}
?>
	</dirs>
	<files>
<?php
	if($files){
		foreach($files as $value){
			print "\t\t<file name=\"" . $value . "\" />\n";
		}
	}
?>
 </files>
<?php
 }
?>
</info>

出力例

<?xml version="1.0" encoding="UTF-8" ?>
<info>
 	<dirs>
 		<dir name="css" />
 		<dir name="js" />
 	</dirs>
 	<files>
 		<file name="index.html" />
 		<file name="top.html" />
 	</files>
</info>

PHPのファイル名をdirInfo.phpとしたとする
dirInfo.phpにアクセスすると、カレントディレクトリの内容のXMLが吐き出される。
また、dirInfo.php?dir=hogehogeとdirパラメータを渡すことで、hogehogeディレクトリの内容のXMLが吐き出すことができる。

※悪用されると、このPHPを設置したディレクトリ以下で表示権限を持っているファイルは、すべて見られる可能性があるので注意すること。

データベースの
mt > mt_entry_meta > entry_meta_vchar_idx の種別をvarchar型からtext型に変更する
 

■robots.txtを使う

ディレクトリごとなど、複数のページを検索クロール禁止にするには、
ドキュメントルートにrobots.txtを置いて設定すると早い。


User-agent: *
Disallow: /internet/
Disallow: /av.html

■metaタグを使う

ドキュメントルートにrobots.txtをおけない場合や、
1ページだけ検索クロール禁止すればいいだけの時はmetaタグで禁止する。


<meta name="robots" content="noindex,nofollow" />

■リンク元から遮断する

クロールされてほしくないページに直接metaタグを書き込めない場合は、
そのページをリンクしているページに指定することができる。


<a href="http://hogehoge.com/" rel="nofollow">クロールされたくないリンク先</a>

■.htaccessで検索ボットのアクセスを遮断

上記方法でクロールを禁止にできるのは、google、yahoo、msnなど代表的な検索サイトで、
いくつかの検索サイトは上記方法をスルーしてしまう。(例えば、metaの方法はexciteには適応されないなど。)
そういうサイトもブロックするには、webサーバー(apache)の設定ファイル.htaccessで、検索ボットの出入りを禁止する。

# Google
SetEnvIf User-Agent "Googlebot" shutout
SetEnvIf User-Agent "Googlebot-Image" shutout
Deny from 66.249.64.0/19

■緊急に削除したい場合

googleの場合は、下記のURL 削除リクエスト ツールを使うと削除できます。
http://www.google.com/support/webmasters/bin/answer.py?answer=61062

mtで書き出す先のドメインと、本番サイトのドメインが違う時に便利

正規表現プラグインを入れる
http://www.sixapart.jp/movabletype/plugins/regex.html

テンプレートにドメインを取り除く正規表現を書く
<$MTAssetURL regex="s|http://www.xxxxx.jp||"$>

mt-static/plugins/FCKeditor/fckeditor/fckconfig.js

FCKConfig.TemplateReplaceAll = true ;

FCKConfig.TemplateReplaceAll = false ;