- Timestamp:
- 11/26/08 11:23:30 (4 years ago)
- Location:
- lang/perl/MENTOS/trunk
- Files:
-
- 2 added
- 12 modified
-
app/controller/edit.mt (modified) (2 diffs)
-
app/controller/edit.pl (modified) (3 diffs)
-
app/controller/entries.mt (modified) (2 diffs)
-
app/controller/entry.mt (modified) (2 diffs)
-
app/controller/index.pl (modified) (2 diffs)
-
lib/MENTA.pm (modified) (5 diffs)
-
lib/MENTA/CGI.pm (modified) (1 diff)
-
lib/MENTA/Context.pm (added)
-
lib/MENTA/Dispatch.pm (modified) (2 diffs)
-
lib/MENTA/Plugin.pm (modified) (2 diffs)
-
lib/MENTA/Response.pm (added)
-
lib/MENTA/TemplateLoader.pm (modified) (2 diffs)
-
menta.cgi (modified) (3 diffs)
-
plugins/blog.pl (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/perl/MENTOS/trunk/app/controller/edit.mt
r24806 r24901 1 1 ? my ($entry, $message) = @_ 2 ?= render _partial('header.mt', config()->{application}->{title})2 ?= render('header.mt', config()->{application}->{title}) 3 3 <div class="entry"> 4 4 <span class="error"><?= $message ?></span> … … 21 21 </form> 22 22 </div> 23 ?= render _partial('footer.mt')23 ?= render('footer.mt') -
lang/perl/MENTOS/trunk/app/controller/edit.pl
r24303 r24901 1 1 use MENTA; 2 3 load_plugin('blog');4 2 5 3 sub do_edit { 6 4 my $id = param('id') || ''; 7 5 my $data_dir = data_dir; 8 my $static_dir = static_dir;6 my $static_dir = docroot . '/static/'; 9 7 my $msg = ''; 10 8 my $entry = {}; … … 26 24 } 27 25 if ($entry->{description}) { 28 write_file("${data_dir}/${id}.txt", $entry->{title}."\n".$entry->{description});26 blog_file_write("${data_dir}/${id}.txt", $entry->{title}."\n".$entry->{description}); 29 27 } else { 30 28 unlink("${data_dir}/${id}.txt"); … … 40 38 } 41 39 42 render ('edit.mt', $entry, $msg);40 render_and_print('edit.mt', $entry, $msg); 43 41 } -
lang/perl/MENTOS/trunk/app/controller/entries.mt
r24806 r24901 1 1 ? my $entries = shift 2 ?= render _partial('header.mt', config()->{application}->{title})2 ?= render('header.mt', config()->{application}->{title}) 3 3 <div class="entries hfeed"> 4 4 ? for my $entry (@{$entries}) { … … 26 26 <p align="right"><a href="edit">新規編集</a></p> 27 27 <br /> 28 ?= render _partial('footer.mt')28 ?= render('footer.mt') -
lang/perl/MENTOS/trunk/app/controller/entry.mt
r24806 r24901 1 1 ? my $entry = shift 2 ?= render _partial('header.mt', config()->{application}->{title})2 ?= render('header.mt', config()->{application}->{title}) 3 3 <div class="entry hentry"> 4 4 <a class="entry-title" href="<?= docroot ?>?id=<?= $entry->{id} ?>"><?=r $entry->{title} ?></a><br /> … … 20 20 </div> 21 21 <p align="right"><a href="edit?id=<?= $entry->{id} ?>">編集</a></p> 22 ?= render _partial('footer.mt')22 ?= render('footer.mt') -
lang/perl/MENTOS/trunk/app/controller/index.pl
r24303 r24901 1 1 use MENTA; 2 3 load_plugin('blog');4 2 5 3 sub do_index { … … 8 6 9 7 if ($id =~ /^\d+$/) { 10 render ('entry.mt', blog_read_entry("${data_dir}/${id}.txt"));8 render_and_print('entry.mt', blog_read_entry("${data_dir}/${id}.txt")); 11 9 } else { 12 my @entries = sort {$b->{mtime} <=> $a->{mtime}}13 map { blog_read_entry($_) } glob("${data_dir}/*.txt");14 render ('entries.mt', \@entries);10 my @entries = sort {$b->{mtime} <=> $a->{mtime}} 11 map { blog_read_entry("$_") } glob("${data_dir}/*.txt"); 12 render_and_print('entries.mt', \@entries); 15 13 } 16 14 } -
lang/perl/MENTOS/trunk/lib/MENTA.pm
r24806 r24901 5 5 use CGI::ExceptionManager; 6 6 use MENTA::Dispatch (); 7 use MENTA::Context; 8 use CGI::Simple; 9 use Class::Trigger qw/BEFORE_OUTPUT/; 7 10 require Encode; # use Encode するとふるい Encode でエラーになるときがあるらしい。2.15 で確認。200810-11-20 8 11 9 our $VERSION = '0.0 6';12 our $VERSION = '0.07'; 10 13 our $REQ; 11 14 our $CONFIG; 12 our $REQUIRED;13 15 our $STASH; 14 our $PLUGIN_LOADED;15 BEGIN {16 $REQUIRED = {};17 }18 16 19 17 sub import { … … 23 21 } 24 22 23 { 24 our $context; 25 sub context { $context } 26 sub run_context { 27 my ($class, $config, $code) = @_; 28 local $context = MENTA::Context->new( 29 config => $config, 30 ); 31 $code->(); 32 } 33 } 34 25 35 package main; # ここ以下の関数はすべてコントローラで呼ぶことができます 26 36 27 sub AUTOLOAD { 28 my $method = our $AUTOLOAD; 29 $method =~ s/.*:://o; 30 (my $prefix = $method) =~ s/_.+//; 31 load_plugin($prefix); 32 return main->can($method)->(@_); 33 } 34 35 sub config () { $MENTA::CONFIG } 37 38 sub config () { MENTA->context->config } 36 39 37 40 sub run_menta { 38 41 my $config = shift @_; 39 42 40 local $MENTA::CONFIG = $config;41 local $MENTA::REQ;42 local $MENTA::STASH;43 44 43 CGI::ExceptionManager->run( 45 44 callback => sub { 46 MENTA::Dispatch->dispatch() 45 MENTA->run_context( 46 $config => sub { 47 MENTA::Dispatch->dispatch() 48 } 49 ); 47 50 }, 48 51 powered_by => '<strong>MENTA</strong>, Web Application Framework.', 49 ( config->{menta}->{fatals_to_browser} ? () : (renderer => sub { "INTERNAL SERVER ERROR!" x 100 }))52 ($config->{menta}->{fatals_to_browser} ? () : (renderer => sub { "INTERNAL SERVER ERROR!" x 100 })) 50 53 ); 51 54 } … … 86 89 } 87 90 88 sub static_dir {89 config->{menta}->{static_dir} || 'app/static/'90 }91 92 91 sub __render_partial { 93 92 my ($tmpl, $tmpldir, @params) = @_; 94 require_once('MENTA/TemplateLoader.pm');95 93 MENTA::TemplateLoader::__load("$tmpldir/$tmpl", @params); 96 94 } 97 sub render_partial { 98 my ($tmpl, @params) = @_; 99 bless \__render_partial($tmpl, controller_dir(), @params), 'MENTA::Template::RawString'; 100 } 101 102 sub detach() { CGI::ExceptionManager::detach(@_) } 103 95 96 # テンプレートの一部を描画する 104 97 sub render { 105 98 my ($tmpl, @params) = @_; 106 my $out = render_partial($tmpl, @params); 107 $out = $$out; 108 $out = encode_output($out); 109 print "Content-Type: text/html; charset=" . charset() . "\r\n"; 110 print "\r\n"; 111 print $out; 112 113 detach; 99 my $out = MENTA::TemplateLoader::__load("@{[ controller_dir() ]}/$tmpl", @params); 100 bless \$out, 'MENTA::Template::RawString'; 101 } 102 103 sub _finish { 104 MENTA->call_trigger('BEFORE_OUTPUT'); 105 use bytes; 106 my $res = MENTA->context->res; 107 $res->headers->content_length(bytes::length($res->content)); 108 print $res->as_string; 109 CGI::ExceptionManager::detach(); 110 } 111 112 sub render_and_print { 113 my ($tmpl, @params) = @_; 114 MENTA::Util::require_once('MENTA/TemplateLoader.pm'); 115 my $out = MENTA::TemplateLoader::__load("@{[ controller_dir() ]}/$tmpl", @params); 116 $out = MENTA::Util::encode_output($out); 117 118 my $res = MENTA->context->res; 119 $res->headers->content_type("text/html; charset=" . MENTA::Util::_charset()); 120 $res->content($out); 121 122 _finish(); 114 123 } 115 124 116 125 sub redirect { 117 126 my ($location, ) = @_; 118 print "Status: 302\r\n"; 119 print "Location: $location\r\n"; 120 print "\r\n"; 121 122 detach; 127 128 my $res = MENTA->context->res; 129 $res->header('Status' => 302); 130 $res->header('Location' => $location); 131 132 _finish(); 123 133 } 124 134 125 135 sub finalize { 126 136 my $str = shift; 127 my $content_type = shift || ('text/html; charset=' . charset()); 128 129 print "Content-Type: $content_type\r\n"; 130 print "\r\n"; 131 print $str; 132 133 detach; 134 } 135 136 sub read_file { 137 my $fname = shift; 138 open my $fh, '<:utf8', $fname or die "${fname} を読み込み用に開けません: $!"; 139 my $s = do { local $/; join '', <$fh> }; 140 close $fh; 141 $s; 142 } 143 144 sub write_file { 145 my ($fname, $stuff) = @_; 146 open my $fh, '>:utf8', $fname or die "${fname} を書き込み用に開けません: $!"; 147 print $fh $stuff; 148 close $fh; 149 } 150 151 sub param { 152 my $key = shift; 153 154 unless (defined $MENTA::REQ) { 155 require_once('MENTA/CGI.pm'); 156 $MENTA::REQ = CGI::Simple->new(); 157 } 158 159 $MENTA::REQ->param($key); 160 } 161 162 sub upload { 163 unless (defined $MENTA::REQ) { 164 require_once('MENTA/CGI.pm'); 165 $MENTA::REQ = CGI::Simple->new(); 166 } 167 $MENTA::REQ->upload(@_); 168 } 169 170 sub require_once { 171 my $path = shift; 172 return if $MENTA::REQUIRED->{$path}; 173 require $path; 174 $MENTA::REQUIRED->{$path} = 1; 175 } 176 177 sub load_plugin { 178 my $plugin = shift; 179 return if $MENTA::PLUGIN_LOADED->{$plugin}; 180 my $path = "plugins/${plugin}.pl"; 181 require $path; 182 $MENTA::PLUGIN_LOADED->{$plugin}++; 183 my $package = __menta_extract_package($path) || ''; 184 no strict 'refs'; 185 for ( 186 grep { /$plugin/o } 187 grep { defined &{"${package}::$_"} } 188 keys %{"${package}::"} 189 ) { 190 *{"main::$_"} = *{"${package}::$_"} 191 } 192 } 193 194 sub __menta_extract_package { 195 my $modulefile = shift; 196 open my $fh, '<', $modulefile or die "$modulefile を開けません: $!"; 197 my $in_pod = 0; 198 while (<$fh>) { 199 $in_pod = 1 if m/^=\w/; 200 $in_pod = 0 if /^=cut/; 201 next if ( $in_pod || /^=cut/ ); # skip pod text 202 next if /^\s*\#/; 203 204 /^\s*package\s+(.*?)\s*;/ and return $1; 205 } 206 return; 137 my $content_type = shift || ('text/html; charset=' . MENTA::Util::_charset()); 138 139 my $res = MENTA->context->res; 140 $res->headers->content_type($content_type); 141 $res->content($str); 142 143 _finish(); 144 } 145 146 sub param { MENTA->context->request->param(@_) } 147 sub upload { MENTA->context->request->upload(@_) } 148 sub mobile_agent { MENTA->context->mobile_agent() } 149 150 151 { 152 # プラグインのロード機構 153 154 my $plugin_loaded; 155 my $__menta_extract_package = sub { 156 my $modulefile = shift; 157 open my $fh, '<', $modulefile or die "$modulefile を開けません: $!"; 158 my $in_pod = 0; 159 while (<$fh>) { 160 $in_pod = 1 if m/^=\w/; 161 $in_pod = 0 if /^=cut/; 162 next if ( $in_pod || /^=cut/ ); # skip pod text 163 next if /^\s*\#/; 164 165 /^\s*package\s+(.*?)\s*;/ and return $1; 166 } 167 return; 168 }; 169 my $_load_plugin = sub { 170 my $plugin = shift; 171 return if $plugin_loaded->{$plugin}; 172 my $path = "plugins/${plugin}.pl"; 173 require $path; 174 $plugin_loaded->{$plugin}++; 175 my $package = $__menta_extract_package->($path) || ''; 176 no strict 'refs'; 177 for ( 178 grep { /$plugin/ } 179 grep { defined &{"${package}::$_"} } 180 keys %{"${package}::"} 181 ) { 182 *{"main::$_"} = *{"${package}::$_"} 183 } 184 }; 185 186 sub AUTOLOAD { 187 my $method = our $AUTOLOAD; 188 $method =~ s/.*:://o; 189 (my $prefix = $method) =~ s/_.+//; 190 die "変な関数よびだしてませんか?: $method" unless $prefix; 191 $_load_plugin->($prefix); 192 return main->can($method)->(@_); 193 } 207 194 } 208 195 … … 212 199 } 213 200 214 # TODO: CGI にはこのための環境変数ってなかったっけ?215 201 sub docroot () { $ENV{SCRIPT_NAME} || '' } 216 202 … … 230 216 } 231 217 232 sub mobile_agent { 233 require_once('HTTP/MobileAgent.pm'); 234 $STASH->{'HTTP::MobileAgent'} ||= HTTP::MobileAgent->new(); 235 } 236 237 # HTTP::MobileAgent::Plugin::Charset よりポート。 238 # cp932 の方が実績があるので優先させる方針。 239 # Shift_JIS とかじゃなくて cp932 にしとかないと、諸問題にひっかかりがちなので注意 240 sub _mobile_encoding { 241 my $ma = mobile_agent(); 242 return 'utf-8' if $ma->is_non_mobile; 243 return 'utf-8' if $ma->is_docomo && $ma->xhtml_compliant; # docomo の 3G 端末では UTF-8 の表示が保障されている 244 return 'utf-8' if $ma->is_softbank && $ma->is_type_3gc; # SoftBank 3G の一部端末は CP932 だと絵文字を送ってこない不具合がある 245 return 'cp932'; # au は HTTPS のときに UTF-8 だと文字化ける場合がある 246 } 247 248 # charset に設定する文字列を生成 249 sub charset { 250 +{ 'utf-8' => 'UTF-8', cp932 => 'Shift_JIS' }->{_mobile_encoding()}; 251 } 252 253 # HTTP の入り口んとこで decode させる用 254 sub decode_input { 255 my ($txt, $fb) = @_; 256 Encode::decode(_mobile_encoding(), $txt, $fb); 257 } 258 259 # 出力直前んとこで encode させる用 260 sub encode_output { 261 my ($txt, $fb) = @_; 262 Encode::encode(_mobile_encoding(), $txt, $fb); 218 { 219 package MENTA::Util; 220 # ユーティリティメソッドたち。 221 # これらのメソッドは一般ユーザーはよぶべきではない。 222 223 # HTTP::MobileAgent::Plugin::Charset よりポート。 224 # cp932 の方が実績があるので優先させる方針。 225 # Shift_JIS とかじゃなくて cp932 にしとかないと、諸問題にひっかかりがちなので注意 226 sub _mobile_encoding { 227 my $ma = MENTA->context->mobile_agent(); 228 return 'utf-8' if $ma->is_non_mobile; 229 return 'utf-8' if $ma->is_docomo && $ma->xhtml_compliant; # docomo の 3G 端末では UTF-8 の表示が保障されている 230 return 'utf-8' if $ma->is_softbank && $ma->is_type_3gc; # SoftBank 3G の一部端末は CP932 だと絵文字を送ってこない不具合がある 231 return 'cp932'; # au は HTTPS のときに UTF-8 だと文字化ける場合がある 232 } 233 234 # HTTP の入り口んとこで decode させる用 235 sub decode_input { 236 my ($txt, $fb) = @_; 237 Encode::decode(_mobile_encoding(), $txt, $fb); 238 } 239 240 # 出力直前んとこで encode させる用 241 sub encode_output { 242 my ($txt, $fb) = @_; 243 Encode::encode(_mobile_encoding(), $txt, $fb); 244 } 245 246 # charset に設定する文字列を生成 247 sub _charset { 248 +{ 'utf-8' => 'UTF-8', cp932 => 'Shift_JIS' }->{_mobile_encoding()}; 249 } 250 251 # 一回ロードしたクラスは二度ロードしないための仕組み。 252 { 253 my $required = {}; 254 sub require_once { 255 my $path = shift; 256 return if $required->{$path}; 257 require $path; 258 $required->{$path} = 1; 259 } 260 } 263 261 } 264 262 -
lang/perl/MENTOS/trunk/lib/MENTA/CGI.pm
r24488 r24901 17 17 and $self->{'.globals'}->{'NO_UNDEF_PARAMS'}; 18 18 $value =~ tr/\000//d if $self->{'.globals'}->{'NO_NULL'}; 19 $value = main::decode_input( $value ); # XXX この行だけ変えてる19 $value = MENTA::Util::decode_input( $value ); # XXX この行だけ変えてる 20 20 push @{ $self->{$param} }, $value; 21 21 unless ( $self->{'.fieldnames'}->{$param} ) { -
lang/perl/MENTOS/trunk/lib/MENTA/Dispatch.pm
r24488 r24901 31 31 } 32 32 } elsif (-f $controller_mt) { 33 my $out = main::__render_partial("${path}.mt", main::controller_dir()); 34 $out = main::encode_output($out); 33 MENTA::Util::require_once('MENTA/TemplateLoader.pm'); 34 my $tmpldir = main::controller_dir(); 35 my $out = MENTA::TemplateLoader::__load("${tmpldir}/${path}.mt", main::controller_dir()); 36 $out = MENTA::Util::encode_output($out); 35 37 main::finalize($out); 36 38 } else { … … 48 50 sub show_static { 49 51 my $path = shift; 52 MENTA::Util::require_once('Cwd.pm'); 53 MENTA::Util::require_once('File/Spec.pm'); 54 $path = Cwd::realpath($path); 55 my $appdir = Cwd::realpath(File::Spec->catfile(Cwd::cwd(), 'app', 'static')); 56 if (index($path, $appdir) != 0) { 57 die "どうやら攻撃されているようだ: $path"; 58 } 50 59 open my $fh, '<', $path or die "ファイルを開けません: ${path}: $!"; 51 60 binmode $fh; -
lang/perl/MENTOS/trunk/lib/MENTA/Plugin.pm
r24111 r24901 1 1 package MENTA::Plugin; 2 use strict; 3 use warnings; 4 use utf8; 2 5 3 6 sub import { … … 7 10 utf8->import; 8 11 12 no strict 'refs'; 9 13 for (qw/config data_dir/) { 10 14 *{"${pkg}::$_"} = *{"main::$_"} -
lang/perl/MENTOS/trunk/lib/MENTA/TemplateLoader.pm
r24488 r24901 21 21 my $tmplcode = eval $code; 22 22 die $@ if $@; 23 $out = $tmplcode->( );23 $out = $tmplcode->(@params); 24 24 __update_cache($path, $code); 25 25 } … … 29 29 sub __compile { 30 30 my ($path) = @_; 31 main::require_once('MENTA/Template.pm'); 31 MENTA::Util::require_once('MENTA/Template.pm'); 32 my $src = do { 33 open my $fh, '<:utf8', $path or die "${path} を読み込み用に開けません: $!"; 34 my $s = do { local $/; join '', <$fh> }; 35 close $fh; 36 $s; 37 }; 32 38 my $t = MENTA::Template->new; 33 $t->parse( main::read_file($path));39 $t->parse($src); 34 40 $t->build(); 35 41 my $code = $t->code(); -
lang/perl/MENTOS/trunk/menta.cgi
r24806 r24901 1 1 #!perl 2 use lib 'lib', 'extlib'; 2 BEGIN { 3 unshift @INC, 'lib', 'extlib'; 4 }; 3 5 use MENTA; 4 6 # -- ここまではおまじない -- … … 13 15 # キャッシュディレクトリ 14 16 cache_dir => 'cache', 17 # ブラウザにエラーを表示するかどうか 18 fatals_to_browser => 1, 15 19 }, 16 20 # あなたのアプリの設定 … … 22 26 }, 23 27 }); 28 29 # 以下、あなたのプログラム 30 -
lang/perl/MENTOS/trunk/plugins/blog.pl
r24410 r24901 3 3 use POSIX qw(strftime); 4 4 5 sub blog_file_write { 6 my ( $fname, $stuff ) = @_; 7 open my $fh, '>:utf8', $fname 8 or die "${fname} を書き込み用に開けません: $!"; 9 print $fh $stuff; 10 close $fh; 11 } 12 5 13 sub blog_top_url { 6 my $url = $ENV{SCRIPT_NAME};14 my $url = ::docroot; 7 15 $url =~ s!menta\.cgi!!g; 8 16 $url || '/'; … … 10 18 11 19 sub blog_read_entry { 12 my ($file, $mode) = @_; 13 my $mtime = (stat $file)[9]; 14 my $content = ::read_file($file); 15 my $data_dir = ::data_dir; 16 my $static_dir = ::static_dir; 17 $file =~ s!.*?([^/]+)\.txt$!$1!; 18 my $photo = "${file}.jpg"; 20 my ($fname, $mode) = @_; 21 my $mtime = (stat $fname)[9]; 22 open my $fh, '<:utf8', $fname 23 or die "${fname} を読み込み用に開けません: $!"; 24 my $content = do { local $/; join '', <$fh> }; 25 close $fh; 26 my $data_dir = data_dir; 27 my $static_dir = ::docroot . '/static/'; 28 $fname =~ s!.*?([^/]+)\.txt$!$1!; 29 my $photo = "${fname}.jpg"; 19 30 $photo = '' unless -f "${static_dir}/${photo}"; 20 31 my $entry = { 21 id => $f ile,32 id => $fname, 22 33 title => '', 23 34 description => '',
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)