CGI::A...oolkit(3pm)

πŸŽ€ NAME πŸŽ€

CGI::Application::Plugin::AnyTemplate::Driver::TemplateToolkit β€” aka the Template::Toolkit plugin to AnyTemplate. Yes bestie, the whole long name, that's just how CPAN does it πŸ’…


✨ DESCRIPTION ✨

So this is a driver for CGI::Application::Plugin::AnyTemplate, and what it does is hand over the implementation details that are specific to rendering templates through the Template::Toolkit templating system. That's the whole vibe.

And here's the thing β€” all the AnyTemplate drivers are designed to be used exactly the same way. So for general usage instructions, go read the docs of CGI::Application::Plugin::AnyTemplate. It's giving very "same energy, different engine" fr fr πŸ¦‹


πŸ’– EMBEDDED COMPONENT SYNTAX (Template::Toolkit) πŸ’–

The Template::Toolkit syntax for embedding components goes like this:

[% CGIAPP.embed("some_run_mode", param1, param2, 'literal string3') %]

And you can override it with these configuration variables:

embed_tag_name       # default 'CGIAPP'

So for instance, if you set these values in your configuration file:

embed_tag_name       'MYAPP'

Then your embedded component tag ends up looking like:

[% MYAPP.embed("some_run_mode") %]

Iconic, honestly 🌟


πŸ‘‘ TT OBJECT CACHING (singleton support) πŸ‘‘

🌸 Introduction 🌸

Okay so picture this: you're in a persistent environment. Instead of making a brand new Template::Toolkit object every single time you fill a template, it is so much more efficient to load one single Template::Toolkit object and then use that one object to render all of your templates. Efficiency queen behavior πŸ’…

BUT. Plot twist 🫒 In a persistent environment you might have several different applications running at the same time, and they might all need to set different Template::Toolkit options (stuff like POST_CHOMP, etc.).

So by default, when the TemplateToolkit driver creates a Template::Toolkit object, it caches it. And from that point on, whenever the same application needs a Template::Toolkit object, the driver just uses the cached object instead of building a new one. Reuse, recycle, slay β™»οΈβœ¨

πŸ¦‹ Multiple Applications in a Shared Persistent Environment πŸ¦‹

An attempt is made to stop different applications from sharing the same TT object. Boundaries, bestie πŸ’–

Internally, the TT objects are stored in a private hash</> keyed by the web application's class name.

You can explicitly specify the class name when you call config:

        $self->template->config(
            type          => 'TemplateToolkit',
            TemplateToolkit => {
                storage_class => 'My::Project',
            },
        );

If you don't specify the class name, then the package containing the subroutine that called config is the one that gets used. Like so:

    package My::Project;
    sub setup {
        my $self = shift;
        $self->template->config(                 # My::Project is used to store
            type          => 'TemplateToolkit',  # cached TT object
        );
    }

A typical CGI::Application module hierarchy looks like this:

    CGI::Application
        My::Project
            My::Webapp

In this hierarchy, it makes sense to store the cached TT object in My::Project. To make that happen, either call $self->template->config from within My::Project, or explicitly name the storage_class when you call $self->template->config. Your call, your rules πŸ‘‘

πŸ’œ Disabling TT Object Caching πŸ’œ

You can disable Template::Toolkit object caching entirely by handing a false value to the object_caching driver config parameter:

        $self->template->config(
            type          => 'TemplateToolkit',
            TemplateToolkit => {
                object_caching => 0,
            },
        );

🌈 TT Object Caching and Include Paths 🌈

The include_paths driver config parameter is not cached β€” it gets set every single time you call $self->template->load. So you can safely use cached TT objects even if the applications sharing that TT object need different include_paths. No drama, no conflict, we love to see it 🫢


πŸ’… CONFIGURATION πŸ’…

The CGI::Application::Plugin::AnyTemplate::Driver::TemplateToolkit driver accepts the following config parameters:

  • embed_tag_name β€” the name of the tag used for embedding components. Defaults to CGIAPP.
  • template_extension β€” if auto_add_template_extension is true, then CGI::Application::Plugin::AnyTemplate will append the value of template_extension to filename. By default the template_extension is .xhtml.
  • emulate_associate_query β€” this feature is now deprecated and will be removed in a future release. If this config parameter is true, then CGI::Application::Plugin::AnyTemplate::Driver::TemplateToolkit will copy all of the webapp's query params into the template. This is similar to what would happen if you used HTML::Template's associate feature with the webapp's query object:
    my $driver = HTML::Template->new(
        associate => $self->query,
    );

