Feature Proposal:
Motivation
This proposal comes from analysis of the requirements of the
SitePermission page, as discussed in
Tasks.Item2394. Thinking about that problem made me realise there may be something more generally useful in there.
SitePermissions enumerates per web. In each web, showing the DENYWEB and ALLOWWEB settings for that web. The values used by the access checking code can be determined using $meta->getPreference() where $meta is a web object (known in the code as a "web preference".
This requires some sort of general mechanism that will "expand this macro in another context". This would return the value of a macro as it would be if the current topic (web) were something else. For example, if I'm editing topic "ThisTopic" and I write
%EXPAND{"$percntFLURB$percnt" scope="ThatTopic"}%
it would return the value of
FLURB
as if "ThatTopic" were the current topic.
scope
would default to the current web.topic, so this makes this doubly interesting, since it supports delayed expansion.
Description and Documentation
EXPAND{"expression" scope="topictoexpandin" ...}%
Expands macros in expression
as if they were used in the topic topictoexpandin
. The viewer must have VIEW access to topictoexpandin
for this to work. All the standard formatting macros can be used in expression
, such as $percnt
and $quot
.
%EXPAND can be useful when you want to pick up the value of macros defined in another topic. For example, you might want to define a set of preferences in one topic, but pick up their value in another topic (this is very useful when building reusable applications). In this case you can write:
* Set MYPREFERENCE = value
in "SettingsTopic" and then, in "MyTopic", write:
%EXPAND{"$percntMYPREFERENCE$percnt" scope="SettingsTopic"}%
Of course we can also write:
%EXPAND{"$percntMYPREFERENCE$percnt" scope="%OTHERTOPIC%"}%
which lets us select which other topic to get the preference value from.
Additional parameters can be passed to the macro being expanded using the standard macro syntax in the name of the macro; for example,
=
EXPAND failed - no such topic 'SettingsTopic'
=
Notes:
- %EXPAND is not very efficient, and should be used sparingly.
- To expand a web preference (for example, a web access control) then set
scope="Theotherweb.%WEBPREFSTOPIC%"
Implementation
The implementation is straightforward - a new macro implementation in the Macros dir, 30 lines or so. I have tested it as described above, and it works beautifully.
--
Contributors: CrawfordCurrie - 20 Jan 2010
Discussion
please don't overload the keyword
context
to mean a topic.
and we ought to work out a param to mean output 'X' if the Setting / macro does not exist, and what to show if the user doesn't have permission to that web/topic
also, what fun - expand a macro in a different topic's
context, but as its a setting expand to that topic's web preferences rather than the current topic's web preferences, and then :}
--
SvenDowideit - 20 Jan 2010
I can see the value expanding TML in a different scope (probably better term than context). The above pattern to motivate %EXPAND to get the value of a pref value defined in a different topic
is quite common and already solvable using different means, e.g.
SetVariablePlugin's %GETVAR. This is also related to
SettingAndGettingVariablesUsingMacros
where we will implement %SET and %GET macros. The latter could easily be extended by adding a
topic
parameter.
So all it needs is a somewhat better example to motivate %EXPAND that illustrate its usefulness and uniqueness ... that it definitely has. I just can't come up with a better example myself right now.
--
MichaelDaum - 20 Jan 2010
There is a minor discrepancy between the
Motivation and the
Description and Documentation.
The
Motivation has
%EXPAND{"FLURB" topic="ThatTopic"}%
whereas the
Description and Documentation has
%EXPAND{"$percntMYPREFERENCE$percnt" context="SettingsTopic"}%
There are two similar alternatives: %SEARCH and %INCLUDE
-
%SEARCH{search="." type="regex" topic="ThatTopic" format="<insert TML here>" nonoise="on"}%
- but with %EXPAND, the TML is evaluated as if in ThatTopic
-
%INCLUDE{"ThatTopic" section="SomeSection TML="<insert TML here>"}%
- but %EXPAND can evaluate TML in the context/scope of another topic without needing an %INCLUDE-able section.
%EXPAND would give
topic="OtherTopic"
capability to all macros (including those provided by plugins, and via the
EasyMacroPlugin) that do not have built-in
topic
parameters. This is useful to users, and it allows for simpler plugins.
%EXPAND and
HereDocumentSyntaxForMacros would be a powerful combination.
I would like to suggest a
rev
option, so that TML could be expanded as if in any specific revision of any arbitrary topic.
--
MichaelTempest - 20 Jan 2010
Sven, dead right; all I can suggest is wrapping the macro reference in a %IF. Because expand expands an arbitrary string rather than a single macro, it's not well placed to insert default values. I have changed
context
to
scope
. At the moment, errors are reported as string returns (not even using
foswikiAlert
)
Michael, yes, there are plugins that do this kind of thing (perhaps). Yes, it's related to SET and GET, with the difference that EXPAND works on an arbitrary string, expanding all macros in it in a different context, so is unlike GET in that respect.
While the rev option is on the face of it attractive, the preferences code has no support for building a preference DB based on old revs of topics, so it is far from a low-hanging fruit.
I'm checking this in for you to play with.
--
CrawfordCurrie - 20 Jan 2010
Since you have already committed it on
SVN I assume you are a committed developer so I added your name and todays date so it gets listed in the 14 day rule list.
With the changes already made I support this feature.
On the documentation part maybe one more example will help its use. That is an easy thing to do once we get a little used to it.
This feature for sure fills a gap in the core that people have had for years.
--
KennethLavrsen - 20 Jan 2010