CGI::Application::Plugin::HTDot - Enable "magic dot" notation in


CGI-Application-Plugin-HTDot documentation Contained in the CGI-Application-Plugin-HTDot distribution.

Index


Code Index:

NAME

Top

CGI::Application::Plugin::HTDot - Enable "magic dot" notation in CGI::Application-derived applications that use HTML::Template for their templating mechanism.

VERSION

Top

Version 0.07

SYNOPSIS

Top

    # In your CGI::Application-derived base class. . .
    use base ("CGI::Application::Plugin::HTDot", "CGI::Application");

    # Later, in a run mode far, far away. . .
    sub view {
        my $self     = shift;
        my $username = $self->query->param( 'user' );
        my $user     = My::Users->retrieve( $username );

        my $tmpl_view = $self->load_tmpl( 'view_user.tmpl' );

        # The magic happens here!  Pass our Class::DBI object
        # to the template and display it
        $tmpl_view->param( user => $user );

        return $tmpl_view->output;
    }

DESCRIPTION

Top

Imagine this: you've written a lot of code based upon CGI::Application, and also with HTML::Template because the two have always had such a high level of integration. You reach a situation (many times, perhaps) where you could really use the power and convenience of being able to pass objects to your templates and call methods of those objects from within your template (ala Template Toolkit), but your development schedule doesn't give you the time to learn (much less migrate to!) Template Toolkit or AnyTemplate. Well, you need fret no more! CGI::Application::Plugin::HTDot helps you bring the power of the magic dot to your HTML::Template-based templates from within your CGI::Application-derived webapps.

CGI::Application::Plugin::HTDot provides the glue between CGI::Application, HTML::Template::Pluggable and HTML::Template::Plugin::Dot. It overrides the load_tmpl() method provided with CGI::Application and replaces it with one that turns on the magic dot in HTML::Template. The load_tmpl() method provided here is 100% compatible with the one found in a stock CGI::Application app, so using this plugin does not require refactoring of any code. You can use the magic dot in your application and templates going forward, and refactor older code to use it as your schedule permits.

When you have lots of apps and lots of templates, and no means to switch to Template Toolkit, this will make your life infinitely easier.

For more information about the magic dot, see HTML::Template::Plugin::Dot.

As of version 4.31 of CGI::Application, you can use the html_tmpl_class() method as an alternative to this plugin. TIMTOWTDI.

METHODS

Top

load_tmpl()

For the most part, this is the exact load_tmpl() method from CGI::Application, except it uses HTML::Template::Pluggable and HTML::Template::Plugin::Dot instead of HTML::Template.

See the CGI::Application reference for more detailed information on what parameters can be passed to load_tmpl().

Extending load_tmpl()

There are times when the basic load_tmpl() functionality just isn't enough. Many HTML::Template developers set die_on_bad_params to 0 on all of their templates. The easiest way to do this is by replacing or extending the functionality of CGI::Application's load_tmpl() method. This is still possible using the plugin.

The following code snippet illustrates one possible way of achieving this:

  sub load_tmpl {
      my ($self, $tmpl_file, @extra_params) = @_;

      push @extra_params, "die_on_bad_params", "0";
      push @extra_params, "cache",             "1";

      return $self->SUPER::load_tmpl($tmpl_file, @extra_params);
  }

This plugin honors the load_tmpl() callback. Any load_tmpl()-based callbacks you have created will be executed as intended:

DEFAULT PARAMETERS

Top

By default, this plugin will automatically add a parameter 'c' to your template that will return your CGI::Application object. This will allow you to access any methods in your application from within your template. This allows for some powerful actions in your templates. For example, your templates can access query parameters, or if you use the excellent CGI::Application::Plugin::Session module, you can access session parameters:

	Hello <tmpl_var c.session.param('username')>!

	<a href="<tmpl_var c.query.self_url>">Reload this page</a>

Another useful plugin that can use this feature is the CGI::Application::Plugin::HTMLPrototype plugin, which gives easy access to the prototype.js JavaScript library:

	<tmpl_var c.prototype.define_javascript_functions>
	<a href="#" onclick="javascript:<tmpl_var c.prototype.visual_effect( 'Appear', 'extra_info' )>; return false;">Extra Info</a>
	<div style="display: none" id="extra_info">Here is some more extra info</div>