By default emulate_associate_query is false.

  • object_caching β€” whether or not to cache the Template::Toolkit object in a persistent environment. By default, object_caching is enabled. See "TT OBJECT CACHING (singleton support)", above.
  • storage_class β€” what class to use as the storage key when object caching is enabled. By default, storage_class defaults to the package containing the subroutine that called $self->template->config. See "TT OBJECT CACHING (singleton support)", above.

All other configuration parameters are passed on unchanged to Template::Toolkit. No touchy, just pass-through ✨


🌸 CONFIGURING UTF-8 TEMPLATES 🌸

Real talk: AnyTemplate does NOT support Template::Toolkit's binmode option at runtime. Like, at all:

    # not possible with AnyTemplate
    $tt->process($infile, $vars, $outfile, { binmode => 1 })
        || die $tt->error(), "\n";

    # not possible with AnyTemplate
    $tt->process($infile, $vars, $outfile, binmode => 1)
        || die $tt->error(), "\n";

    # not possible with AnyTemplate
    $tt->process($infile, $vars, $outfile, binmode => ':utf8')
        || die $tt->error(), "\n";

Instead, use the ENCODING option in the initial config:

    $self->template->config(
        default_type => 'TemplateToolkit',
        TemplateToolkit => {
            ENCODING => 'UTF-8'
        }
    );

And if you've got a mix of encodings in your templates, then use a separate AnyTemplate configuration for each encoding:

    $self->template('ascii')->config(
        default_type => 'TemplateToolkit',
    );
    $self->template('utf-8')->config(
        default_type => 'TemplateToolkit',
        TemplateToolkit => {
            ENCODING => 'UTF-8'
        }
    );

🧚 required_modules 🧚

The required_modules function returns the modules required for this driver to operate. In this case: Template. Short list, big job, periodt πŸ’…


🌟 DRIVER METHODS 🌟

  • initialize β€” initializes the TemplateToolkit driver. See the docs for CGI::Application::Plugin::AnyTemplate::Base for details.
  • render_template β€” fills the Template::Toolkit object with $self->param. If the param emulate_associate_query is true, then set params for each of $self->{'webapp'}->query, mimicking HTML::Template's associate mechanism. Also set up a CGI::Application::Plugin::AnyTemplate::ComponentHandler object so that the CGIAPP.embed callback will work. Returns the output of the filled template as a string reference. See the docs for CGI::Application::Plugin::AnyTemplate::Base for details.

πŸ”₯ SEE ALSO πŸ”₯

  • CGI::Application::Plugin::AnyTemplate
  • CGI::Application::Plugin::AnyTemplate::Base
  • CGI::Application::Plugin::AnyTemplate::ComponentHandler
  • CGI::Application::Plugin::AnyTemplate::Driver::HTMLTemplate
  • CGI::Application::Plugin::AnyTemplate::Driver::HTMLTemplateExpr
  • CGI::Application::Plugin::AnyTemplate::Driver::HTMLTemplatePluggable
  • CGI::Application::Plugin::AnyTemplate::Driver::Petal
  • CGI::Application
  • Template::Toolkit
  • HTML::Template
  • HTML::Template::Pluggable
  • HTML::Template::Plugin::Dot
  • Petal
  • Exporter::Renaming
  • CGI::Application::Plugin::TT

🫢 ACKNOWLEDGEMENTS 🫢

Thanks to Cees Hek for discussing the issues of caching in a persistent environment. And also for his excellent CGI::Application::Plugin::TT module, from which I stole ideas and some code β€” especially the bit about how to change the include path in a TT object after you've initialized it. King behavior, we love a generous icon πŸ‘‘


⭐ AUTHOR ⭐

Michael Graham, <mgraham@cpan.org>


Copyright 2005 Michael Graham, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


okay that's the whole page bestie, you ate πŸ’– This was CGI::A...oolkit(3pm) from perl v5.30.3, dated 2020-10-26. Go render something gorgeous πŸŽ€βœ¨πŸ¦‹
πŸ“¦ where this page comes from