Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

MicroTempate::DataSection => Xslate

  • Loading branch information...
commit 97a23a66c900725f9aae6b2a74d0c2658d7028df 1 parent a599808
@kazeburo authored
Showing with 106 additions and 82 deletions.
  1. +2 −2 Makefile.PL
  2. +41 −43 lib/NoNoPaste.pm
  3. +63 −37 lib/Shirahata.pm
View
4 Makefile.PL
@@ -17,11 +17,11 @@ requires 'Net::IP';
requires 'Plack::Middleware::Access';
requires 'Plack::Middleware::ReverseProxy';
requires 'Router::Simple';
-requires 'Text::MicroTempate::DataSection';
-requires 'Text::MicroTempate::Extended', 0.11;
+requires 'Text::Xslate', 0.1043;
requires 'HTML::FillInForm::Lite', 1.09;
requires 'Cwd';
requires 'File::Basename';
+requires 'Class::ISA';
requires 'DBI';
requires 'DBD::SQLite', 1.25;
View
84 lib/NoNoPaste.pm
@@ -81,7 +81,7 @@ get '/' => sub {
my ( $self, $c ) = @_;
my ($entries,$next) = $self->entry_list($c->req->param('offset'));
- $c->render('index',
+ $c->render('index.tx',
entries => $entries,
next => $next );
};
@@ -95,7 +95,7 @@ post '/add' => sub {
}
my ($entries,$next) = $self->entry_list;
- $c->render('index',
+ $c->render('index.tx',
entries => $entries,
next => $next);
};
@@ -105,88 +105,87 @@ get '/entry/{id:[0-9a-f]{16}}' => sub {
my $entry = $self->retrieve_entry($c->args->{id});
return $c->res->not_found() unless $entry;
- $c->render('entry', entry => $entry );
+ $c->render('entry.tx', entry => $entry );
};
1;
__DATA__
-@@ base.mt
+@@ base.tx
<html>
<head>
<title>NoNoPaste: Yet Another NoPaste</title>
-<link rel="stylesheet" type="text/css" href="<?= $c->req->uri_for('/static/js/prettify/prettify.css') ?>" />
-<link rel="stylesheet" type="text/css" href="<?= $c->req->uri_for('/static/css/ui-lightness/jquery-ui-1.8.2.custom.css') ?>" />
-<link rel="stylesheet" type="text/css" href="<?= $c->req->uri_for('/static/css/default.css') ?>" />
+<link rel="stylesheet" type="text/css" href="<: $c.req.uri_for('/static/js/prettify/prettify.css') :>" />
+<link rel="stylesheet" type="text/css" href="<: $c.req.uri_for('/static/css/ui-lightness/jquery-ui-1.8.2.custom.css') :>" />
+<link rel="stylesheet" type="text/css" href="<: $c.req.uri_for('/static/css/default.css') :>" />
</head>
<body>
<div id="container">
<div id="header">
-<h1 class="title"><a href="<?= $c->req->uri_for('/') ?>">NoNoPaste: Yet Another NoPaste</a></h1>
+<h1 class="title"><a href="<: $c.req.uri_for('/') :>">NoNoPaste: Yet Another NoPaste</a></h1>
<div class="welcome">
<ul>
-<li><a href="<?= $c->req->uri_for('/') ?>">TOP</a></li>
+<li><a href="<: $c.req.uri_for('/') :>">TOP</a></li>
</ul>
</div>
</div>
<div id="content">
-? block content => sub { }
+: block content -> { }
</div>
</div>
-<script src="<?= $c->req->uri_for('/static/js/jquery-1.4.2.min.js') ?>" type="text/javascript"></script>
-<script src="<?= $c->req->uri_for('/static/js/jstorage.js') ?>" type="text/javascript"></script>
-<script src="<?= $c->req->uri_for('/static/js/prettify/prettify.js') ?>" type="text/javascript"></script>
-? block javascript => sub {
+<script src="<: $c.req.uri_for('/static/js/jquery-1.4.2.min.js') :>" type="text/javascript"></script>
+<script src="<: $c.req.uri_for('/static/js/jstorage.js') :>" type="text/javascript"></script>
+<script src="<: $c.req.uri_for('/static/js/prettify/prettify.js') :>" type="text/javascript"></script>
+: block javascript -> {
<script type="text/javascript">
$(function() {
prettyPrint();
});
</script>
-? }
-
+: }
</body>
</html>
-@@ index.mt
-? extends 'base'
+@@ index.tx
+: cascade 'base.tx'
-? block content => sub {
+: around content -> {
<h2 class="subheader">New Entry</h2>
-? fillinform( $c->req, sub {
+: block form | fillinform( $c.req ) -> {
<form method="post" action="/add" id="nopaste">
<textarea name="body" rows="20" cols="60"></textarea>
<label for="nick">nick</label>
<input type="text" id="nick" name="nick" value="" size="21" />
<input type="submit" id="post_nopaste" value="POST" />
</form>
-? })
+: } # block form
<h2 class="subheader">List</h2>
-? for my $entry ( @$entries ) {
+: for $entries -> $entry {
<div class="entry">
<pre class="prettyprint">
-<?= $entry->{body} ?>
+<: $entry.body :>
</pre>
-<div class="entry_meta"><a href="<?= $c->req->uri_for('/entry/' . $entry->{id}) ?>" class="date"><?= $entry->{ctime} ?></a> / <span class="nick"><?= $entry->{nick} ?></span></div>
+<div class="entry_meta"><a href="<: $c.req.uri_for('/entry/' ~ $entry.id) :>" class="date"><: $entry.ctime :></a> / <span class="nick"><: $entry.nick :></span></div>
</div>
-? }
+: }
<p class="paging">
-? my $offset = $c->req->param('offset') || 0;
-? if ( $offset >= 10 ) {
-<a href="<?= $c->req->uri_for('/', [ 'offset' => ($offset - 10) ] ) ?>">Prev</a>
-? }
-? if ( $next ) {
-<a href="<?= $c->req->uri_for('/', [ 'offset' => ($offset + 10) ] ) ?>">Next</a>
-? }
+: my $offset = $c.req.param('offset') || 0
+: if $offset >= 10 {
+<a href="<: $c.req.uri_for('/', [ 'offset' => ($offset - 10) ] ) :>">Prev</a>
+: }
+: if $next {
+<a href="<: $c.req.uri_for('/', [ 'offset' => ($offset + 10) ] ) :>">Next</a>
+: }
</p>
-? } #block content
+: } #block content
-? block javascript => sub {
+: around javascript -> {
<script type="text/javascript">
$(function() {
prettyPrint();
@@ -199,19 +198,18 @@ $(function() {
}
});
</script>
-? } #block javascript
-
+: } #block javascript
-@@ entry.mt
-? extends 'base'
+@@ entry.tx
+: cascade 'base.tx'
-? block content => sub {
-<h2 class="subheader"><a href="<?= $c->req->uri_for('/entry/' . $entry->{id}) ?>"><?= $c->req->uri_for('/entry/' . $entry->{id}) ?></a></h2>
+: around content -> {
+<h2 class="subheader"><a href="<: $c.req.uri_for('/entry/' ~ $entry.id) :>"><: $c.req.uri_for('/entry/' ~ $entry.id) :></a></h2>
<div class="entry">
<pre class="prettyprint">
-<?= $entry->{body} ?>
+<: $entry.body :>
</pre>
-<div class="entry_meta"><a href="<?= $c->req->uri_for('/entry/' . $entry->{id}) ?>" class="date"><?= $entry->{ctime} ?></a> / <span class="nick"><?= $entry->{nick} ?></span></div>
+<div class="entry_meta"><a href="<: $c.req.uri_for('/entry/' ~ $entry.id) :>" class="date"><: $entry.ctime :></a> / <span class="nick"><: $entry.nick :></span></div>
</div>
-? } # content
+: } # content
View
100 lib/Shirahata.pm
@@ -11,6 +11,10 @@ use Cwd qw/realpath/;
use File::Basename qw/dirname/;
use Path::Class;
use Net::IP;
+use Class::ISA;
+use Text::Xslate;
+use Data::Section::Simple;
+use HTML::FillInForm::Lite qw//;
__PACKAGE__->mk_accessors(qw/root_dir/);
our @EXPORT = qw/get post any/;
@@ -23,11 +27,12 @@ sub import {
if ( $name && $name =~ /^-base/ ) {
if ( ! $caller->isa($class) && $caller ne 'main' ) {
push @{"$caller\::ISA"}, $class;
- for my $func (@EXPORT) {
- *{"$caller\::$func"} = \&$func;
- }
}
-
+ }
+ if ( $name && $name =~ /^-(?:base|import)/ ) {
+ for my $func (@EXPORT) {
+ *{"$caller\::$func"} = \&$func;
+ }
}
}
strict->import;
@@ -96,7 +101,48 @@ sub psgi {
sub build_app {
my $self = shift;
-
+
+ my @isa = Class::ISA::super_path(ref $self);
+ unshift @isa, ref $self;
+
+ my @inheri;
+ for my $parent ( @isa ) {
+ last if $parent eq __PACKAGE__;
+ push @inheri, $parent;
+ }
+
+ #router
+ my $router = Router::Simple->new;
+ for my $parent ( @inheri ) {
+ $router->connect(@{$_}) for @{$parent->router};
+ }
+
+ #template
+ my %templates;
+ for my $parent ( @inheri ) {
+ my $reader = Data::Section::Simple->new($parent);
+ my $template_hashref = $reader->get_data_section;
+ next if ! $template_hashref;
+ %templates = ( %$template_hashref, %templates );
+ }
+
+ #xslate
+ my $tx = Text::Xslate->new(
+ path => [ \%templates ],
+ cache => 2,
+ input_layer => '',
+ function => {
+ fillinform => sub {
+ my $q = shift;
+ return sub {
+ my ($html) = @_;
+ my $fif = HTML::FillInForm::Lite->new(layer => ':raw');
+ return Text::Xslate::mark_raw( $fif->fill( \$html, $q ) );
+ }
+ }
+ },
+ );
+
sub {
my $env = shift;
my $psgi_res;
@@ -106,13 +152,13 @@ sub build_app {
$s_res->content_type('text/html; charset=UTF-8');
my $c = Shirahata::Connection->new({
- klass => ref $self,
+ tx => $tx,
req => $s_req,
res => $s_res,
stash => {},
});
- if ( my $p = $self->router->match($env) ) {
+ if ( my $p = $router->match($env) ) {
my $code = delete $p->{action};
return $self->ise('uri match but no action found') unless $code;
@@ -147,9 +193,13 @@ sub build_app {
my $_ROUTER={};
sub router {
- my $class = ref $_[0] ? ref $_[0] : $_[0];
+ my $klass = shift;
+ my $class = ref $klass ? ref $klass : $klass;
if ( !$_ROUTER->{$class} ) {
- $_ROUTER->{$class} = Router::Simple->new();
+ $_ROUTER->{$class} = [];
+ }
+ if ( @_ ) {
+ push @{ $_ROUTER->{$class} }, [@_];
}
$_ROUTER->{$class};
}
@@ -158,7 +208,7 @@ sub _any($$$;$) {
my $class = shift;
if ( @_ == 3 ) {
my ( $methods, $pattern, $code ) = @_;
- $class->router->connect(
+ $class->router(
$pattern,
{ action => $code },
{ method => [ map { uc $_ } @$methods ] }
@@ -166,7 +216,7 @@ sub _any($$$;$) {
}
else {
my ( $pattern, $code ) = @_;
- $class->router->connect(
+ $class->router(
$pattern,
{ action => $code }
);
@@ -195,9 +245,8 @@ package Shirahata::Connection;
use strict;
use warnings;
use base qw/Class::Accessor::Fast/;
-use Text::MicroTemplate::DataSectionEx qw//;
-__PACKAGE__->mk_accessors(qw/req res stash args klass/);
+__PACKAGE__->mk_accessors(qw/req res stash args tx/);
*request = \&req;
*response = \&res;
@@ -212,12 +261,7 @@ sub render {
%args,
);
- my $mt = Text::MicroTemplate::DataSectionEx->new(
- package => $self->klass,
- package_name => 'Shirahata::TemplateFilters',
- template_args => \%vars
- );
- my $body = $mt->render($file);
+ my $body = $self->tx->render($file, \%vars);
$self->res->status( 200 );
$self->res->content_type('text/html; charset=UTF-8');
$self->res->body( $body );
@@ -226,24 +270,6 @@ sub render {
1;
-package Shirahata::TemplateFilters;
-
-use strict;
-use warnings;
-use HTML::FillInForm::Lite qw//;
-
-sub fillinform {
- my $q = shift;
- my $code = shift;
- my $mteref = $Shirahata::TemplateFilters::_MTEREF ||
- $Shirahata::TemplateFilters::_MTEREF::_MTREF;
- $code->();
- my $fif = HTML::FillInForm::Lite->new(layer => ':raw');
- $$mteref = $fif->fill($mteref, $q);
-}
-
-1;
-
package Shirahata::Request;
use strict;
Please sign in to comment.
Something went wrong with that request. Please try again.