Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Badger::Config::FilesyUser(Contributed Perl DocumBadger::Config::Filesystem(3)

       Badger::Config::Filesystem - reads configuration	files in a directory

	   use Badger::Config::Filesystem;

	   my $config =	Badger::Config::Filesystem->new(
	       root => 'path/to/some/dir'

	   # Fetch the data in user.[yaml|json]	in above dir
	   my $user = $config->get('user')
	       || die "user: not found";

	   # Fetch sub-data items using	dotted syntax
	   print $config->get('');
	   print $config->get('user.emails.0');

       This module is a	subclass of Badger::Config for reading data from
       configuration files in a	directory.

       Consider	a directory that contains the following	files and sub-


       We can create a Badger::Config::Filesystem object to read the
       configuration data from the files in this directory like	so:

	   my $config =	Badger::Config::Filesystem->new(
	       root => 'config'

       Reading the data	from "site.yaml" is as simple as this:

	   my $site = $config->get('site');

       Note that the file extension is not required.  You can have either a
       "site.yaml" or a	"site.json" file in the	directory and the module will
       load whichever one it finds first.  It's	possible to add	other data
       codecs if you want to use something other than YAML or JSON.

       You can also access data	from within a configuration file.  If the
       "site.yaml" file	contains the following:

	   name:    My Site
	   version: 314
	     name:  Andy Wardley

       Then we can read	the version and	author name like so:

	   print $config->get('site.version');
	   print $config->get('');

       If the configuration directory contains a sub-directory with the	same
       name as the data	file being loaded (minus the extension)	then any files
       under that directory will also be loaded.  Going	back to	our earlier
       example,	the "pages" item is such a case:


       There are three files relevant to "pages" here.	Let's assume the
       content of each is as follow:


	   one:	       Page One
	   two:	       Page Two


	   three:      Page Three
	   four:       Page Four


	   five:       Page Five

       When we load the	"pages"	data like so:

	   my $pages = $config->get('pages');

       We end up with a	data structure like this:

	       one   =>	'Page One',
	       two   =>	'Page Two',
	       admin =>	{
		   three => 'Page Three',
		   four	 => 'Page Four',
	       developer => {
		   five	 => 'Page Five',

       Note how	the "admin" and	"developer" items have been nested into	the
       data.  The filename base	(e.g. "admin", "developer") is used to define
       an entry	in the "parent"	hash array containing the data in the "child"
       data file.

       The "tree_type" option can be used to change the	way that this data is
       merged.	To use this option, put	it in a	"schema" section in the	top
       level configuration file, e.g. the "pages.yaml":


	   one:	       Page One
	   two:	       Page Two
	     tree_type:	flat

       If you don't want the data nested at all	then specify a "flat" value
       for "tree_type".	 This would return the following data:

	       one   =>	'Page One',
	       two   =>	'Page Two',
	       three =>	'Page Three',
	       four  =>	'Page Four',
	       five  =>	'Page Five',

       The "join" type collapses the nested data files by joining the file
       path (without extension)	onto the data items contain therein. e.g.

	       one	       => 'Page	One',
	       two	       => 'Page	Two',
	       admin_three     => 'Page	Three',
	       admin_four      => 'Page	Four',
	       developer_five  => 'Page	Five',

       You can specify a different character sequence to join paths via	the
       "tree_joint" option, e.g.

	     tree_type:	 join
	     tree_joint: '-'

       That would producing this data structure:

	       one	       => 'Page	One',
	       two	       => 'Page	Two',
	       admin-three     => 'Page	Three',
	       admin-four      => 'Page	Four',
	       developer-five  => 'Page	Five',

       The "uri" type is a slightly smarter version of the "join" type.	 It
       joins path elements with	the "/"	character to create URI	paths.

	       one	       => 'Page	One',
	       two	       => 'Page	Two',
	       admin/three     => 'Page	Three',
	       admin/four      => 'Page	Four',
	       developer/five  => 'Page	Five',

       What makes it special is	that it	follows	the standard rules for URI
       resolution and recognises a path	with a leading slash to	be absolute
       rather than relative to the current location.

       For example, the	pages/admin.yaml file could contain something like


	   three:      Page Three
	   /four:      Page Four

       The "three" entry is considered to be relative to the "admin" file so
       results in a final path of "admin/three"	as before.  However, "/four"
       is an absolute path so the "admin" path is ignored.  The	end result is
       a data structure	like this:

	       one	       => 'Page	One',
	       two	       => 'Page	Two',
	       admin/three     => 'Page	Three',
	       /four	       => 'Page	Four',
	       developer/five  => 'Page	Five',

       In this example we've ended up with an annoying inconsistency in	that
       our "/four" path	has a leading slash when the other items don't.	 The
       "uri_paths" option can be set to	"relative" or "absolute" to remove or
       add leading slashes respectively, effectively standardising all paths
       as one or the other.

	     tree_type:	 uri
	     uri_paths:	 absolute

       The data	would then be returned like so:

	       /one	       => 'Page	One',
	       /two	       => 'Page	Two',
	       /admin/three    => 'Page	Three',
	       /four	       => 'Page	Four',
	       /developer/five => 'Page	Five',

   root	/ directory / dir
       The "root" (or "directory" or "dir" if you prefer) option must be
       provided	to specify the directory that the module should	load
       configuration files from.  Directories can be specified as absolute
       paths or	relative to the	current	working	directory.

	   my $config =	Badger::Config::Filesystem->new(
	       dir => 'path/to/config/dir'

       Any additional configuration data can be	provided via the "data"	named

	   my $config =	Badger::Config::Filesystem->new(
	       dir  => 'path/to/config/dir'
	       data => {
		   name	 => 'Arthur Dent',
		   email => '',

       The character encoding of the configuration files.  Defaults to "utf8".

       A list of file extensions to try	in addition to "yaml" and "json".
       Note that you may also need to define a "codecs"	entry to map the file
       extension to a data encoder/decoder module.

	   my $config =	Badger::Config::Filesystem->new(
	       dir	  => 'path/to/config/dir'
	       extensions => ['str'],
	       codecs	  => {
		   str	  => 'storable',

       File extensions like ".yaml" and	".json"	are recognised by
       Badger::Codecs which can	then provide the appropriate Badger::Codec
       module to handle	the encoding and decoding of data in the file.	The
       codecs options can be used to provide mapping from other	file
       extensions to Badger::Codec modules.

	   my $config =	Badger::Config::Filesystem->new(
	       dir	  => 'path/to/config/dir'
	       extensions => ['str'],
	       codecs	  => {
		   str	  => 'storable',   # *.str files loaded	via storable codec

       You may need to write a simple codec module yourself if there isn't one
       for the data format you want, but it's usually just a few lines of code
       that are	required to provide the	Badger::Codec wrapper module around
       whatever	other Perl module or custom code you've	using to load and save
       the data	format.

       TODO: document specification of item schemas.  The items	below
       (tree_type through uri_paths) must now be defined in a schema.  Support
       for a default schema has	temporarily been disabled/broken.

       This option can be used to sets the default tree	type for any
       configuration items that	don't explicitly declare it by other means.
       The default tree	type is	"nest".

       NOTE: this has been changed.  Don't trust these docs.

       The following tree types	are supported:


       This is the default tree	type, creating nested hash arrays of data.


       Creates a flat hash array by merging all	nested hash array of data into


       Joins data paths	together using the "tree_joint"	string which is	"_" by


       Joins data paths	together using slash characters	to create URI paths.
       An item in a sub-directory can have a leading slash (i.e. an absolute
       path) and it will be promoted to	the top-level data hash.


	   foo/bar + baz  = foo/bar/baz
	   foo/bar + /bam = /bam


       No tree is created.  No sub-directories are scanned.   You never	saw
       me.  I wasn't here.

       This option can be used to set the default character sequence for
       joining paths

       This option can be used to set the default "uri_paths" option for
       joining paths as	URIs.  It should be set	to "relative" or "absolute".
       It can be over-ridden in	a "schema" section of a	top-level
       configuration file.

       The module inherits all methods defined in the Badger::Config and
       Badger::Workplace base classes.

       The following methods are defined for internal use.

       This overrides the default initialisation method	inherited from
       Badger::Config.	It calls the init_config() method to perform the base
       class Badger::Config initialisation and then the	init_filesystem()
       method to perform initialisation	specific to the
       Badger::Config::Filesystem module.

       This performs the initialisation	of the object specific to the
       filesystem object.

       This redefines the head() method	in the Badger::Config base class.  The
       method is called	by get() to fetch a top-level data item	(e.g. "user"
       in "$config->get('')").	 This implementation looks for
       existing	data items as usual, but additionally falls back on a call to
       fetch($item) to load additional data (or	attempt	to load	it).

   tail($item, $data)
       This is a do-nothing stub for subclasses	to redefine.  It is called
       after a successful call to fetch().

       This is the main	method called to load a	configuration file (or tree of
       files) from the filesystem.  It looks to	see if a configuration file
       (with one of the	known extensions appended, e.g.	"$item.yaml",
       "$item.json", etc) exists and/or	a directory named $item.

       If the file exists but the directory doesn't then the configuration
       data is read from the file.  If the directory exists

   config_tree($item, $file, $dir)
       This scans a configuration tree comprising of a configuration file
       and/or a	directory.  The	$file and $dir arguments are optional and are
       only supported as an internal optimisation.  The	method can safely be
       called with a single $item argument and the relevant file and directory
       will be determined automatically.

       The configuration file is loaded	(via scan_config_file()).  If the
       directory exists	then it	is also	scanned	(via scan_config_dir())	and
       the files contained therein are loaded.

   scan_config_file($file, $data, $path, $schema, $binder)
       Loads the data in a configuration $file and merges it into the common
       $data hash under	the $path prefix (a reference to an array).  The
       $schema contains	any schema rules for this data item.  The $binder is a
       reference to a tree_binder() method to handle the data merge.

   scan_config_dir($dir, $data,	$path, $schema,	$binder)
       Scans the diles in a configuration directory, $dir and recursively
       calls scan_config_dir() for each	sub-directory found, and
       scan_config_file() for each file.

       This method returns a reference to one of the binder methods below
       based on	the $name parameter provided.

	   # returns a reference to the	nest_binder() method
	   my $binder =	$config->tree_binder('nest');

       If no $name is specified	then it	uses the default "tree_type" of
       "nest".	This can be changed via	the tree_type configuration option.

   nest_tree_binder($parent, $path, $child, $schema)
       This handles the	merging	of data	for the	nest tree_type.

   flat_tree_binder($parent, $path, $child, $schema)
       This handles the	merging	of data	for the	flat tree_type.

   uri_tree_binder($parent, $path, $child, $schema)
       This handles the	merging	of data	for the	uri tree_type.

   join_tree_binder($parent, $path, $child, $schema)
       This handles the	merging	of data	for the	join tree_type.

       This method returns a Badger::Filesystem::File object representing a
       configuration file in the configuration directory.  It will
       automatically have the correct filename extension added (via a call to
       config_filename)	and the	correct	"codec"	and "encoding" parameters set
       (via a call to config_filespec) so that the data	in the configuration
       file can	be automatically loaded	(see config_data($name)).

       This method fetches a configuration file	via a call to config_file()
       and then	returns	the data contained therein.

       Returns a reference to a	hash array containing appropriate
       initialisation parameters for Badger::Filesystem::File objects created
       to read general and resource-specific configuration files.  The
       parameters are  constructed from	the "codecs" (default: "yaml") and
       "encoding" (default: "utf8") configuration options.  These can be
       overridden or augmented by extra	parameters passed as arguments.

       Andy Wardley <>

       Copyright (C) 2008-2014 Andy Wardley.  All Rights Reserved.

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

perl v5.32.0			  2016-12-12	 Badger::Config::Filesystem(3)


Want to link to this manual page? Use this URL:

home | help