01214: Document a "recommended" way to use core functions from config files
TL;DR The recommended way to call core functions is to either include scripts/stdconfig.php before calling them. This is documented now.
From a discussion with DaveG:
DaveG: Something else that is particularly inconsistent is documentation around the use of functions like ResolvePagename, PageTextVars, etc, for config processing.
For instance, *in general* documentation suggests the use of PageVar to determine group/page for specific config settings ie, PmWiki/GroupCustomizations). Which contradicts the generally suggested flow to use these types of functions only at the end of config processing. Combine this with documentation around config/farm/group config processing, and it's pretty inconsistent, and very spread out across many pages.
Petko: I agree that there is a problem, only it is not about how to document it, the problem is *using* these functions too early. I don't think these functions were designed to be used from config files, and they shouldn't be used. We're deviating a little away from the documentation topic we started with, but if the functions were not designed to be used in the manner they are now being used, then we should document that. In addition though, we should be providing a way to get the information these functions provide from within config -- and then documenting it.
(eg. PageVar should be used from inside functions, called by Markup() rules.)
DaveG: This is a good example. There are many use cases where it would be useful to have page attribute values from config. I understand PageVar shouldn't be used for that, but perhaps we need to come up with a way to either enable PageVar to be used in these situations, or provide an alternate mechanism. That mechanism may be a new function(s), or might simply be helping developers utilize existing functions more appropriately. The key here, it to provide support at a level it can be understood -- not everyone is at the same level of coding sophistication -- and document it in a consistent way.
Petko: If you want to enable or disable something for a single group or page, you are supposed to use the Group.php, Group.Page.php or default.php scripts. A recipe that wants to be run after group/page customizations should include pgcust.php, that should be the standard recommendation for such situations.
DaveG: Again, we're away from documentation, but briefly, Group configs may not be a reasonable solution in all cases, so perhaps some alternatives need to be considered. For instance, some config needs to occur in all Groups, except one. Can't do that from Group config. The documentation that would help here, is a single consistent way to determine the Group from config.php -- we use that recommendation moving forward, and strike the ways from the wiki.
Petko: The next version 2.2.17 will allow you to include scripts or to call functions even after stdconfig.php.
DaveG: I noticed that activity on the wiki, but the discussion went over my head.
Petko: The advice about calling these functions at the end of config.php was mostly added by me. At the time I thought that using them this way would create less problems, but unfortunately that was not the bestest thing to do. If we notice a side-effect instead of a designed feature, we probably shouldn't rush to document it -- people could start building on it. :-)
DaveG: Very true. But in these cases, lets come up with the 'recommended' way, and document it. Overrride the older advice. I'd be happy to document these things (as would others I'm sure), but I'm rarely sure of the recommended way.
(End of original excerpt)
Sven: Maybe I or others can help better if you could explain some example use cases of what kinds of configuration has to be done and, unless it's obvious, why it has to be done at config time. A lot of "feature not ready at this stage" problems can be solved by defering code execution. — Sven June 24, 2017, at 05:28 PM
This was mostly discussed when the $PostConfig was in planning or just written and kind-of experimental. Today I'd recommend adding these calls in a $PostConfig function of file, either after stdconfig.php (recommended, if possible, value>100) or after group and page configuration (value < 50).
One could want to use these functions to get a page variable from a specific page in config.php, or check if the user has edit or admin permissions, and do something conditionally based on that result (enable a markup, change the skin, set some variables, load a function...) search for "config.php CondAuth" or "config.php PageVar" and you'll find a number of places where people explain why they want this.
The problem is that in config.php the
$pagename variable may not yet be correctly sanitized and formatted (CamelCase...) and also most of these functions will call each other and cache some of the results ($PCache, $acache) -- both can possibly break the future processing and/or be insecure. Having them in $PostConfig is hopefully after any configuration settings have been done, and just before the "action" is processed, makes it less risky for something to break. --Petko June 24, 2017, at 06:15 PM
Just to make it clear, the "risky" part is only when calling the functions directly in config.php or Group.Page.php, or from a cookbook recipe as/when it is loaded. There is no risk if the functions are called from a skin.php file, from a function called by MarkupToHTML() ie markup rules, or by a function called by UpdatePage() ie those from
$EditFunctions. --Petko June 24, 2017, at 06:23 PM
Sven: Should PageStores perform extra checks to prevent their standard API methods (exists read ls write delete) from using pagename-related functions too early, or can a PageStore expect to only get requests once all core is ready? — Sven June 24, 2017, at 07:23 PM