Is there a nice way to make a (pre-computed) version of a slow page available, so Foswiki doesn't have to expand all its macros on every single view?
This solution saves the result of some macro expression(s), for example a complex report produced by SEARCH. This means the results will be the same for every user who visits the page, even if some parts of the report contain data from protected topics that other users wouldn't normally see if they viewed the report directly.
You should also consider Foswiki 1.1's PageCaching feature, which properly respects AccessControls. It also uses deep dependency tracking that tries to automatically remove (fully-rendered HTML) cache objects that are invalidated by topic updates, whereas the solution presented below only updates the report when you tell it to regenerate.
Foswiki ships with an
FAQ System.FAQRebuildingWikiUsersTopic, which includes an example of this technique. However, let's build a more realistic example - a
nested search which firstly queries all Support topics pertaining to extensions, and then for each of those, displays a list of the tasks against them.
So, this is the "slow" code, which you can the see result of by
clicking here:
%SEARCH{
"(form.name='BasicForm' OR form.name='Support.BasicForm') AND Extension"
type="query"
nonoise="on"
limit="10"
format=" * [[$web.$topic][$formfield(TopicTitle)]]$percntFORMAT{
\"$formfield(Extension)\"
header=\"$n\"
format=\"$dollarpercntINCLUDE{\\"%TOPIC%\\" section=\\"doextension\\" extension=\\"$dollartopic\\"}$dollarpercnt\"
}$percnt"
}%%STARTSECTION{"doextension"}%%SEARCH{
"Component~'*%extension%*'"
web="Tasks"
type="query"
nonoise="on"
limit="10"
nofinalnewline="on"
header=" * [[Extensions.%extension%][%extension%]]"
format=" * [[$web.$topic][$topic]]: $formfield(Summary)"
}%%ENDSECTION{"doextension"}%
The pattern is essentially:
Here's the necessary code:
%INCLUDE{"%TOPIC%Report"}%
<verbatim class="foswikiHidden">
%STARTSECTION{"report"}%%SEARCH{
"(form.name='BasicForm' OR form.name='Support.BasicForm') AND Extension"
type="query"
nonoise="on"
limit="10"
format=" * [[$web.$topic][$formfield(TopicTitle)]]$percntFORMAT{
\"$formfield(Extension)\"
header=\"$n\"
format=\"$dollarpercntINCLUDE{\\"%TOPIC%\\" section=\\"doextension\\" extension=\\"$dollartopic\\"}$dollarpercnt\"
}$percnt"
}%%STARTSECTION{"doextension"}%%SEARCH{
"Component~'*%extension%*'"
web="Tasks"
type="query"
nonoise="on"
limit="10"
nofinalnewline="on"
header=" * [[Extensions.%extension%][%extension%]]"
format=" * [[$web.$topic][$topic]]: $formfield(Summary)"
}%%ENDSECTION{"doextension"}%%ENDSECTION{"report"}%%STARTSECTION{"generate"}%
<form action="%SCRIPTURLPATH{"save"}%/%WEB%/%TOPIC%Report" method="post">
<textarea name="text">%INCLUDE{"%TOPIC%" section="report"}%</textarea>
<input type="hidden" name="redirectto" value="%BASEWEB%.%BASETOPIC%"/>
<input type="submit" value="Update"/>
</form>
%ENDSECTION{"generate"}%
</verbatim>
%IF{"'%WEB%.%TOPIC%Report' allows 'CHANGE'" then="<blockquote class='foswikiHelp'>$percntI$percnt You have permission to [[%TOPIC%?section=generate][re-generate]] this list</blockquote>"}%
And here's the result:
You have permission to re-generate this list