CakePHP1.3 を使って、ソースコードを表示するアプリを作ってみました。

こんな感じで動いています。

http://baldwin.ivory.ne.jp/code/

CakePHPでコーディングする時に参考になれば、と思って。

今後修正しちゃうかも知れないので、こっちにも必要なファイルのコードを書いておきます。

※ CSSは別ファイルにしてもいいんですが、以下の理由からこんな形にしました。

  1. 外部ファイル読み込みの形にすると、キャッシュが効いて修正しづらい
  2. 他のアプリに、このコントローラを追加する感じで使いたいのでlayoutファイルにはいれたくない

 

File: controllers/source_controller.php

  • ソースコードを表示するためのコントローラです。
  • $sourceFiles で表示するファイルを定義しています。
<?php

class SourceController extends AppController {

	var $name = 'Source';
	var $uses = array();
	var $sourceFiles = array(
		'source' => array(
			'controllers/source_controller.php',
			'views/source/index.ctp',
			'views/source/view.ctp',
		),
		'others' => array(
			'views/elements/code.ctp',
		),
	);

	function index() {
		$sourceKeys = array_keys($this->sourceFiles);
		$this->set('sourceKeys', $sourceKeys);
	}

	function view($act = null) {
		if (empty($act)) {
			$this->redirect(array('action' => 'index'));
		}
		if (!array_key_exists($act, $this->sourceFiles)) {
			$this->Session->setFlash(__('invalid key.', true));
			$this->redirect(array('action' => 'index'));
		}

		$sources = array();
		foreach($this->sourceFiles[$act] as $file) {
			$file_path = ROOT . DS . APP_DIR . DS . $file;
			if (file_exists($file_path)) {
				$lines = file($file_path);
				$sources[$file] = $lines;
			} else {
				$sources[$file] = null;
			}
		}
		$this->set('sources', $sources);
	}
}
?>

File: views/source/index.ctp

  • 表示できるソース群のキーだけを表示します。
<?php
	foreach ($sourceKeys as $sourceKey) {
		$link = array('action' => 'view', $sourceKey);
		echo $html->link($sourceKey, $link) . "<br>";
	}
?>

File: views/source/view.ctp

  • ソースコードを表示します。
  • 実際のコード表示は”code”elementを呼び出しています。
  • コード表示の為のCSSを設定しています。
<?php
	foreach($sources as $filePath => $lines) {
		$params = array(
			'filePath' => $filePath,
			'lines' => $lines
		);
		echo $this->element('code', $params);
	}

$script = <<< EOD
<style type="text/css">
<!--
.code {
	margin: 1em 0 1em 0;
	padding: 1px;
}
table.code {
	border: 1px solid gray;
	margin-left: 20px;
	border-collapse: collapse;
}
td.line {
	text-align: right;
	padding-right: .3em;
	width: 3em;
	white-space: pre;
}
td.content {
	padding-left: .5em;
	border-left:solid 3px #0099cc;
	white-space: pre;
}
-->
</style>
EOD;

	$this->addScript($script);
?>

File: views/elements/code.ctp

  • ソースコードを整形して表示します。
<h3><?php echo $filePath; ?></h3>

<?php
if (empty($lines)) {
?>
	<p class="error">file not found.</p>
<?php
} else {
?>

<table class="code">
<?php
foreach ($lines as $lineNum => $line):
?>
	<tr class="code">
	<td class="code line"><?php echo ++$lineNum; ?></td>
	<td class="code content"><?php echo htmlspecialchars($line); ?></td>
	</tr>
<?php endforeach; ?>
</table>

<?php
}
?>