Permalink
Browse files

add View::JSON

  • Loading branch information...
1 parent 887e279 commit 1a4359eab71d0e395b0f5623b95d41f42dec6118 @nekokak committed Sep 28, 2009
View
@@ -4,8 +4,14 @@
my $home = container('home');
return +{
- tmpl => {
- path => $home->file('assets/tmpl')->stringify,
- options => '',
+ view => {
+ tt => +{
+ path => $home->file('assets/tmpl')->stringify,
+ options => '',
+ },
+ json => +{
+ stash_key => 'json',
+ callback_param => 'callback',
+ },
},
};
@@ -12,5 +12,11 @@ sub dispatch_index {
}
}
+sub dispatch_json {
+ my ($class, $c) = @_;
+ $c->stash->{json} = +{name => 'nekokak'};
+ $c->view('JSON');
+}
+
1;
@@ -6,6 +6,10 @@ on '/' => run {
return 'Root', 'index', FALSE, +{};
};
+on '/json' => run {
+ return 'Root', 'json', FALSE, +{ };
+};
+
on '/(.+)' => run {
return 'Root', 'index', FALSE, +{ p => $1 };
};
View
@@ -0,0 +1,41 @@
+package Kamui::View::JSON;
+use Kamui;
+use base 'Kamui::View';
+use JSON::XS;
+
+sub render {
+ my ($class, $context) = @_;
+
+ my $data = $context->stash->{$context->conf->{view}->{json}->{stash_key} || 'json'};
+ my $cb_param = $context->conf->{view}->{json}->{callback_param} || 'callback';
+ my $cb = $cb_param ? _validate_callback_param($context->req->param($cb_param)||'') : undef;
+
+ my $json = encode_json($data);
+
+ my $content_type;
+ if (($context->req->user_agent || '') =~ /Opera/) {
+ $content_type = 'application/x-javascript; charset=utf-8';
+ } else {
+ $content_type = 'application/json; charset=utf-8';
+ }
+
+ my $output;
+ ## add UTF-8 BOM if the client is Safari ### XXXX
+ if (($context->req->user_agent || '') =~ m/Safari/) {
+ $output = "\xEF\xBB\xBF";
+ }
+
+ $output .= "$cb(" if $cb;
+ $output .= $json;
+ $output .= ");" if $cb;
+
+ return [ 200, [ 'Content-Type' => $content_type ], [$output] ];
+}
+
+sub _validate_callback_param {
+ my $param = shift;
+ $param =~ /^[a-zA-Z0-9\.\_\[\]]+$/ ? $param : undef;
+}
+
+1;
+
View
@@ -6,6 +6,7 @@ use File::Spec;
use Template::Stash::EscapeHTML;
use HTML::Entities;
use String::CamelCase qw/decamelize/;
+use Encode;
sub render {
my ($class, $context) = @_;
@@ -21,8 +22,8 @@ sub render {
html_unescape => sub { HTML::Entities::decode_entities(shift) },
},
COMPILE_DIR => '/tmp/' . $ENV{USER} . "/",
- INCLUDE_PATH => [ '.', File::Spec->catfile($context->conf->{tmpl}->{path}) ],
- %{ $context->conf->{tmpl}->{options} || {} },
+ INCLUDE_PATH => [ '.', File::Spec->catfile($context->conf->{view}->{tt}->{path}) ],
+ %{ $context->conf->{view}->{tt}->{options} || {} },
);
$tt->process(
$template,
@@ -33,7 +34,7 @@ sub render {
\my $output
) or die $@;
- $output;
+ return [ 200, [ 'Content-Type' => 'text/html' ], [Encode::encode('utf8',$output)] ];
}
sub guess_filename {
View
@@ -6,15 +6,24 @@ use Encode;
sub new {
my $class = shift;
bless {
- view => 'Kamui::View::TT',
+ _view => 'Kamui::View::TT',
@_
}, $class;
}
sub req { $_[0]->{req} }
sub app { $_[0]->{app} }
sub dispatch_rule { $_[0]->{dispatch_rule} }
-sub view : lvalue { $_[0]->{view} }
+sub view {
+ my ($self, $view) = @_;
+
+ if ($view) {
+ $self->{_view} = 'Kamui::View::'.$view;
+ } else {
+ $self->{_view};
+ }
+}
+
sub load_template : lvalue { $_[0]->{load_template} }
sub stash : lvalue {
my $self = shift;
@@ -26,9 +35,7 @@ sub render {
my $self = shift;
$self->load_class($self->view);
- my $out = $self->view->render($self);
-
- return [ 200, [ 'Content-Type' => 'text/html' ], [Encode::encode('utf8',$out)] ];
+ $self->view->render($self);
}
sub is_redirect { $_[0]->{is_redirect} }

0 comments on commit 1a4359e

Please sign in to comment.