Contentment::VFS - Provides a virtual file system for Contentment


The purpose of a content management system is to provide a store for content. Unfortunately, it is difficult to determine how such content should be represented and stored. As such, this class provides a "virtual file system" that allows the user to store components in a customized manner.


The basic functionality required is identical to that of File::System::Object. The Contentment::VFS class is actually a subclass of File::System::Passthrough, which wraps the file system defined by the "vfs" key of the global configuration. It will employ the use of an internal File::System::Layered object and File::System::Table object to perform file system layering and mounting.

By using the add_layer() and mount() methods, you can use existing File::System::Object implementations or custom implementations to add additional files and directories to the VFS.

In addition to the functionality provided by each of these file system implementations, the VFS adds the ability to provide files through a simple set of hooks. This doesn't provide as much power as defining a full blown file system object implementation, but is far simpler.

Another change from the File::System implementation is that the use of the content() method is discouraged. Instead, use the generator() method to return an object capable of generating the file's content. If the VFS hook functionality is used, it's probable that content() will return an empty string for a file while the generator() returned will output text.


If you want to extend the VFS without a full-blown mount, register a named hook handler for the "Contentment::VFS::simple" hook. The name registered is the base path your hook will provide files under. The name must include a starting slash, but do not include the traling slash.

  # Be sure to NOT include a trailing "/"
      hook => 'Contentment::VFS::simple',
      name => '/node',
      code => \&Contentment::Node::simple,

When someone looks up a path starting with the name you register, the handler will be called.

The handler will be passed a single argument, the relative path under the named path that was requested. (A lone slash ("/") will be passed if the user asks for the name you registered).

  my $vfs = $context->vfs;

  # The /node handler will be passed "/"
  my $obj = $vfs->lookup('/node');

  # The /node handler will be passed "/"
  my $obj = $vfs->lookup('/node');

  # The /node handler will be passed "/id/42/rev/142"
  my $obj = $vfs->lookup('/node/id/42/rev/142');

Based upon the path given, your handler should return a reference to a hash describing the file/directory that exists at that path. Return undef if no such file exists.

The returned hash may contain the following keys:

type (required)

This describes the file type. This is a string containing at least a "d" or an "f" or a combination of them. If "d" is given, then the file is a directory and contains other files. If "f" is given, then the file is contains file data.

children (required if type contains "d")

This should be a reference to an array of strings. Each string is the name of a valid path immediately within the directory.

generator (required if type contains "f")

This should be a reference to a generator object.

properties (optional, defaults to {})

This is a hash of the properties to set on the file system object (in addition to basename, dirname, path, and object_type which are handled by the VFS for you).


The VFS class is a singleton object that can be referenced by doing:

  $vfs = $context->vfs;

Once you have a $vfs object, you can use it to lookup files and directories. Whenever possible, the VFS delegates work directly to File::System::Object, so see that documentation for the basic details. Any additional functionality is described in this document.


$vfs = $context->vfs

Returns a reference to the VFS singleton object.

$source_obj = $obj->lookup_source($path)

This is like lookup, except that instead of looking for an exact filename match, this will attempt to find the first file that could be used as a source to generate output for the given path.

If no path is given and $obj->has_content returns true, then $source_obj = $obj. If no path is given and $obj->has_content returns false, but $obj->is_container returns true, then a check is performed to see if a file named index.* can be found inside of the container. If so, that object is returned.

If the $path matches a file (not a directory) exactly, then the object representing that file is returned.

If the $path matches a directory exactly, then this method checks to see if that directory contains an index. The index is any file starting with index with any file extension. If the directory doesn't contain an index file, then undef is returned.

Finally, this method searches for a file matching $path without regard to file extensions. If a match is found, it is returned.

In the case of multiple matches at any point, the choice is arbitrary.

$generator = $file_thing->generator

Returns the generator which is capable of generating the file thing.

Returns undef when has_content is false.

$vfs->add_layer($index, $filesystem)

Layers another file system object over the current file system. If you want to make the new layer top priority set $index to 0. If you want it the lowest priority, set $index to -1.

If the file system wrapped is not a File::System::Layered object, it is made such an object with the current file system object made the only internal layer.


Lists the layers in the file system.


Removes the layer found at the given $index. Throws an exception if the file system isn't layered or there is only one layer left.

$vfs->mount($path, $filesystem)

Mount a the given file system, $filesystem, onto the given path, $path.

See File::System::Table for more details.

@paths = $fs->mounts

Returns the list of all paths that have been mounted to.

See File::System::Table for more details.

$filesystem = $vfs->unmount($path)

Unmount a given file system found at path, $path. Returns the file system object that was unmounted.

See File::System::Table for more details.


This class adds the following methods to the context:

$vfs = $context->vfs

Returns the VFS object.



Handles the "Contentment::Response::resolve" handler. Looks for a file in the VFS to return as a component for rendering.



The handlers for this hook are passed a single argument, a Contentment::VFS object pointing to a particular path. The handler should return undef if it is unable to provide a generator for that file. The handler should return a constructor generator for the file, if it can provide a generator. The hook stops when the first handler returns something other than undef.


Used as a simple way of grafting on to the file system without having to implement a full blown File::System::Object implementation. See "VFS HOOKS" for additional information.


File::System, File::System::Other, File::System::Passthrough, Contentment::Generator::Plain


Andrew Sterling Hanenkamp, <>


Copyright 2005 Andrew Sterling Hanenkamp. All Rights Reserved.

Contentment is distributed and licensed under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 988:

You forgot a '=back' before '=head2'