[Jifty-commit] r1045 - in jifty/branches/jifty-jsan: .
lib/Jifty/Script lib/Jifty/View/Static
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Sat May 13 16:41:17 EDT 2006
Author: trs
Date: Sat May 13 16:41:14 2006
New Revision: 1045
Added:
jifty/branches/jifty-jsan/lib/Jifty/Script/Plugin.pm
Modified:
jifty/branches/jifty-jsan/ (props changed)
jifty/branches/jifty-jsan/lib/Jifty/Continuation.pm
jifty/branches/jifty-jsan/lib/Jifty/Dispatcher.pm
jifty/branches/jifty-jsan/lib/Jifty/Plugin.pm
jifty/branches/jifty-jsan/lib/Jifty/Request.pm
jifty/branches/jifty-jsan/lib/Jifty/View/Static/Handler.pm
jifty/branches/jifty-jsan/lib/Jifty/Web.pm
Log:
r12256 at zot (orig r1038): alexmv | 2006-05-12 16:14:54 -0400
r12966 at zoq-fot-pik: chmrr | 2006-05-12 16:14:48 -0400
* Remove confusing, undocumented, and unnecessary 'next_show'
r12257 at zot (orig r1039): alexmv | 2006-05-12 17:04:13 -0400
r12968 at zoq-fot-pik: chmrr | 2006-05-12 17:04:05 -0400
* Plugin rule reodering
r12258 at zot (orig r1040): alexmv | 2006-05-12 18:09:20 -0400
r12970 at zoq-fot-pik: chmrr | 2006-05-12 18:09:12 -0400
* jifty plugin --name Something
r12266 at zot (orig r1043): trs | 2006-05-13 16:33:10 -0400
r12265 at zot: tom | 2006-05-13 16:32:56 -0400
Allow for MIME types to be overridden. The included override is needed because Opera chokes with ajax-fetched JS otherwise.
r12268 at zot (orig r1044): trs | 2006-05-13 16:38:58 -0400
r12267 at zot: tom | 2006-05-13 16:38:53 -0400
Put a note in a code
Modified: jifty/branches/jifty-jsan/lib/Jifty/Continuation.pm
==============================================================================
--- jifty/branches/jifty-jsan/lib/Jifty/Continuation.pm (original)
+++ jifty/branches/jifty-jsan/lib/Jifty/Continuation.pm Sat May 13 16:41:14 2006
@@ -214,13 +214,7 @@
# Enter the request in the continuation, and handle it
Jifty->web->request(Clone::clone($self->request));
Jifty->web->handle_request();
-
- # Now we want to skip the rest of the
- # Jifty::Web->handle_request that we were called from. Pop up
- # to the dispatcher
- Jifty::Dispatcher::next_show();
}
-
}
=head2 delete
Modified: jifty/branches/jifty-jsan/lib/Jifty/Dispatcher.pm
==============================================================================
--- jifty/branches/jifty-jsan/lib/Jifty/Dispatcher.pm (original)
+++ jifty/branches/jifty-jsan/lib/Jifty/Dispatcher.pm Sat May 13 16:41:14 2006
@@ -104,6 +104,34 @@
=cut
+=head1 Plugins and rule ordering
+
+By default, L<Jifty::Plugin> dispatcher rules are added in the order
+they are specified in the application's configuration file; that is,
+after all the plugin dispatchers have run in order, then tha
+application's dispatcher runs. It is possible to specify rules which
+should be reordered with respect to this rule, however. This us done
+by using a variant on the C<before> and C<after> syntax:
+
+ before plugin NAME =>
+ RULE(S);
+
+ after plugin NAME =>
+ RULE(S);
+
+C<NAME> may either be a string, which must match the plugin name
+exactly, or a regular expression, which is matched against the plugin
+name. The rule will be placed at the first boundry that it matches --
+that is, given a C<before plugin qr/^Jifty::Plugin::Auth::/> and both
+a C<Jifty::Plugin::Auth::Basic> and a C<Jifty::Plugin::Auth::Complex>,
+the rules will be placed before the first.
+
+C<RULES> may wither be a single C<before>, C<on>, C<under>, or
+C<after> rule to change the ordering of, or an array reference of
+rules to reorder.
+
+=cut
+
=head1 Data your dispatch routines has access to
=head2 request
@@ -213,10 +241,9 @@
Redirect to another URI.
+=head2 plugin
-=head2 next_show
-
-INTERNAL MAGIC YOU SHOULD NOT USE THAT ALEX SHOULD RENAME ;)
+See L</Plugins and rule odering>, above.
=cut
@@ -229,6 +256,8 @@
GET POST PUT HEAD DELETE OPTIONS
+ plugin
+
get next_rule last_rule
already_run
@@ -263,6 +292,8 @@
sub DELETE ($) { _qualify method => @_ }
sub OPTIONS ($) { _qualify method => @_ }
+sub plugin ($) { return { plugin => @_ } }
+
=head2 import
Jifty::Dispatcher is an L<Exporter>, that is, part of its role is to
@@ -284,7 +315,7 @@
no strict 'refs';
no warnings 'once';
- for (qw(RULES_RUN RULES_SETUP RULES_CLEANUP)) {
+ for (qw(RULES_RUN RULES_SETUP RULES_CLEANUP RULES_DEFERRED)) {
@{ $pkg . '::' . $_ } = ();
}
if ( @args != @_ ) {
@@ -328,7 +359,9 @@
my($pkg, $rule) = @_;
my $op = $rule->[0];
my $ruleset;
- if ( $op eq 'before' ) {
+ if ( ($op eq "before" or $op eq "after") and ref $rule->[1] and $rule->[1]{plugin} ) {
+ $ruleset = 'RULES_DEFERRED';
+ } elsif ( $op eq 'before' ) {
$ruleset = 'RULES_SETUP';
} elsif ( $op eq 'after' ) {
$ruleset = 'RULES_CLEANUP';
@@ -501,7 +534,6 @@
die "LAST RULE";
}
-sub next_show { last HANDLE_WEB }
=head2 _do_under
@@ -698,7 +730,6 @@
request->path($path);
$self->render_template(request->path);
-
last_rule;
}
@@ -814,7 +845,10 @@
}
# All precondition passed, get original condition literal
- return $self->_match( $cond->{''} );
+ return $self->_match( $cond->{''} ) if $cond->{''};
+
+ # Or, if we don't have a literal, we win.
+ return 1;
};
if ( my $err = $@ ) {
warn "$self _match failed: $err";
@@ -844,6 +878,12 @@
lc( $self->{cgi}->method ) eq lc($method);
}
+sub _match_plugin {
+ my ( $self, $plugin ) = @_;
+ warn "Deferred check shouldn't happen";
+ return 0;
+}
+
=head2 _compile_condition CONDITION
Takes a condition defined as a simple string ad return it as a regex
@@ -971,8 +1011,7 @@
my $self = shift;
my $template = shift;
- return Jifty->handler->mason->interp->comp_exists( $template);
-
+ return Jifty->handler->mason->interp->comp_exists( $template);
}
@@ -1023,14 +1062,78 @@
sub import_plugins {
my $self = shift;
+
+ # Find the deferred rules
+ my @deferred;
+ push @deferred, $_->dispatcher->rules('DEFERRED') for Jifty->plugins;
+ push @deferred, $self->rules('DEFERRED');
+
+ # XXX TODO: Examine @deferred and find rles that cannot fire
+ # because they match no plugins; they should become un-deferred in
+ # the appropriate group. This is so 'before plugin qr/Auth/' runs
+ # even if we have no auth plugin
+
for my $stage (qw/SETUP RUN CLEANUP/) {
+ my @groups;
+ push @groups, {name => ref $_, rules => [$_->dispatcher->rules($stage)]} for Jifty->plugins;
+ push @groups, {name => 'Jifty', rules => [$self->rules($stage)]};
+
+ my @left;
my @rules;
- push @rules, $_->dispatcher->rules($stage) for Jifty->plugins;
- push @rules, $self->rules($stage);
+ for (@groups) {
+ my $name = $_->{name};
+ my @group_rules = @{$_->{rules}};
+
+ # XXX TODO: 'after' rules should possibly be placed after
+ # the *last* thing they could match
+ push @rules, $self->_match_deferred(\@deferred, before => $name, $stage);
+ push @rules, @group_rules;
+ push @rules, $self->_match_deferred(\@deferred, after => $name, $stage);
+ }
no strict 'refs';
@{ $self . "::RULES_$stage" } = @rules;
}
+ if (@deferred) {
+ warn "Leftover unmatched deferred rules: ".YAML::Dump(\@deferred);
+ }
+}
+
+sub _match_deferred {
+ my $self = shift;
+ my ($deferred, $time, $name, $stage) = @_;
+ my %stages = (SETUP => "before", RUN => "on", CLEANUP => "after");
+ $stage = $stages{$stage};
+
+ my @matches;
+ for my $op (@{$deferred}) {
+ # Only care if we're on the correct side of the correct plugin
+ next unless $op->[0] eq $time;
+
+ # Regex or string match, appropriately
+ next unless (
+ ref $op->[1]{plugin}
+ ? ( $name =~ $op->[1]{plugin} )
+ : ( $op->[1]{plugin} eq $name ) );
+
+ # Find the list of subrules
+ my @subrules = ref $op->[2] eq "ARRAY" ? @{$op->[2]} : ($op->[2]);
+
+ # Only toplevel rules make sense (before, after, on)
+ warn "Invalid subrule ".$_->[0] for grep {$_->[0] !~ /^(before|on|after)$/} @subrules;
+ @subrules = grep {$_->[0] =~ /^(before|on|after)$/} @subrules;
+
+ # Only match if the stage matches
+ push @matches, grep {$_->[0] eq $stage} @subrules;
+ @subrules = grep {$_->[0] ne $stage} @subrules;
+
+ $op->[2] = [@subrules];
+ }
+
+ # Clean out any completely matched rules
+ @$deferred = grep {@{$_->[2]}} @$deferred;
+
+ return @matches;
}
1;
Modified: jifty/branches/jifty-jsan/lib/Jifty/Plugin.pm
==============================================================================
--- jifty/branches/jifty-jsan/lib/Jifty/Plugin.pm (original)
+++ jifty/branches/jifty-jsan/lib/Jifty/Plugin.pm Sat May 13 16:41:14 2006
@@ -11,7 +11,25 @@
Plugins are like mini-apps. They come in packages with share
directories which provide static and template files; they provide
-actions; they have dispatcher rules.
+actions; they have dispatcher rules.
+
+To use a plugin in your Jifty application, find the C<Plugins:> line
+in the C<config.yml> file:
+
+ Plugins:
+ - SpiffyThing: {}
+ - SomePlugin:
+ arguments: to
+ the: constructor
+
+The dispatcher for a plugin should live in
+C<Jifty::Plugin::I<name>::Disptcher>; it is written like any other
+L<Jifty::Dispatcher>. Plugin dispatcher rules are checked before the
+application's rules; however, see L<Jifty::Dispatcher/Plugins and rule
+ordering> for how to manually specify exceptions to this.
+
+Actions and models under a plugin's namespace are automatically
+discovered and made available to applications.
=cut
Modified: jifty/branches/jifty-jsan/lib/Jifty/Request.pm
==============================================================================
--- jifty/branches/jifty-jsan/lib/Jifty/Request.pm (original)
+++ jifty/branches/jifty-jsan/lib/Jifty/Request.pm Sat May 13 16:41:14 2006
@@ -435,7 +435,9 @@
=head2 call_continuation
Calls the L<Jifty::Continuation> associated with this request, if
-there is one.
+there is one. Returns true if the continuation was called
+successfully -- if calling the continuation requires a redirect, this
+function will throw an exception to its enclosing dispatcher.
=cut
@@ -446,6 +448,7 @@
$self->log->debug("Calling continuation $cont");
$self->continuation(Jifty->web->session->get_continuation($cont));
$self->continuation->call;
+ return 1;
}
=head2 path
Added: jifty/branches/jifty-jsan/lib/Jifty/Script/Plugin.pm
==============================================================================
--- (empty file)
+++ jifty/branches/jifty-jsan/lib/Jifty/Script/Plugin.pm Sat May 13 16:41:14 2006
@@ -0,0 +1,149 @@
+use warnings;
+use strict;
+
+package Jifty::Script::Plugin;
+use base qw'App::CLI::Command Class::Accessor::Fast';
+
+use File::Copy;
+use Jifty::Config;
+use Jifty::YAML;
+use File::Basename;
+
+__PACKAGE__->mk_accessors(qw/prefix dist_name mod_name lib_dir/);
+
+
+=head1 NAME
+
+Jifty::Script::Plugin - Create the skeleton of a Jifty plugin
+
+=head1 DESCRIPTION
+
+Creates a skeleton of a new L<Jifty::Plugin>.
+
+=head2 options
+
+This script only takes one option, C<--name>, which is required; it is
+the name of the plugin to create; this will be prefixed with
+C<Jifty::Plugin::> automatically. Jifty will create a directory with
+that name, and place all of the files it creates inside that
+directory.
+
+=cut
+
+sub options {
+ (
+ 'n|name=s' => 'name',
+ )
+}
+
+=head2 run
+
+Create a directory for the application, a skeleton directory
+structure, and a C<Makefile.PL> for you application.
+
+=cut
+
+sub run {
+ my $self = shift;
+
+ $self->prefix( $self->{name} ||'');
+
+ unless ($self->prefix =~ /\w+/ ) { die "You need to give your new Jifty app a --name"."\n";}
+ $self->prefix( $self->prefix );
+
+ # Turn my-plugin-name into My::Plugin::Name.
+ $self->mod_name ("Jifty::Plugin::" . join ("::", map { ucfirst } split (/\-/, $self->prefix)));
+ $self->dist_name("Jifty-Plugin-".$self->prefix);
+ $self->lib_dir(join("/",grep{$_} split '::', $self->mod_name));
+
+ print("Creating new plugin ".$self->mod_name."\n");
+ $self->_make_directories();
+ $self->_write_makefile();
+ $self->_write_default_files();
+}
+
+sub _write_makefile {
+ my $self = shift;
+ my $prefix = $self->prefix;
+ # Write a makefile
+ open(MAKEFILE, ">$prefix/Makefile.PL") or die "Can't write Makefile.PL: $!";
+ print MAKEFILE <<"EOT";
+use inc::Module::Install;
+name('@{[$self->dist_name]}');
+version('0.01');
+requires('Jifty' => '@{[$Jifty::VERSION]}');
+
+install_share;
+
+WriteAll;
+EOT
+ close MAKEFILE;
+}
+
+sub _write_default_files {
+ my $self = shift;
+ my $mod_name = $self->mod_name;
+ my $prefix = $self->prefix;
+ my $lib = $self->lib_dir;
+ open(PLUGIN, ">$prefix/lib/$lib.pm") or die "Can't write $prefix/$lib.pm: $!";
+ print PLUGIN <<"EOT";
+use strict;
+use warnings;
+
+package $mod_name;
+use base qw/Jifty::Plugin/;
+
+# Your plugin goes here. If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+1;
+EOT
+ close PLUGIN;
+
+ open(DISPATCHER, ">$prefix/lib/$lib/Dispatcher.pm") or die "Can't write $prefix/lib/$lib/Dispatcher.pm: $!";
+ print DISPATCHER <<"EOT";
+use strict;
+use warnings;
+
+package @{[$mod_name]}::Dispatcher;
+use Jifty::Dispatcher -base;
+
+# Put any plugin-specific dispatcher rules here.
+
+EOT
+}
+
+sub _make_directories {
+ my $self = shift;
+
+ mkdir($self->prefix);
+ my @dirs = qw( lib );
+ my @dir_parts = split('/',$self->lib_dir);
+ push @dirs, join('/', 'lib', @dir_parts[0..$_]) for 0.. at dir_parts-1;
+
+ @dirs = (@dirs, $self->_directories);
+
+ foreach my $dir (@dirs) {
+ $dir =~ s/__APP__/$self->lib_dir/e;
+ print("Creating directory $dir\n");
+ mkdir( $self->prefix."/$dir") or die "Can't create ". $self->prefix."/$dir: $!";
+ }
+}
+
+sub _directories {
+ return qw(
+ doc
+ share
+ share/po
+ share/web
+ share/web/templates
+ share/web/static
+ lib/__APP__/Model
+ lib/__APP__/Action
+ t
+ );
+}
+
+
+1;
+
Modified: jifty/branches/jifty-jsan/lib/Jifty/View/Static/Handler.pm
==============================================================================
--- jifty/branches/jifty-jsan/lib/Jifty/View/Static/Handler.pm (original)
+++ jifty/branches/jifty-jsan/lib/Jifty/View/Static/Handler.pm Sat May 13 16:41:14 2006
@@ -135,6 +135,17 @@
my $self = shift;
my $local_path = shift;
+ # The key is the file extension, the value is the MIME type to send.
+ my %type_override = (
+ # MIME::Types returns application/javascript for .js, but Opera
+ # chokes on ajax-fetched JS that has a type other than the one below
+ # JSAN.js fetches JS via Ajax when it loads JSAN modules
+ 'js' => 'application/x-javascript',
+ );
+
+ return ($type_override{$1})
+ if $local_path =~ /\.(.+)$/ and defined $type_override{$1};
+
my $mimeobj = $mime->mimeTypeOf($local_path);
my $mime_type = (
$mimeobj
Modified: jifty/branches/jifty-jsan/lib/Jifty/Web.pm
==============================================================================
--- jifty/branches/jifty-jsan/lib/Jifty/Web.pm (original)
+++ jifty/branches/jifty-jsan/lib/Jifty/Web.pm Sat May 13 16:41:14 2006
@@ -281,8 +281,8 @@
}
$self->session->set_cookie();
- $self->request->call_continuation
- if $self->response->success;
+ # If there's a continuation call, don't do the rest of this
+ return if $self->response->success and $self->request->call_continuation;
$self->redirect if $self->redirect_required;
$self->request->do_mapping;
More information about the Jifty-commit
mailing list