読者です 読者をやめる 読者になる 読者になる

tohokuaikiのチラシの裏

技術的ネタとか。

Confluenceのプラグイン開発を承ります。ご連絡はこちらのホームページからお願いいたします。

テンプレートと実行ファイルの位置関係とか

テンプレートファイルのディレクトリ構成 | 眠る開発屋blog

実行ファイルのディレクトリとテンプレートディレクトリの分離はセキュリティ的に安全というか、デザイナとプログラマの責務が明確になるというか、システムの教科書的には美しいのかなと思う。

が、

正直、運用を考えるとこの仕組みは使いにくい。

っていうのは、確かにそうですね。

んていうので、PHPフレームワークEthna使った前提だけど、こうやっています。

まず、Ethna側でテンプレファイルの拡張子指定を.htmlにしておきます。

次に、ドキュメントルートで(じゃなくてもいいんですが).htaccess

AddType application/x-httpd-php .html
php_value auto_prepend_file "/path_to_document_root/auto_prepend.php"

ってやっちゃう。まぁ、できればauto_prepend.phpはDocumentRoot外にしておけば尚よし。

<?php
if ($action = isDynamicContent()){
	include_once 'このへん適当にPathあわせ/app/Ethnasample_Controller.php';
	
	class Anonymous_Controller extends Ethnasample_Controller
	{
		function Anonymous_Controller(){
			$this->Ethna_Controller();
			$this->directory['template'] = dirname(__FILE__);
		}
		
		function getTemplatedir()
		{
			$template = $this->getDirectory('template');
			return $template;
		}

	}
	Anonymous_Controller::main('Anonymous_Controller', array($action));
	exit;
}

function isDynamicContent(){
	$dyna = array(
		'^/restaurant/(index|reserve)\.html',
		'^/event/index.html',
		'/news/index(detail)?.html',
		'^/index.html$',
		'^/en/inquire',
		/* この辺にテンプレートとして動かしたいファイルを正規表現で記述 */
		);
	
	foreach ($dyna as $regexp){
		if (preg_match('{'.$regexp.'}', $_SERVER['PATH_INFO'])){
			$action = str_replace('/', '_', $_SERVER['PATH_INFO']);
			$action = substr($action, 1, strrpos($_SERVER['PATH_INFO'], '.')-1) ;
			return $action ;
		}
	}
	
	return false ;
}

で、EthnaのActionは、たとえば、この.htaccessを/ethnaAppに置いたとすると、
http://www.example.com/ethnaApp/contact/require/sample.html
の場合、contact_require_sampleになる。で、ここがミソなんだけど、

  • sample.htmlはそのままSmartyテンプレートとして記述できる。
  • URLももちろん、上記のままでOK

Ethnaを使ったアプリケーションのSmartyテンプレートじゃない場合はただのPHPとして動作します。
この切り分けはfunction isDynamicContent()で行っています。

この辺は、エントリポイントが一つにまとめられるフレームワークならではの利点。

実際は、外部からActionの指定が予期しないもので乗っ取られないように、Actionの縛りをしています。が、その辺はEthnaの機能の詳細に入るので省略。