How can I process lists in Foswiki, or what is the modern replacement for ForEachPlugin?

TIP Some examples of the FORMAT macro where you might have used ForEachPlugin can also be found at Faq40

View this topic on trunk to see rendered output.

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:
Error: no such plugin chili
%FORMAT{
  "Faq1, Faq2, Faq3"
  format="   * [[$web.$topic]] was modified $date by [[$wikiusername][$wikiname]] and is titled <em>$formfield(TopicTitle)</em>"
}%

Result:

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.

Converting ForEachPlugin usage

Before:
Error: no such plugin chili
%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: 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
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. see CopyrightStatement. Creative Commons LicenseGet Foswiki at sourceforge.net. Fast, secure and Free Open Source software downloads