summaryrefslogtreecommitdiff
path: root/lib/Template/Plugin/File.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Template/Plugin/File.pm')
-rw-r--r--lib/Template/Plugin/File.pm416
1 files changed, 416 insertions, 0 deletions
diff --git a/lib/Template/Plugin/File.pm b/lib/Template/Plugin/File.pm
new file mode 100644
index 0000000..d1d542e
--- /dev/null
+++ b/lib/Template/Plugin/File.pm
@@ -0,0 +1,416 @@
+#============================================================= -*-Perl-*-
+#
+# Template::Plugin::File
+#
+# DESCRIPTION
+# Plugin for encapsulating information about a system file.
+#
+# AUTHOR
+# Originally written by Michael Stevens <michael@etla.org> as the
+# Directory plugin, then mutilated by Andy Wardley <abw@kfs.org>
+# into separate File and Directory plugins, with some additional
+# code for working with views, etc.
+#
+# COPYRIGHT
+# This module is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+#
+# REVISION
+# $Id: File.pm,v 2.64 2004/01/13 16:20:38 abw Exp $
+#
+#============================================================================
+
+package Template::Plugin::File;
+
+require 5.004;
+
+use strict;
+use Cwd;
+use File::Spec;
+use File::Basename;
+use Template::Plugin;
+
+use vars qw( $VERSION );
+use base qw( Template::Plugin );
+use vars qw( @STAT_KEYS );
+
+$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/);
+
+@STAT_KEYS = qw( dev ino mode nlink uid gid rdev size
+ atime mtime ctime blksize blocks );
+
+
+#------------------------------------------------------------------------
+# new($context, $file, \%config)
+#
+# Create a new File object. Takes the pathname of the file as
+# the argument following the context and an optional
+# hash reference of configuration parameters.
+#------------------------------------------------------------------------
+
+sub new {
+ my $config = ref($_[-1]) eq 'HASH' ? pop(@_) : { };
+ my ($class, $context, $path) = @_;
+ my ($root, $home, @stat, $abs);
+
+ return $class->throw('no file specified')
+ unless defined $path and length $path;
+
+ # path, dir, name, root, home
+
+ if (File::Spec->file_name_is_absolute($path)) {
+ $root = '';
+ }
+ elsif (($root = $config->{ root })) {
+ # strip any trailing '/' from root
+ $root =~ s[/$][];
+ }
+ else {
+ $root = '';
+ }
+
+ my ($name, $dir, $ext) = fileparse($path, '\.\w+');
+ # fixup various items
+ $dir =~ s[/$][];
+ $dir = '' if $dir eq '.';
+ $name = $name . $ext;
+ $ext =~ s/^\.//g;
+ my @fields = File::Spec->splitdir($dir);
+ shift @fields if @fields && ! length $fields[0];
+ $home = join('/', ('..') x @fields);
+ $abs = File::Spec->catfile($root ? $root : (), $path);
+
+ my $self = {
+ path => $path,
+ name => $name,
+ root => $root,
+ home => $home,
+ dir => $dir,
+ ext => $ext,
+ abs => $abs,
+ user => '',
+ group => '',
+ isdir => '',
+ stat => defined $config->{ stat } ? $config->{ stat }
+ : ! $config->{ nostat },
+ map { ($_ => '') } @STAT_KEYS,
+ };
+
+ if ($self->{ stat }) {
+ (@stat = stat( $abs ))
+ || return $class->throw("$abs: $!");
+ @$self{ @STAT_KEYS } = @stat;
+ unless ($config->{ noid }) {
+ $self->{ user } = eval { getpwuid( $self->{ uid }) || $self->{ uid } };
+ $self->{ group } = eval { getgrgid( $self->{ gid }) || $self->{ gid } };
+ }
+ $self->{ isdir } = -d $abs;
+ }
+
+ bless $self, $class;
+}
+
+
+#-------------------------------------------------------------------------
+# rel($file)
+#
+# Generate a relative filename for some other file relative to this one.
+#------------------------------------------------------------------------
+
+sub rel {
+ my ($self, $path) = @_;
+ $path = $path->{ path } if ref $path eq ref $self; # assumes same root
+ return $path if $path =~ m[^/];
+ return $path unless $self->{ home };
+ return $self->{ home } . '/' . $path;
+}
+
+
+#------------------------------------------------------------------------
+# present($view)
+#
+# Present self to a Template::View.
+#------------------------------------------------------------------------
+
+sub present {
+ my ($self, $view) = @_;
+ $view->view_file($self);
+}
+
+
+sub throw {
+ my ($self, $error) = @_;
+ die (Template::Exception->new('File', $error));
+}
+
+__END__
+
+
+#------------------------------------------------------------------------
+# IMPORTANT NOTE
+# This documentation is generated automatically from source
+# templates. Any changes you make here may be lost.
+#
+# The 'docsrc' documentation source bundle is available for download
+# from http://www.template-toolkit.org/docs.html and contains all
+# the source templates, XML files, scripts, etc., from which the
+# documentation for the Template Toolkit is built.
+#------------------------------------------------------------------------
+
+=head1 NAME
+
+Template::Plugin::File - Plugin providing information about files
+
+=head1 SYNOPSIS
+
+ [% USE File(filepath) %]
+ [% File.path %] # full path
+ [% File.name %] # filename
+ [% File.dir %] # directory
+
+=head1 DESCRIPTION
+
+This plugin provides an abstraction of a file. It can be used to
+fetch details about files from the file system, or to represent abstract
+files (e.g. when creating an index page) that may or may not exist on
+a file system.
+
+A file name or path should be specified as a constructor argument. e.g.
+
+ [% USE File('foo.html') %]
+ [% USE File('foo/bar/baz.html') %]
+ [% USE File('/foo/bar/baz.html') %]
+
+The file should exist on the current file system (unless 'nostat'
+option set, see below) as an absolute file when specified with as
+leading '/' as per '/foo/bar/baz.html', or otherwise as one relative
+to the current working directory. The constructor performs a stat()
+on the file and makes the 13 elements returned available as the plugin
+items:
+
+ dev ino mode nlink uid gid rdev size
+ atime mtime ctime blksize blocks
+
+e.g.
+
+ [% USE File('/foo/bar/baz.html') %]
+
+ [% File.mtime %]
+ [% File.mode %]
+ ...
+
+In addition, the 'user' and 'group' items are set to contain the user
+and group names as returned by calls to getpwuid() and getgrgid() for
+the file 'uid' and 'gid' elements, respectively. On Win32 platforms
+on which getpwuid() and getgrid() are not available, these values are
+undefined.
+
+ [% USE File('/tmp/foo.html') %]
+ [% File.uid %] # e.g. 500
+ [% File.user %] # e.g. abw
+
+This user/group lookup can be disabled by setting the 'noid' option.
+
+ [% USE File('/tmp/foo.html', noid=1) %]
+ [% File.uid %] # e.g. 500
+ [% File.user %] # nothing
+
+The 'isdir' flag will be set if the file is a directory.
+
+ [% USE File('/tmp') %]
+ [% File.isdir %] # 1
+
+If the stat() on the file fails (e.g. file doesn't exists, bad
+permission, etc) then the constructor will throw a 'File' exception.
+This can be caught within a TRY...CATCH block.
+
+ [% TRY %]
+ [% USE File('/tmp/myfile') %]
+ File exists!
+ [% CATCH File %]
+ File error: [% error.info %]
+ [% END %]
+
+Note the capitalisation of the exception type, 'File' to indicate an
+error thrown by the 'File' plugin, to distinguish it from a regular
+'file' exception thrown by the Template Toolkit.
+
+Note that the 'File' plugin can also be referenced by the lower case
+name 'file'. However, exceptions are always thrown of the 'File'
+type, regardless of the capitalisation of the plugin named used.
+
+ [% USE file('foo.html') %]
+ [% file.mtime %]
+
+As with any other Template Toolkit plugin, an alternate name can be
+specified for the object created.
+
+ [% USE foo = file('foo.html') %]
+ [% foo.mtime %]
+
+The 'nostat' option can be specified to prevent the plugin constructor
+from performing a stat() on the file specified. In this case, the
+file does not have to exist in the file system, no attempt will be made
+to verify that it does, and no error will be thrown if it doesn't.
+The entries for the items usually returned by stat() will be set
+empty.
+
+ [% USE file('/some/where/over/the/rainbow.html', nostat=1)
+ [% file.mtime %] # nothing
+
+All File plugins, regardless of the nostat option, have set a number
+of items relating to the original path specified.
+
+=over 4
+
+=item path
+
+The full, original file path specified to the constructor.
+
+ [% USE file('/foo/bar.html') %]
+ [% file.path %] # /foo/bar.html
+
+=item name
+
+The name of the file without any leading directories.
+
+ [% USE file('/foo/bar.html') %]
+ [% file.name %] # bar.html
+
+=item dir
+
+The directory element of the path with the filename removed.
+
+ [% USE file('/foo/bar.html') %]
+ [% file.name %] # /foo
+
+=item ext
+
+The file extension, if any, appearing at the end of the path following
+a '.' (not included in the extension).
+
+ [% USE file('/foo/bar.html') %]
+ [% file.ext %] # html
+
+=item home
+
+This contains a string of the form '../..' to represent the upward path
+from a file to its root directory.
+
+ [% USE file('bar.html') %]
+ [% file.home %] # nothing
+
+ [% USE file('foo/bar.html') %]
+ [% file.home %] # ..
+
+ [% USE file('foo/bar/baz.html') %]
+ [% file.home %] # ../..
+
+=item root
+
+The 'root' item can be specified as a constructor argument, indicating
+a root directory in which the named file resides. This is otherwise
+set empty.
+
+ [% USE file('foo/bar.html', root='/tmp') %]
+ [% file.root %] # /tmp
+
+=item abs
+
+This returns the absolute file path by constructing a path from the
+'root' and 'path' options.
+
+ [% USE file('foo/bar.html', root='/tmp') %]
+ [% file.path %] # foo/bar.html
+ [% file.root %] # /tmp
+ [% file.abs %] # /tmp/foo/bar.html
+
+=back
+
+In addition, the following method is provided:
+
+=over 4
+
+=item rel(path)
+
+This returns a relative path from the current file to another path specified
+as an argument. It is constructed by appending the path to the 'home'
+item.
+
+ [% USE file('foo/bar/baz.html') %]
+ [% file.rel('wiz/waz.html') %] # ../../wiz/waz.html
+
+=back
+
+=head1 EXAMPLES
+
+ [% USE file('/foo/bar/baz.html') %]
+
+ [% file.path %] # /foo/bar/baz.html
+ [% file.dir %] # /foo/bar
+ [% file.name %] # baz.html
+ [% file.home %] # ../..
+ [% file.root %] # ''
+ [% file.abspath %] # /foo/bar/baz.html
+ [% file.ext %] # html
+ [% file.mtime %] # 987654321
+ [% file.atime %] # 987654321
+ [% file.uid %] # 500
+ [% file.user %] # abw
+
+ [% USE file('foo.html') %]
+
+ [% file.path %] # foo.html
+ [% file.dir %] # ''
+ [% file.name %] # foo.html
+ [% file.root %] # ''
+ [% file.home %] # ''
+ [% file.abspath %] # foo.html
+
+ [% USE file('foo/bar/baz.html') %]
+
+ [% file.path %] # foo/bar/baz.html
+ [% file.dir %] # foo/bar
+ [% file.name %] # baz.html
+ [% file.root %] # ''
+ [% file.home %] # ../..
+ [% file.abspath %] # foo/bar/baz.html
+
+ [% USE file('foo/bar/baz.html', root='/tmp') %]
+
+ [% file.path %] # foo/bar/baz.html
+ [% file.dir %] # foo/bar
+ [% file.name %] # baz.html
+ [% file.root %] # /tmp
+ [% file.home %] # ../..
+ [% file.abspath %] # /tmp/foo/bar/baz.html
+
+ # calculate other file paths relative to this file and its root
+ [% USE file('foo/bar/baz.html', root => '/tmp/tt2') %]
+ [% file.path('baz/qux.html') %] # ../../baz/qux.html
+ [% file.dir('wiz/woz.html') %] # ../../wiz/woz.html
+
+
+=head1 AUTHORS
+
+Michael Stevens E<lt>michael@etla.orgE<gt> wrote the original Directory plugin
+on which this is based. Andy Wardley E<lt>abw@wardley.orgE<gt> split it into
+separate File and Directory plugins, added some extra code and documentation
+for VIEW support, and made a few other minor tweaks.
+
+=head1 VERSION
+
+2.64, distributed as part of the
+Template Toolkit version 2.13, released on 30 January 2004.
+
+
+
+=head1 COPYRIGHT
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Template::Plugin|Template::Plugin>, L<Template::Plugin::Directory|Template::Plugin::Directory>, L<Template::View|Template::View>
+