MRWolf has asked for the wisdom of the Perl Monks concerning the following question:

I'd like to access template files during run time. What's a good practice for doing this?

I just learned about File::ShareDir and how it works with the share_dir directive of Module::Build and Module::Install.

This is great, since production code can do something like:

  use File::ShareDir;
  my $template_file =   File::ShareDir::module_file('Module::Name', 'template/resume.tt')

But this doesn't seem to help me during development and test, where I'm used to accessing things (i.e. modules, scripts) from ../blib without having to install them.

Is there an analog to blib for share_dir so that I can use the same code in dev/test as I do in production?

And beyond the pre- vs. post- question relating to 'Build install', is there a recommended directory structure for where to hang the templates relative to the modules or relative to the distribution? Even lacking a recommendation, could you point me to a distribution that uses TT so that I could study how it does it?

  • Comment on Dirctory structure for TT2 templates (in test *and* production)

Replies are listed 'Best First'.
Re: Dirctory structure for TT2 templates (in test *and* production)
by Your Mother (Archbishop) on Nov 30, 2010 at 19:49 UTC

    I would only use File::ShareDir for things that are never supposed to be changed, even in testing, except perhaps as the default path (in the INCLUDE_PATH). That way the user or test can add paths which will be preferred where they exist. This is powerful but hard to debug if you don't include the right diagnostics. The ShareDir stuff should play nicely with blib and make test so maybe you're just hitting a development env/setup issue and ShareDir is what you want.

    Catalyst applications often use TT and they generally put the templates in the bottom of the application directory under root, e.g.:

    / /lib /root /root/tt2 /root/tt2/lib/macros.tt # lib for "code" templates /root/tt2/src/index.tt # src for /uri matching templates

    They can go anywhere though and you can use any kind of configuration or ENV settings to include whatever paths you want for the process phase.

      I like your "Things that are never supposed to be changed" phrase. That's exactly my problem with using it. I want it to be different in development and production. It doesn't seem to be able to support that.

      Perhaps I miss something, because it seems that you change gears from ShareDir is not useful to "it is what you want".

      I don't see a way to configure ShareDir to do what I want: let the development paths shadow the production paths in development but have only one set of paths for production.

      On another note, I'm not conversant in Catalyst. How does its directory structure work in development, then in production? Are they kept separate until 'build install', but somehow accessible in both environments?

        I think ShareDir can work for you with care and blib (I haven't done this so, consider it salted/untested). You'll just need to run something like this before using the code in dev:

        perl Makefile.PL && make # then- use blib; # or perl -Mblib ...executable...

        The blib stuff should function as production code would; i.e., ShareDir will find the right things in a relative fashion under, I think, blib/**/auto/... The pain being that you might need to run make all the time to see code changes.

        For Catalyst, take a look at the source code for home() in Catalyst::Utils. It uses the presence of a Makefile.PL (or other dev env markers) to determine the root of the application (local/anywhere v formally installed) and where it can find its files relatively. This is a bit of a systems/deployment decision more than a code choice though so I'm not sure I'd recommend it.