ルモーリン

Mojoliciousでfavicon表示

投稿:2019-02-26

Mojoliciousがデフォルトのアイコンファイルを持っていて、アプリケーションのルーティングの設定よりも先に参照されます。 場所はMojolicious::Staticのextraです。
extraのfavicon.icoを削除して自分が設定したルーティングで希望のfavicon.icoを返せば良い訳です。
	# favicon.ico
	delete $self->static->extra->{"favicon.ico"};
希望のfavicon.ico以外にも単純にディレクトリにあるファイルを返すようにしています。 コントローラー「anyfile」のメソッド「through」を呼び出すルートを設定、リクエストの際はルートのファイル名がスタッシュ「filename」に入ります。
	# マッチしなかったその他のファイル全部
	$r->get("/#filename")->to("anyfile#through", directory => "");
コントローラーはこんなコードです。 公開するつもりの拡張子だけ選別、予定外の場合はnot_foundを返します。
ackage Myapp::Controller::Anyfile;
use Mojo::Base 'Mojolicious::Controller';

# This action will render a template
sub through {
	my $self = shift;

	my $directory = $self->stash("directory");
	my $filename = $self->stash("filename");
	$self->app->log->debug("固定ファイル: $directory/$filename");

	my $path = $self->app->home->child("draft")->child($directory)->child($filename)->to_string;
	if (-e $path) {
		my $data = $self->app->home->child("draft")->child($directory)->child($filename)->slurp;
		if ($filename =~ /\.pdf$/i) {
			$self->render(data => $data, format => "pdf");
		} elsif ($filename =~ /\.css$/i) {
			$self->render(data => $data, format => "css");
		} elsif ($filename =~ /\.ico$/i) {
			$self->render(data => $data, format => "ico");
		} elsif ($filename =~ /\.png$/i) {
			$self->render(data => $data, format => "png");
		} elsif ($filename =~ /\.jpg$/i) {
			$self->render(data => $data, format => "jpg");
		} elsif ($filename =~ /\.jpeg$/i) {
			$self->render(data => $data, format => "jpg");
		} else {
			$self->reply->not_found;
		}
	} else {
		$self->reply->not_found;
	}
}

1;