With this extra flexibility comes some responsibilty as well. It could lead down a dangerous path if you start making alterations to your object from within the template. For example you could call c.header_add to add new outgoing headers, but that is something that should be left in your code, not in your template. Try to limit yourself to pulling in information into your templates (like the session example above does).

This plugin will respect your current die_on_bad_params setting. If die_on_bad_params is set to 1 and your template does not use 'c', the plugin will not attempt to pass the CGI::Application object to your template. In other words, it does not force your application to set die_on_bad_params to 0 to accomplish this action.

AUTHOR

Top

Jason A. Crome, <cromedome@cpan.org>

BUGS

Top

Please report any bugs or feature requests to bug-cgi-application-plugin-htdot@rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CGI-Application-Plugin-HTDot. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGMENTS

Top

Thanks and credit needs to be given to Jesse Erlbaum and Mark Stosberg for the original load_tmpl() method that this is based on, to Rhesa Rozendaal and Mark Stosberg for their work on enabling the magic dot in HTML::Template, Cees Hek for his idea (and tutorial on how) to use multiple inheritance to make this plugin work, and to the usual crowd in #cgiapp on irc.perl.org for making this all worthwhile for me :)

An extra special thanks to Cees Hek for the inspiration, code, and examples to implement the 'c' parameter in templates.

SEE ALSO

Top

CGI::Application, HTML::Template, HTML::Template::Pluggable, HTML::Template::Plugin::Dot, CGI::Application::Plugin::TT.

COPYRIGHT & LICENSE

Top


CGI-Application-Plugin-HTDot documentation Contained in the CGI-Application-Plugin-HTDot distribution.
package CGI::Application::Plugin::HTDot;

use strict;

$CGI::Application::Plugin::HTDot::VERSION = '0.07';

sub load_tmpl {
	my $self = shift;
	my ( $tmpl_file, @extra_params ) = @_;

	# Add tmpl_path to path array if one is set, otherwise add a path arg
	if (my $tmpl_path = $self->tmpl_path) {
		my @tmpl_paths = (ref $tmpl_path eq 'ARRAY') ? @$tmpl_path : $tmpl_path;
		my $found = 0;
		for( my $x = 0; $x < @extra_params; $x += 2 ) {
			if ($extra_params[$x] eq 'path' and
			ref $extra_params[$x+1] eq 'ARRAY') {
				unshift @{$extra_params[$x+1]}, @tmpl_paths;
				$found = 1;
				last;
			}
		}
		push( @extra_params, path => [ @tmpl_paths ] ) unless $found;
	}

    my %tmpl_params = ();
    my %ht_params   = @extra_params;
    %ht_params      = () unless keys %ht_params;

    # Define our extension if one doesn't already exist
    $self->{__CURRENT_TMPL_EXTENSION} = '.html' unless defined $self->{__CURRENT_TMPL_EXTENSION};

    # Define a default template name based on the current run mode
    unless (defined $tmpl_file) {
        $tmpl_file = $self->get_current_runmode . $self->{__CURRENT_TMPL_EXTENSION};
    }

    $self->call_hook('load_tmpl', \%ht_params, \%tmpl_params, $tmpl_file);

    # This is really where the magic occurs.  We replace HTML::Template with
    # the magic-dot enabled version, and the rest really works itself out.
    use HTML::Template::Pluggable;
    use HTML::Template::Plugin::Dot;

    # Check $tmpl_file and see what kind of parameter it is:
    # - scalar (filename)
	# - ref to scalar (the actual html/template content)
	# - reference to filehandle
    my $t = undef;
    if ( ref $tmpl_file eq 'SCALAR' ) {
        $t = HTML::Template::Pluggable->new_scalar_ref( $tmpl_file, %ht_params );
    }
	elsif ( ref $tmpl_file eq 'GLOB' ) {
        $t = HTML::Template::Pluggable->new_filehandle( $tmpl_file, %ht_params );
    }
	else {
        $t = HTML::Template::Pluggable->new_file( $tmpl_file, %ht_params );
    }

    if ( keys %tmpl_params ) {
        $t->param( %tmpl_params );
    }

	# Pass the CGI::Application object to the template (if it's being referenced
    # somewhere in the template...)
    my @vars = $t->query;
    foreach my $var ( @vars ) {
        $t->param( c => $self ) if $var =~ /^c\./;
    }

	# Give the user back their template
	return $t;
}

1; # End of CGI::Application::Plugin::HTDot