Skip to content

Commit

Permalink
Merge branch 'release/1.3079_05'
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexis Sukrieh committed Oct 18, 2011
2 parents ce7b0de + cd9e524 commit 12d646a
Show file tree
Hide file tree
Showing 35 changed files with 157 additions and 101 deletions.
14 changes: 14 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
1.3079_05 02.10.2011

[ API CHANGES ]
* Deprecation of 'before', 'before_template' and 'after' in favor of hook
(Alberto Simões)

[ ENHANCEMENTS]
* Add support for the HTTP 'PATCH' verb (David Precious)

[ BUG FIXES ]
* Minor corrections (jamhed, felixdo)
* Log if a view and or a layout is not found (Alberto Simões, reported
by David Previous)

1.3079_04 02.10.2011

[ ENHANCEMENTS ]
Expand Down
3 changes: 0 additions & 3 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,6 @@ t/17_apps/00_base.t
t/17_apps/01_settings.t
t/17_apps/02_load_app.t
t/17_apps/03_prefix.t
t/17_apps/04_issue_91.t
t/17_apps/05_api.t
t/19_dancer/01_script.t
t/19_dancer/02_script_version_from.t
Expand Down Expand Up @@ -309,8 +308,6 @@ t/25_exceptions/views/layouts/main.tt
t/lib/EasyMocker.pm
t/lib/Forum.pm
t/lib/LinkBlocker.pm
t/lib/MyApp.pm
t/lib/MyAppFoo.pm
t/lib/TestApp.pm
t/lib/TestAppUnicode.pm
t/lib/TestPlugin.pm
Expand Down
61 changes: 52 additions & 9 deletions lib/Dancer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use warnings;
use Carp;
use Cwd 'realpath';

our $VERSION = '1.3079_04';
our $VERSION = '1.3079_05';
our $AUTHORITY = 'SUKRIA';

