At some point there was a policy decision to hide TWiki config from extensions. A number of functions were added to
TWiki::Func to portal access to these configuration items;
getPubUrlPath,
getWikiToolName,
getMainWebname,
getTwikiWebname,
getDefaultUserName,
getDataDir,
getPubDir, and
getRegularExpression are all simple no-op references to config items.
When the config was all in random global variables that made good sense, but now all the config is captured in
$TWiki::cfg and
$TWiki::regex the question arises whether there is any point to these functions. I don't think so, and I propose that we deprecate (though not remove) these functions and foster instead reference to
$TWiki::cfg and
$TWiki::regex.
Quite a large number of extensions already make direct use of
$TWiki::cfg (and while we're at it,
$TWiki::regex which is computed statically from
$TWiki::cfg) directly.
TWiki::Func has not kept pace with the development of the config, leaving extension authors with no other choice. On the other hand, the config is public (via
configure) and is kept stable.
Note that even if core developers change the implementation of
$TWiki::cfg in the future, it is a simple enough matter to provide a tied hash.
I'm raising this as a feature request on behalf of all extension developers. My feature request is a simple one: a clear statement (in EmptyPlugin and Func.pm) confirming public access to
$TWiki::cfg and $TWiki::regex= in extensions, and deprecation of the functions described above. No extra documentation is required of the config options; they are already documented via
configure.
No code changes are required.
--
Contributors: CrawfordCurrie - 07 May 2008
Discussion
That's an ambivalent question.
The
TWiki::Func API is our current way to guarantee a certain amount of encapsulation. I like that.
However, it sometimes bloats things and becomes a performance bottleneck, i.e in those cases where you only want to access
$TWiki::cfg. A pattern that you see very often - and that I followed myself most of the time - is to capture the return value of a
TWiki::Func::getMainWebname() (and similar) in a private variable
$mainWeb inside the plugin in an initialization step. That's simply to avoid any performance overhead of calling
TWiki::Func repeatedly for such a simple task that always returns the same value anyway.
Up to this point there's nothing wrong actually.
Where things
do fail is that the
TWiki::Func API, as you already said, did not keep pace with the variety of things that are stored in the
$TWiki::cfg hash. Even worse: it
can't because you don't know which and how plugins are installed that store settings in
$TWiki::cfg as well.
IMHO, the conclusion better should not be to advertise direct access to
$TWiki::cfg but to have a
TWiki::Func::getCfg("path/to/var") instead,
a generic way to access
$TWiki::cfg or whatever the config store implementation is actually. For example it could be an xml registry file as well.
All other standard calls would then be deprecated in favor of a call to
getCfg(), e.g.
getPubUrlPath() becomes
getCfg("PubUrlPath").
$TWiki::cfg{Htpasswd}{FileName} becomes
getCfg("Htpasswd/FileName"),
$TWiki::cfg{Plugins}{LdapContrib}{WikiNameAttribute} becomes
getCfg("Plugins/LdapContrib/WikiNameAttribute") etc
Finally, there are some configuration variables that we may need to protect, like access to
$TWiki::cfg{Password}.
--
MichaelDaum - 07 May 2008
I don't see the point of such a function; if the implementation of
$TWiki::cfg ever changed, we could simply use a tied hash to continue to provide it to extensions. Also, the standard of pathnaming configuration items e.g.
{Plugins}{TablePlugin}{Enabled} is well established; I don't see the point of adding a new syntax to refer to configuration items.
There is no compromise w.r.t encapsulation, because
$TWiki::cfg is just like your
getCfg function in all important respects. Indirection doesn't stop people writing to it.
--
CrawfordCurrie - 07 May 2008
I like the concept, and I feel inclined to Crawfords proposal, but both have their caveats:
- By impementing
getCfg("/Plugins/My/Config"), we will incur in an additional performance hit to extract the keys that will be used in the hash. So this would need a change in the backend of the configuration to be more "path-friendly".
- $=TWiki::cfg= works as long as the configuration is statically stored in a hash or in an storage mechanism that can be manipulated with a tied hash with at least the same performance as the current file-based solution, because the configuration is loaded at each topic read on sites that don't use accelerators.
Given that as soon as we publish the configuration, with any mechanism, will be nearly impossible to change it in the future, it would be good if more people comment on this.
--
RafaelAlvarez - 07 May 2008
will be nearly impossible to change it in the future It is already pretty much impossible to remove configuration items, because LocalSite.cfg file compatibility must be maintained, but as long as the
$TWiki::cfg hash is treated as
read only there is no problem with changing the way it works.
For example, at some point it would make sense to get rid of
{RCS}{EgrepCmd}, because "RCS" is just one of many different possible store implementations. So it might be changed to
{Stores}{RCS}{EgrepCmd}. In this case
configure would take on the responsibility of silently maintaining the
{RCS}{EgrepCmd} hash entry for any misguided plugins that might have used it.
Also, this situation already exists.
$TWiki::cfg is used in many (dare I say most?) plugins already.
--
CrawfordCurrie - 08 May 2008