[Jifty-commit] r772 - in jifty/trunk: . lib/Jifty lib/Jifty/Templater lib/Jifty/View lib/Jifty/View/Mason

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Thu Mar 30 03:27:33 EST 2006


Author: jesse
Date: Thu Mar 30 03:27:32 2006
New Revision: 772

Added:
   jifty/trunk/lib/Jifty/View/
   jifty/trunk/lib/Jifty/View/Mason/
   jifty/trunk/lib/Jifty/View/Mason/Handler.pm
Removed:
   jifty/trunk/lib/Jifty/Templater/
Modified:
   jifty/trunk/   (props changed)
   jifty/trunk/README
   jifty/trunk/lib/Jifty/Everything.pm
   jifty/trunk/lib/Jifty/Handler.pm
   jifty/trunk/lib/Jifty/Web/PageRegion.pm

Log:
 r10549 at hualien:  jesse | 2006-03-30 17:18:28 +0900
 * Audrey had a good suggestion. ::View


Modified: jifty/trunk/README
==============================================================================
--- jifty/trunk/README	(original)
+++ jifty/trunk/README	Thu Mar 30 03:27:32 2006
@@ -1,79 +0,0 @@
-NAME
-    Jifty -- Just Do It
-
-DESCRIPTION
-    Yet another web framework.
-
-  What's cool about Jifty? (Buzzwords)
-    DRY (Don't Repeat Yourself)
-        Jifty tries not to make you say things more than once.
-
-    Full-stack
-        Out of the proverbial box, Jifty comes with one way to do everything
-        you should need to do: One database mapper, one templating system,
-        one web services layer, one AJAX toolkit, one set of handlers for
-        standalone or FastCGI servers. We work hard to make all the bits
-        play well together, so you don't have to.
-
-    Continuations
-        With Jifty, it's easy to let the user go off and do something else,
-        like fill out a wizard, look something up in the help system or go
-        twiddle their preferences and come right back to where they were.
-
-    Form-based dispatch
-        This is one of the things that Jifty does that we've not seen
-        anywhere else. Jifty owns your form rendering and processing. This
-        means you never need to write form handling logic. All you say is "I
-        want an input for this argument here" and Jifty takes care of the
-        rest. (Even autocomplete and validation)
-
-    A Pony
-        Jifty is the only web application framework that comes with a pony.
-
-  Introduction
-    If this is your first time using Jifty, Jifty::Manual::Tutorial is
-    probably a better place to start.
-
-METHODS
-  new PARAMHASH
-    This class method instantiates a new "Jifty" object. This object deals
-    with configuration files, logging and database handles for the system.
-    Most of the time, the server will call this for you to set up your
-    "Jifty" object. If you are writing command-line programs htat want to
-    use your libraries (as opposed to web services) you will need to call
-    this yourself.
-
-    See Jifty::Config for details on how to configure your Jifty
-    application.
-
-   Arguments
-    no_handle
-        If this is set to true, Jifty will not create a Jifty::Handle and
-        connect to a database. Only use this if you're about to drop the
-        database or do something extreme like that; most of Jifty expects
-        the handle to exist. Defaults to false.
-
-  config
-    An accessor for the Jifty::Config object that stores the configuration
-    for the Jifty application.
-
-  logger
-    An accessor for our Jifty::Logger object for the application.
-
-  handle
-    An accessor for the Jifty::Handle object that stores the database handle
-    for the application.
-
-  web
-    An accessor for the Jifty::Web object that the web interface uses.
-
-LICENSE
-    Jifty is Copyright 2005 Best Practical Solutions, LLC. Jifty is
-    distributed under the same terms as Perl itself.
-
-SEE ALSO
-    <http://jifty.org>
-
-AUTHORS
-    Jesse Vincent, Alex Vandiver and David Glasser.
-

Modified: jifty/trunk/lib/Jifty/Everything.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Everything.pm	(original)
+++ jifty/trunk/lib/Jifty/Everything.pm	Thu Mar 30 03:27:32 2006
@@ -33,7 +33,7 @@
 use Jifty::Logger ();
 use Jifty::Handler ();
 use Jifty::Handler::Static ();
-use Jifty::Templater::Mason::Handler ();
+use Jifty::View::Mason::Handler ();
 
 use Jifty::Model::Schema ();
 

Modified: jifty/trunk/lib/Jifty/Handler.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Handler.pm	(original)
+++ jifty/trunk/lib/Jifty/Handler.pm	Thu Mar 30 03:27:32 2006
@@ -51,7 +51,7 @@
     $self->dispatcher(
         Jifty->config->framework('ApplicationClass') . "::Dispatcher" );
     Jifty::Util->require( $self->dispatcher );
-    $self->mason( Jifty::Templater::Mason::Handler->new( $self->mason_config ) );
+    $self->mason( Jifty::View::Mason::Handler->new( $self->mason_config ) );
 
     $self->static_handler(Jifty::Handler::Static->new());
 

Added: jifty/trunk/lib/Jifty/View/Mason/Handler.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/View/Mason/Handler.pm	Thu Mar 30 03:27:32 2006
@@ -0,0 +1,265 @@
+use strict;
+use warnings;
+
+package Jifty::View::Mason::Handler;
+
+=head1 NAME
+
+Jifty::View::Mason::Handler - Handler for Mason requests inside of Jifty
+
+=head1 SUMMARY
+
+Jifty controls all of the input and output from the Mason templating
+engine; this means that we cannot use the Mason's standard
+L<HTML::Mason::CGIHandler> interface to interact with it.
+
+=cut
+
+use HTML::Mason;
+use HTML::Mason::Utils;
+use Params::Validate qw(:all);
+use HTML::Mason::Exceptions;
+use HTML::Mason::FakeApache;
+use Encode qw();
+
+use Class::Container;
+use base qw(Class::Container);
+
+use HTML::Mason::MethodMaker
+    ( read_write => [ qw( interp ) ] );
+
+use vars qw($VERSION);
+
+__PACKAGE__->valid_params
+    (
+     interp => { isa => 'HTML::Mason::Interp' },
+    );
+
+__PACKAGE__->contained_objects
+    (
+     interp => 'HTML::Mason::Interp',
+    );
+
+
+=head2 new PARAMHASH
+
+Takes a number of key-value parameters; see L<HTML::Mason::Params>.
+Defaults the C<out_method> to L</out_method>, and the C<request_class>
+to L<HTML::MAson::request::Jifty> (below).  Finally, adds C<h> and
+C<u> escapes, which map to L</escape_uri> and L<escape_utf8>
+respectively.
+
+=cut
+
+sub new {
+    my $package = shift;
+
+    my %p = @_;
+    my $self = $package->SUPER::new( request_class => 'HTML::Mason::Request::Jifty',
+                                     out_method => \&out_method,
+                                     %p );
+    $self->interp->compiler->add_allowed_globals('$r');
+    $self->interp->set_escape( h => \&escape_utf8 );
+    $self->interp->set_escape( u => \&escape_uri );
+
+    return $self;
+}
+
+
+=head2 out_method
+
+The default output method.  Sets the content-type to C<text/html;
+charset=utf-8> unless a content type has already been set, and then
+sends a header if need be.
+
+=cut
+
+sub out_method {
+    my $m = HTML::Mason::Request->instance;
+    my $r = Jifty->handler->apache;
+
+    $r->content_type || $r->content_type('text/html; charset=utf-8'); # Set up a default
+
+    if ($r->content_type =~ /charset=([\w-]+)$/ ) {
+        my $enc = $1;
+	if (lc($enc) =~ /utf-?8/) {
+            binmode *STDOUT, ":utf8";
+	}
+	else {
+            binmode *STDOUT, ":encoding($enc)";
+	}
+    }
+
+    unless ($r->http_header_sent or not $m->auto_send_headers) {
+        $r->send_http_header();
+    }
+
+    # We could perhaps install a new, faster out_method here that
+    # wouldn't have to keep checking whether headers have been
+    # sent and what the $r->method is.  That would require
+    # additions to the Request interface, though.
+    print STDOUT grep {defined} @_;
+}
+
+
+=head2 escape_utf8 SCALARREF
+
+Does a css-busting but minimalist escaping of whatever html you're passing in.
+
+=cut
+
+sub escape_utf8 {
+    my $ref = shift;
+    my $val = $$ref;
+    use bytes;
+    $val =~ s/&/&#38;/g;
+    $val =~ s/</&lt;/g;
+    $val =~ s/>/&gt;/g;
+    $val =~ s/\(/&#40;/g;
+    $val =~ s/\)/&#41;/g;
+    $val =~ s/"/&#34;/g;
+    $val =~ s/'/&#39;/g;
+    $$ref = $val;
+    Encode::_utf8_on($$ref);
+}
+
+
+=head2 escape_uri SCALARREF
+
+Escapes URI component according to RFC2396
+
+=cut
+
+sub escape_uri {
+    my $ref = shift;
+    $$ref = Encode::encode_utf8($$ref);
+    $$ref =~ s/([^a-zA-Z0-9_.!~*'()-])/uc sprintf("%%%02X", ord($1))/eg;
+    Encode::_utf8_on($$ref);
+}
+
+
+=head2 handle_comp COMPONENT
+
+Takes a component path to render.  Deals with setting up a global
+L<HTML::Mason::FakeApache> and Request object, and calling the
+component.
+
+=cut
+
+sub handle_comp {
+    my ($self, $comp) = (shift, shift);
+
+    # Set up the global
+    my $r = Jifty->handler->apache;
+    $self->interp->set_global('$r', $r);
+
+    my %args = $self->request_args($r);
+
+    my @result;
+    if (wantarray) {
+        @result = eval { $self->interp->exec($comp, %args) };
+    } elsif ( defined wantarray ) {
+        $result[0] = eval { $self->interp->exec($comp, %args) };
+    } else {
+        eval { $self->interp->exec($comp, %args) };
+    }
+
+    if (my $err = $@) {
+        my $retval = isa_mason_exception($err, 'Abort')   ? $err->aborted_value  :
+                     isa_mason_exception($err, 'Decline') ? $err->declined_value :
+                     rethrow_exception $err;
+
+        # Unlike under mod_perl, we cannot simply return a 301 or 302
+        # status and let Apache send headers, we need to explicitly
+        # send this header ourself.
+        $r->send_http_header if $retval && grep { $retval eq $_ } ( 200, 301, 302 );
+
+        return $retval;
+    }
+
+    return wantarray ? @result : defined wantarray ? $result[0] : undef;
+}
+
+=head2 request_args
+
+The official source for request arguments is from the current
+L<Jifty::Request> object.
+
+=cut
+
+sub request_args {
+    return %{Jifty->web->request->arguments};
+}
+
+
+###########################################################
+package HTML::Mason::Request::Jifty;
+# Subclass for HTML::Mason::Request object $m
+
+=head1 HTML::Mason::Request::Jifty
+
+Subclass of L<HTML::Mason::Request> which is customised for Jifty's use.
+
+=cut
+
+use HTML::Mason::Exceptions;
+use HTML::Mason::Request;
+use base qw(HTML::Mason::Request);
+
+=head2 auto_send_headers
+
+Doesn't send headers if this is a subrequest (according to the current
+L<Jifty::Request>).
+
+=cut
+
+sub auto_send_headers {
+    return not Jifty->web->request->is_subrequest;
+}
+
+=head2 exec
+
+Actually runs the component; in case no headers have been sent after
+running the component, and we're supposed to send headers, sends them.
+
+=cut
+
+sub exec
+{
+    my $self = shift;
+    my $r = Jifty->handler->apache;
+    my $retval;
+
+    eval { $retval = $self->SUPER::exec(@_) };
+
+    if (my $err = $@)
+    {
+	$retval = isa_mason_exception($err, 'Abort')   ? $err->aborted_value  :
+                  isa_mason_exception($err, 'Decline') ? $err->declined_value :
+                  rethrow_exception $err;
+    }
+
+    # On a success code, send headers if they have not been sent and
+    # if we are the top-level request. Since the out_method sends
+    # headers, this will typically only apply after $m->abort.
+    if ($self->auto_send_headers
+        and not $r->http_header_sent
+        and (!$retval or $retval==200)) {
+        $r->send_http_header();
+    }
+}
+
+=head2 redirect
+
+Calls L<Jifty::Web/redirect>.
+
+=cut
+
+sub redirect {
+    my $self = shift;
+    my $url = shift;
+
+    Jifty->web->redirect($url);
+}
+
+1;

Modified: jifty/trunk/lib/Jifty/Web/PageRegion.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/PageRegion.pm	(original)
+++ jifty/trunk/lib/Jifty/Web/PageRegion.pm	Thu Mar 30 03:27:32 2006
@@ -292,7 +292,7 @@
     $result .= qq|</div>| if ($self->region_wrapper);
 
     #XXX TODO: There's gotta be a better way to localize it
-    Jifty->handler->mason->interp->out_method( \&Jifty::Templater::Mason::Handler::out_method);
+    Jifty->handler->mason->interp->out_method( \&Jifty::View::Mason::Handler::out_method);
 
     return $result;
 }


More information about the Jifty-commit mailing list