| 1 | package NanoA::TemplateLoader; |
|---|
| 2 | |
|---|
| 3 | use strict; |
|---|
| 4 | use warnings; |
|---|
| 5 | use utf8; |
|---|
| 6 | |
|---|
| 7 | use base qw(NanoA); |
|---|
| 8 | |
|---|
| 9 | sub __load { |
|---|
| 10 | my ($config, $module, $path) = @_; |
|---|
| 11 | if (__use_cache($config, $path)) { |
|---|
| 12 | NanoA::load_once($config->mt_cache_dir . "/$path.c", $path); |
|---|
| 13 | return $module; |
|---|
| 14 | } |
|---|
| 15 | my $code = __compile($path, $module); |
|---|
| 16 | local $@; |
|---|
| 17 | eval $code; |
|---|
| 18 | die $@ if $@; |
|---|
| 19 | __update_cache($config, $path, $code) |
|---|
| 20 | if $config->mt_cache_dir; |
|---|
| 21 | NanoA::loaded($path, 1); |
|---|
| 22 | } |
|---|
| 23 | |
|---|
| 24 | sub __compile { |
|---|
| 25 | my ($path, $module) = @_; |
|---|
| 26 | NanoA::require_once('MENTA/Template.pm'); |
|---|
| 27 | my $t = MENTA::Template->new; |
|---|
| 28 | $t->parse(NanoA::read_file($path)); |
|---|
| 29 | $t->build(); |
|---|
| 30 | my $code = $t->code(); |
|---|
| 31 | $code = << "EOT"; |
|---|
| 32 | package $module; |
|---|
| 33 | use strict; |
|---|
| 34 | use warnings; |
|---|
| 35 | use utf8; |
|---|
| 36 | use base qw(NanoA::TemplateLoader); |
|---|
| 37 | NanoA::__insert_methods(__PACKAGE__); |
|---|
| 38 | sub run { |
|---|
| 39 | my (\$app, \$c) = \@_; |
|---|
| 40 | raw_string($code->()); |
|---|
| 41 | } |
|---|
| 42 | 1; |
|---|
| 43 | EOT |
|---|
| 44 | ; |
|---|
| 45 | $code; |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | sub __update_cache { |
|---|
| 49 | my ($config, $path, $code) = @_; |
|---|
| 50 | my $cache_path = $config->mt_cache_dir; |
|---|
| 51 | foreach my $p (split '/', $path) { |
|---|
| 52 | mkdir $cache_path; |
|---|
| 53 | $cache_path .= "/$p"; |
|---|
| 54 | } |
|---|
| 55 | $cache_path .= '.c'; |
|---|
| 56 | open my $fh, '>:utf8', $cache_path |
|---|
| 57 | or die "failed to create cache file $cache_path"; |
|---|
| 58 | print $fh $code; |
|---|
| 59 | close $fh; |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | sub __use_cache { |
|---|
| 63 | my ($config, $path) = @_; |
|---|
| 64 | return unless $config->mt_cache_dir; |
|---|
| 65 | my @orig = stat $path |
|---|
| 66 | or return; |
|---|
| 67 | my @cached = stat $config->mt_cache_dir . "/$path.c" |
|---|
| 68 | or return; |
|---|
| 69 | return $orig[9] < $cached[9]; |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | "ENDOFMODULE"; |
|---|
| 73 | |
|---|