2009年6月29日月曜日

[Symfony] 静的ファイルをバージョン管理するためのメモ

Ruby on Railsを利用していて何気に便利だなと思うのが、JavascriptやCSS等の静的ファイルをバージョン管理してくれるところです。

ここでいうバージョン管理 (Versioning) というのは、ファイルの更新日時をクエリパラメータとして付加してくれることを指します。

<%= javascript_include_tag 'application' %>
# => <script src="/javascripts/application.js?1164912447" type="text/javascript"></script>

こうすることで、ファイルを更新してもブラウザのキャッシュを気にする必要がなくなります。

SymfonyにもRailsと同名の javascript_include_tag というViewヘルパーがあるので、その辺うまいことやってくれるのかと思ったら、そうではありませんでした。
仕方ないので自分でなんとかすることに。


Symfonyの場合、Javascriptファイルの出力の仕方はいろいろあると思うのですが、最終的には、javascript_include_tagが利用されているようです。
(CentOSの場合は /usr/share/pear/symfony/helper/AssetHelper.php)

ですので、javascript_include_tagをごにょごにょすれば一括で修正できそうです。

もちろんSymfonyのコアファイルをいじるのは色々問題があると思うので、AssetHelper.phpをコピーして、同じ名前のままプロジェクトディレクトリ内の lib/helper に置きます。
(helperというディレクトリない場合は新たに作成)


変更前
function javascript_include_tag()
{
$html = '';
foreach (func_get_args() as $source)
{
$source = javascript_path($source);
$html .= content_tag('script', '', array('type' => 'text/javascript', 'src' => $source))."\n";
}

return $html;
}

変更後
function javascript_include_tag()
{
$html = '';
foreach (func_get_args() as $source)
{
$version = filemtime(SF_ROOT_DIR . DIRECTORY_SEPARATOR . 'web' . $source);
$source = javascript_path($source);
$html .= content_tag('script', '', array(
'type' => 'text/javascript', 'src' => $source . '?' . $version))."\n";
}

return $html;
}


スタイルシートの場合は、AssetHelper.php内の stylesheet_tag 修正します。

変更前
function stylesheet_tag()
{
$sources = func_get_args();
$sourceOptions = (func_num_args() > 1 && is_array($sources[func_num_args() - 1])) ? array_pop($sources) : array();

$html = '';
foreach ($sources as $source)
{
$source = stylesheet_path($source);
$options = array_merge(array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => 'screen', 'href' => $source), $sourceOptions);
$html .= tag('link', $options)."\n";
}

return $html;
}

変更後
function stylesheet_tag()
{
$sources = func_get_args();
$sourceOptions = (func_num_args() > 1 && is_array($sources[func_num_args() - 1])) ? array_pop($sources) : array();

$html = '';
foreach ($sources as $source)
{
$version = filemtime(SF_ROOT_DIR . DIRECTORY_SEPARATOR . 'web' . $source);
$source = stylesheet_path($source);
$options = array_merge(array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => 'screen', 'href' => $source . '?' . $version), $sourceOptions);
$html .= tag('link', $options)."\n";
}

return $html;
}


SF_ROOT_DIR はプロジェクトのルートディレクトリを指します。

0 件のコメント: