package AmphetaDesk::Templates;
###############################################################################
# AmphetaDesk                                           (c) 2000-2002 Disobey #
# morbus@disobey.com                      http://www.disobey.com/amphetadesk/ #
###############################################################################
# ABOUT THIS PACKAGE:                                                         #
#   This package encapsulates all the various template handling code. It      #
#   uses Text::Template to parse the templates, and then sends the results    #
#   back to the calling function for further action. Simple stuff.            #
#                                                                             #
# LIST OF ROUTINES BELOW:                                                     #
#   include - used within template files to include other template files.     #
#   parse_template - take the passed file path, parse it, and return results. #
#   send_to_browser - take the output destined for the browser, and send it.  #
#   to_browser - add the passed message to the output for the browser.        #
###############################################################################
#           "Put something witty here before committing to CVS."              #
###############################################################################

use strict; $|++;
use Text::Template;
require Exporter;
use vars qw( @ISA @EXPORT );
@ISA = qw( Exporter );
@EXPORT = qw( parse_template );

# we always prepend all this stuff to the various Text::Template
# files so that we can use templates-within-templates without the
# namespace being lost (ie, a template-within-template would get
# Text::Template::get_setting unless you used PACKAGE statements
# in the actual parent template). this isn't ideal since you're
# restricted to only one PACKAGE at a time. so, we predeclare
# all the packages and pragmas we may want to use in our templates.
Text::Template->always_prepend("
   use strict;                      use File::Spec::Functions;
   use CGI qw/:standard :cgi-lib/;  use AmphetaDesk::Channels;
   use AmphetaDesk::Settings;       use AmphetaDesk::ChannelsList;
   use AmphetaDesk::MyChannels;     use AmphetaDesk::Utilities;
   use AmphetaDesk::Versioning;     use AmphetaDesk::WWW;
");

# where we store our template output. we do this
# in an array because adding a zillion items to an
# array and then joining on whitespace is far less
# memory hungry than concating string after string.
my @BROWSER_OUTPUT;

###############################################################################
# include - used within template files to include other template files.       #
###############################################################################
# USAGE:                                                                      #
#   [$ include ( $file_path ) $]         # within the user templates.         #
#                                                                             #
# NOTES:                                                                      #
#   Only used within the user templates, this routine parses another          #
#   template and puts the results in the current template. It's meant         #
#   reproduce (to a small degree) server-side includes. This code comes       #
#   almost verbatim from the Text::Template documentation.                    #
#                                                                             #
# RETURNS:                                                                    #
#   undef; if the include failed for some reason.                             #
#   results; the parsed results of the included template.                     #
###############################################################################

sub include { my $file = shift; &Text::Template::fill_in_file($file, DELIMITERS => ['[$', '$]']); };

###############################################################################
# parse_template - take the passed file path, parse it, and return results.   #
###############################################################################
# USAGE:                                                                      #
#   my $results = parse_template( $file_path );                               #
#                                                                             #
# NOTES:                                                                      #
#   This routine accepts a full file path (which is assumed to exist),        #
#   attempts to parse the template with Text::Template, and then returns      #
#   the results. If this fails, something really wrong happened.              #
#                                                                             #
# RETURNS:                                                                    #
#   $results; the results of a successful parsing.                            #
#   die; if the template could not be parsed for some odd reason.             #
###############################################################################

sub parse_template {

   my ($file_path) = @_;

   # construct the template object.
   my $template = Text::Template->new( SOURCE => $file_path, DELIMITERS => [ '[$ ', ' $]' ] )
               or error("AmphetaDesk couldn't create the template: $Text::Template::ERROR");

   # and return the results.
   return $template->fill_in();

}

###############################################################################
# send_to_browser - take the output destined for the browser, and send it.    #
# to_browser - add the passed message to the output for the browser.          #
###############################################################################
# USAGE:                                                                      #
#   $OUT = send_to_browser;                                                   #
#   to_browser("random crap for the ", $browser",  "whoooO");                 #
#   to_browser("the above was an array. this is a string.");                  #
#                                                                             #
# NOTES:                                                                      #
#   In previous versions of the AmphetaDesk template code, we concat'd all    #
#   of our strings together in the templates. This started causing memory     #
#   leaks and slowdowns, due to the sheer amount of concat's we do for heavy  #
#   users. Now we throw everything into an array, and only concat things      #
#   together when we're done everything else. to_browser adds the message     #
#   to our array, and send_to_browser dumps it all out in one big string.     #
#                                                                             #
#   You can, of course, choose not to use send_?to_browser when it's not      #
#   needed, such as small template places like my_settings.html, etc. If      #
#   that's the case, you can send straight to Text::Template's $OUT.          #
#                                                                             #
# RETURNS:                                                                    #
#   $out; the final string from send_to_browser for Text::Template's $OUT.    #
#   1; to_browser always returns 1 - it'd be really weird if it didn't.       #
###############################################################################

sub send_to_browser { my $out = join("", @BROWSER_OUTPUT); undef @BROWSER_OUTPUT; return $out; }
sub to_browser { my (@msgs) = @_; push(@BROWSER_OUTPUT, join("", @msgs)); return 1; }

1;
