Skip to content

Commit

Permalink
Item14237: More docs on new specs.
Browse files Browse the repository at this point in the history
  • Loading branch information
vrurg committed Oct 1, 2017
1 parent f797404 commit 1b288a1
Show file tree
Hide file tree
Showing 3 changed files with 310 additions and 139 deletions.
32 changes: 16 additions & 16 deletions core/data/System/SpecFileFormat.txt
Expand Up @@ -7,7 +7,7 @@ about the history and the reasoning behind the specs in
[[Development.HowToWriteASpecFile]]. This document has more focus on specs
supported by %WIKITOOLNAME% v3.

%X% *NOTE* This document might not be a comprehensive description of the specs and
*%X% NOTE:* This document might not be a comprehensive description of the specs and
may require further improvements.

#BasicConcepts
Expand Down Expand Up @@ -91,18 +91,17 @@ There're three Spec formats supported out of the box:
pre-%WIKITOOLNAME% v3 era. Sure enough, it is supported for compatibility
matters but its use is discouraged.

=data= format is the basic and the simplest one. Its use is described in the
[[#BasicConcepts][Basic Concepts]] section.

=perl= format is somewhat more advanced as file content is considered to be
a body of a method called on a object of a class with
=%PERLDOC{Foswiki::AppObject}%= and =%PERLDOC{Foswiki::CfgObject}%= roles
applied. The actual class name is irrelevant and may vary depending on
implementation. The method will have local scalar =$this= available the code. It
must return a list with valid spec data.

=perl= format is good for a situation when some complex processing is necessary
before spec data could be formed.
$ =data=: is the basic and the simplest one. Its use is described in the
[[#BasicConcepts][Basic Concepts]] section.
$ =perl=: is somewhat more advanced as file content is considered to be
a body of a method called on a object of a class with
=%PERLDOC{Foswiki::AppObject}%= and =%PERLDOC{Foswiki::CfgObject}%= roles
applied. The actual class name is irrelevant and may vary depending on
implementation. The method will have local scalar =$this= available the code.
It must return a list with valid spec data. The format is good for
a situation when some complex processing is necessary before spec data could
be formed.
$ =legacy=: pre-%WIKITOOLNAME% v3 format.

---++ Data Format

Expand Down Expand Up @@ -305,7 +304,7 @@ these basic types share the following options:
element was read. Usually it's a string with file name but could be a \
strutrure containing a line number too. |

*NOTE:* _flag_ option type indicates that the option doesn't take a value. It
*%X% NOTE:* _flag_ option type indicates that the option doesn't take a value. It
is boolean and using it in =-option= form means the option is _on_; while
=-nooption= means _off_.

Expand Down Expand Up @@ -358,7 +357,7 @@ configuration UI code.
| =-enhance= | _flag_ | Set if enhancing earlier definition of the same key. |
| =-feedback= | | |
| =-hidden= | _flag_ | |
| =-label= | | |
| =-label= | _string_ | Configuration UI input field label text |
| =-onsave= | | |
| =-optional= | _flag_ | |
| =-spellcheck= | | |
Expand Down Expand Up @@ -399,4 +398,5 @@ The attributes above are related to configuration UI:

---++ Related

=%PERLDOC{"Foswiki::Config"}%=
=%PERLDOC{Foswiki::Config}%=, =%PERLDOC{Foswiki::Config::DataHash}%=,
=%PERLDOC{Foswiki::Config::Node}%=
60 changes: 40 additions & 20 deletions core/lib/Foswiki/Config/DataHash.pm
@@ -1,38 +1,46 @@
# See bottom of file for license and copyright information

package Foswiki::Config::DataHash;

=begin TML
---+ Class Foswiki::Config::DataHash
---+!! Class Foswiki::Config::DataHash
Container class for config specs. The config attribute =data= hash is tied to
this class when config is in specs mode.
Container class for config specs. The =Foswiki::Config= attribute =data= hash is
tied to this class when config is in specs mode.
---++ DESCRIPTION
This is only a container class. Actual specs are stored in a node data defined by
=Foswiki::Config::Node= class. Node data is kept in =nodes= hash. For example:
This is only a container class. Actual specs are stored in a node data defined
by =Foswiki::Config::Node= class. Node data are kept in =nodes= hash. For
example:
<verbatim>
$app->cfg->data->{Email}{MailMethod} = 'Net::SMTP';
</verbatim>
is actually represented by four objects: root =DataHash= stores a branch =Node=
in key _Email_ on =nodes= attribute. This node =value= attribute is a reference
to a hash tied to =DataHash= object named _Email_. _MailMethod_ key of the
=nodes= attribute contains a =Node= object which value is _Net::SMTP_.
is actually represented by four objects:
* =$app->cfg->data= is the root hashref tied to =Foswiki::Config::DataHash=.
* Key _Email_ of the hash in =nodes= attribute contains
a =Foswiki::Config::Node= object.
* The node object's =value= attribute contains a reference to hash tied
to =Foswiki::Config::DataHash=; its =name= attribute contains
_'Email'_.
* Its =nodes= attribute hash has a key _MailMethod_. The key is in
turn a =Foswiki::Config::Node= object.
* The node object's =value= is the string _'Net::SMTP'_.
Though this structure may seem a bit complicated but it serves two purposes:
1. Use of tied hash keeps the structure transparent for code using config
data. The code would deal with config data hash as usual and don't care
whether it's a plain data hash or specs loaded in memory.
1. Separate actual container from specs data. Mostly it should be sufficient
to request a spec data using full config path like _Email.MailMethod_.
1 Use of tied hashes keeps the structure transparent for code using config
data. The code would deal with config data hash as usual and doesn't care
whether it's a plain data hash or specs loaded in memory.
1 Separate actual container (a =Foswiki::Config::DataHash= object) from specs
data.
=cut

package Foswiki::Config::DataHash;

use Assert;
use Foswiki::Exception;
use Foswiki ();
Expand All @@ -45,11 +53,17 @@ use constant NODE_CLASS => 'Foswiki::Config::Node';

=begin TML
---++ ATTRIBUTES
=cut

=begin TML
---+++ ObjectAttribute nodes -> \%nodes
Hash nodes. Each key in the hash either doesn't exists or is a
=Foswiki::Config::Node= object. No other values like a scalar value or a non
=Foswiki::Config::Node= object are allowed.
Hash nodes. Each key in the hash either doesn't exists or is
a =Foswiki::Config::Node= object. No other values like a scalar value or
a object of any other but =Foswiki::Config::Node= class are allowed.
=cut

Expand Down Expand Up @@ -151,6 +165,12 @@ has _trace => (
builder => '_prepareTrace',
);

=begin TML
---++ METHODS
=cut

around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
Expand Down Expand Up @@ -233,7 +253,7 @@ sub STORE {
$node->value($value);

# Mark node as leaf if
$node->setLeafState(1) if $node->isVague;
$node->setLeafState(&Foswiki::Config::Node::LEAF) if $node->isVague;
}
}

Expand Down

0 comments on commit 1b288a1

Please sign in to comment.