use Dancer::App;
Expand Down Expand Up @@ -67,6 +67,7 @@ our @EXPORT = qw(
params
pass
path
patch
post
prefix
push_header
Expand Down Expand Up @@ -99,10 +100,26 @@ our @EXPORT = qw(

# Dancer's syntax

sub after { Dancer::Hook->new('after', @_) }
sub after {
Dancer::Deprecation->deprecated(reason => "use hooks!",
version => '1.3080',
fatal => 0);
Dancer::Hook->new('after', @_);
}
sub before {
Dancer::Deprecation->deprecated(reason => "use hooks!",
version => '1.3080',
fatal => 0);
Dancer::Hook->new('before', @_);
}
sub before_template {
Dancer::Deprecation->deprecated(reason => "use hooks!",
version => '1.3080',
fatal => 0);
Dancer::Hook->new('before_template', @_);
}

sub any { Dancer::App->current->registry->any_add(@_) }
sub before { Dancer::Hook->new('before', @_) }
sub before_template { Dancer::Hook->new('before_template', @_) }
sub captures { Dancer::SharedData->request->params->{captures} }
sub cookie { Dancer::Cookies->cookie( @_ ) }
sub cookies { Dancer::Cookies->cookies }
Expand Down Expand Up @@ -142,6 +159,7 @@ sub options { Dancer::App->current->registry->universal_add('options', @
sub params { Dancer::SharedData->request->params(@_) }
sub param { params->{$_[0]} }
sub pass { Dancer::SharedData->response->pass(1) }
sub patch { Dancer::App->current->registry->universal_add('patch', @_) }
sub path { Dancer::FileUtils::path(@_) }
sub post { Dancer::App->current->registry->universal_add('post', @_) }
sub prefix { Dancer::App->current->set_prefix(@_) }
Expand Down Expand Up @@ -488,7 +506,7 @@ your app. You can control the exporting through the normal
L<Exporter> mechanism. For example:
# Just export the route controllers
use Dancer qw(before after get post);
use Dancer qw(before after get post put patch);
# Export everything but pass to avoid clashing with Test::More
use Test::More;
Expand Down Expand Up @@ -548,11 +566,13 @@ Add a hook at the B<after> position:
after sub {
my $response = shift;
# do something with request
# do something with response, e.g.:
$response->header('X-Beer' => 'Yes please');
};
The anonymous function which is given to C<after> will be executed after
having executed a route.
having executed a route, but before the response is returned (so you can modify
the response here, if you need to)..
You can define multiple after filters, using the C<after> helper as
many times as you wish; each filter will be executed, in the order you added
Expand Down Expand Up @@ -1010,9 +1030,13 @@ by the layout
=item after
This is an alias for 'after'.
This is an alias for C<after>.
This hook receives as argument a L<Dancer::Response> object.
This hook runs after a request has been processed, but before the response is
sent.
It receives a L<Dancer::Response> object, which it can modify
if it needs to make changes to the response which is about to be sent.
hook after => sub {
my $response = shift;
Expand Down Expand Up @@ -1130,6 +1154,25 @@ You should always C<return> after calling C<pass>:
}
};
=head2 patch
Defines a route for HTTP B<PATCH> requests to the given URL:
patch '/resource' => sub { ... };
(C<PATCH> is a relatively new and not-yet-common HTTP verb, which is intended to
work as a "partial-PUT", transferring just the changes; please see
L<http://tools.ietf.org/html/rfc5789|RFC5789> for further details.)
Please be aware that, if you run your app in standalone mode, C<PATCH> requests
will not reach your app unless you have a new version of L<HTTP::Server::Simple>
which accepts C<PATCH> as a valid verb. The current version at time of writing,
C<0.44>, does not. A pull request has been submitted to add this support, which
you can find at:
L<https://github.com/bestpractical/http-server-simple/pull/1>
=head2 path
Concatenates multiple paths together, without worrying about the underlying
Expand Down
8 changes: 8 additions & 0 deletions lib/Dancer/Cookbook.pod
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,14 @@ wouldn't store your users passwords in the clear, would you?)) follows:



=head3 Retrieve complete hash stored in session

Get complete hash stored in session:

my $hash = session;



=head1 APPEARANCE

=head2 Using templates - views and layouts
Expand Down
4 changes: 2 additions & 2 deletions lib/Dancer/Deployment.pod
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ Start by creating a simple app.psgi file:
my $app1 = sub {
my $env = shift;
local $ENV{DANCER_APPDIR} = '/Users/franck/tmp/app1';
setting appdir => '/Users/franck/tmp/app1';
load_app "app1";
Dancer::App->set_running_app('app1');
setting appdir => '/Users/franck/tmp/app1';
Dancer::Config->load;
my $request = Dancer::Request->new( env => $env );
Dancer->dance($request);
Expand All @@ -187,9 +187,9 @@ Start by creating a simple app.psgi file:
my $app2 = sub {
my $env = shift;
local $ENV{DANCER_APPDIR} = '/Users/franck/tmp/app2';
setting appdir => '/Users/franck/tmp/app2';
load_app "app2";
Dancer::App->set_running_app('app2');
setting appdir => '/Users/franck/tmp/app2';
Dancer::Config->load;
my $request = Dancer::Request->new( env => $env );
Dancer->dance($request);
Expand Down
8 changes: 4 additions & 4 deletions lib/Dancer/Introduction.pod
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ method 'get', so only GET requests will be honoured by that route:
get '/hello/:name' => sub {
# do something

return "Hello ".params->{name};
return "Hello ".param('name');
};


Expand Down Expand Up @@ -121,13 +121,13 @@ be set in the params hashref.


get '/hello/:name' => sub {
"Hey ".params->{name}.", welcome here!";
"Hey ".param('name').", welcome here!";
};

Tokens can be optional, for example:

get '/hello/:name?' => sub {
"Hello there " . params->{name} || "whoever you are!";
"Hello there " . param('name') || "whoever you are!";
};


Expand Down Expand Up @@ -621,7 +621,7 @@ This is a possible webapp created with Dancer:
};

get '/hello/:name' => sub {
"Hello ".params->{name};
"Hello ".param('name');
};

# run the webserver
Expand Down
2 changes: 1 addition & 1 deletion lib/Dancer/Logger/Abstract.pm
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ sub format_message {
chomp $message;

if (setting('charset')) {
unless (setting('charset') eq "UTF-8" && Encode::is_utf8($message)) {
unless (uc setting('charset') eq "UTF-8" && Encode::is_utf8($message)) {
$message = Encode::encode(setting('charset'), $message);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Dancer/Plugin/Ajax.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use Dancer::Plugin;

register 'ajax' => \&ajax;

before sub {
hook before => sub {
if (request->is_ajax) {
content_type('text/xml');
}
Expand Down
5 changes: 5 additions & 0 deletions lib/Dancer/Request.pm
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ sub is_post { $_[0]->{method} eq 'POST' }
sub is_get { $_[0]->{method} eq 'GET' }
sub is_put { $_[0]->{method} eq 'PUT' }
sub is_delete { $_[0]->{method} eq 'DELETE' }
sub is_patch { $_[0]->{method} eq 'PATCH' }
sub header { $_[0]->{headers}->header($_[1]) }

# public interface compat with CGI.pm objects
Expand Down Expand Up @@ -678,6 +679,10 @@ Return true if the method requested by the client is 'GET'
Return true if the method requested by the client is 'HEAD'
=head2 is_patch()
Return true if the method requested by the client is 'PATCH'
=head2 is_post()
Return true if the method requested by the client is 'POST'
Expand Down
2 changes: 1 addition & 1 deletion lib/Dancer/Route/Registry.pm
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ sub register_route {
sub any_add {
my ($self, $pattern, @rest) = @_;

my @methods = qw(get post put delete options);
my @methods = qw(get post put patch delete options);

if (ref($pattern) eq 'ARRAY') {
@methods = @$pattern;
Expand Down
33 changes: 27 additions & 6 deletions lib/Dancer/Template/Abstract.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use strict;
use warnings;
use Carp;

use Dancer::Logger;
use Dancer::Factory::Hook;
use Dancer::FileUtils 'path';

Expand Down Expand Up @@ -41,9 +42,14 @@ sub layout {
my $layout_name = $self->_template_name($layout);
my $layout_path = path(Dancer::App->current->setting('views'), 'layouts', $layout_name);

my $full_content =
Dancer::Template->engine->render($layout_path,
{%$tokens, content => $content});
my $full_content;
if (-e $layout_path) {
$full_content = Dancer::Template->engine->render(
$layout_path, {%$tokens, content => $content});
} else {
$full_content = $content;
Dancer::Logger::error("Defined layout ($layout_name) was not found!");
}
$full_content;
}

Expand Down Expand Up @@ -126,16 +132,31 @@ sub template {
my ($class, $view, $tokens, $options) = @_;
my ($content, $full_content);

my $engine = Dancer::Template->engine;

# it's important that $tokens is not undef, so that things added to it via
# a before_template in apply_renderer survive to the apply_layout. GH#354
$tokens ||= {};
$options ||= {};

$content = $view ? Dancer::Template->engine->apply_renderer($view, $tokens)
: delete $options->{content};
if ($view) {
# check if the requested view exists
my $view_path = $engine->view($view);
if (-e $view_path) {
$content = $engine->apply_renderer($view, $tokens);
} else {
Dancer::Logger::error("Supplied view ($view) was not found.");
return Dancer::Error->new(
code => 500,
message => 'view not found',
)->render();
}
} else {
$content = delete $options->{content};
}

defined $content and $full_content =
Dancer::Template->engine->apply_layout($content, $tokens, $options);
$engine->apply_layout($content, $tokens, $options);

defined $full_content
and return $full_content;
Expand Down
8 changes: 7 additions & 1 deletion lib/Dancer/Tutorial.pod
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,13 @@ applications focus on the verbs which closely map to the CRUD (Create,
Retrieve, Update, Delete) operations most database driven applications need to
implement.

Dancer currently supports GET, PUT, POST, DELETE, OPTIONS which map to
In addition, the C<PATCH> verb was defined in
L<RFC5789|http://tools.ietf.org/html/rfc5789>, and is intended as a
"partial PUT" - sending just the changes required to the entity in question.
How this would be handled is down to your app, it will vary depending on the
type of entity in question and the serialisation in use.

Dancer currently supports GET, PUT/PATCH, POST, DELETE, OPTIONS which map to
Retrieve, Update, Create, Delete respectively. Let's take a look now at the
C</add> route handler which handles a POST operation.

Expand Down
2 changes: 1 addition & 1 deletion t/02_request/15_headers.t
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Test::TCP::test_tcp(
show_errors => 1,
startup_info => 0 );

after sub {
hook after => sub {
my $response = shift;
$response->header('X-Foo', 2);
};
Expand Down
10 changes: 5 additions & 5 deletions t/03_route_handler/05_filter.t
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ plan tests => 19;
{
my $i = 0;

before sub { content_type('text/xhtml'); };
before sub {
hook before => sub { content_type('text/xhtml'); };
hook before => sub {
if ( request->path_info eq '/redirect_from' ) {
redirect('/redirect_to');
}
Expand Down Expand Up @@ -53,7 +53,7 @@ plan tests => 19;

# filters and params
{
before sub {
hook before => sub {
return if request->path !~ /foo/;
ok( defined( params->{'format'} ),
"param format is defined in before filter" );
Expand All @@ -70,13 +70,13 @@ plan tests => 19;

# filter and halt
{
before sub {
hook before => sub {
unless (params->{'requested'}) {
return halt("stopped");
}
};

before sub {
hook before => sub {
unless (params->{'requested'}) {
halt("another halt");
}
Expand Down
Loading

0 comments on commit 12d646a

Please sign in to comment.