How can I process lists in Foswiki, or what is the modern replacement for ForEachPlugin?
Examples
There are two types of lists that you may want to process
1. Lists of topics
In Foswiki 1.1, you would use
FORMAT
macro:
%FORMAT{
"Faq1, Faq2, Faq3"
format=" * [[$web.$topic]] was modified $date by [[$wikiusername][$wikiname]] and is titled <em>$formfield(TopicTitle)</em>"
}%
Result:
- Support.Faq1 was modified 27 Dec 2011 - 16:14 by ArthurClemens and is titled How do you handle errors resulting from calls to CGI executables or REST handlers?
- Support.Faq2 was modified 27 Dec 2011 - 19:17 by ArthurClemens and is titled Does Foswiki have encrypted groups or any other technique to restrict access all the way?
- Support.Faq3 was modified 27 Dec 2011 - 19:22 by ArthurClemens and is titled How should I set filesystem access modes?
In Foswiki 1.0, you may use the
FilterPlugin
2. Lists of arbitrary strings
In Foswiki 1.1, you would use
FORMAT
macro with the
type="string"
parameter. This avoids some processing overhead when treating each member of the list as a topic.
%FORMAT{
"green, eggs, ham"
type="string"
header="The ingredients are:$n"
format=" * $index: $item"
}%
Result: The ingredients are:
In Foswiki 1.0, you may use the
FilterPlugin
2. List of arbitrary strings: section names
You can use FORMAT to display topic sections. To do this you write a
INCLUDE maco in the
format
string (escaped to delay processing):
%FORMAT{
"intro,notes"
separator=""
type="string"
format="$percntINCLUDE{$quot%TOPIC%$quot section=$quot$item$quot}$percnt"
}%
%STARTSECTION{"intro"}% This is the introduction. %ENDSECTION{"intro"}%
%STARTSECTION{"notes"}% These are the notes. %ENDSECTION{"notes"}%
Result:
This is the introduction. These are the notes.
Before:
%FOREACH{"web" in="Main, Sandbox, System"}%
* [[$web.WebHome]]
%NEXT{"web"}%
After: (Foswiki 1.1)
%FORMAT{
"Main, Sandbox, System"
type="string"
format=" * [[$item.WebHome]]"
}%
After: (Foswiki 1.0 using
FilterPlugin)
%FORMATLIST{
"Main, Sandbox, System"
format=" * [[$1.WebHome]]"
}%
Converting more complex usage
ForEachPlugin allows more complex multi-line sections to be processed in the list, as follows:
Before:
%FOREACH{"topic" in="Faq1, Faq2, Faq3"}%
---+++ [[%WEB%.$topic]]
* one
* two
And some other stuff
%NEXT{"topic"}%
After, format string with newlines: This is the simplest conversion
%FORMAT{
"Faq1, Faq2, Faq3"
format="---+++ [[$web.$topic]]
* one
* two
And some other stuff: modified on $date by $wikiusername"
}%
However, special care must be taken to avoid unwanted effects of
inside-out, left-to-right macro expansion, such as:
- Remembering to escape
"
quotes as \"
so that the format
string ends where you want it
- Remembering to delay any macros contained within the string, if necessary
Below is an example which addresses these two problems more easily
After, delayed sectional includes: Use
delayed sectional
INCLUDEs in the
FORMAT macro's
format
parameter:
%FORMAT{
"Faq1, Faq2, Faq3"
format="$percentINCLUDE{
\"%TOPIC%\" section=\"topicthing\"
web=\"$web\" topic=\"$topic\"
modified=\"$date\" modifiedby=\"$wikiusername\"
}$percent\""
}%
<verbatim class="foswikiHidden">
%STARTSECTION{"topicthing"}%
---+++ [[%web%.%topic%]]
* one
* two
And some other stuff: modified on %modified% by %modifiedby%
%ENDSECTION{"topicthing"}%
</verbatim>
This approach looks more cumbersome than
ForEachPlugin, but allows us to use a standard "registerTagHandler" type macro (
VarFORMAT or
FilterPlugin) rather than the old, less reliable "commonTagsHandler" type macros which
ForEachPlugin provides.
--
PaulHarvey - 22 Dec 2010