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?

ALERT! 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.

IDEA! 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:
  • Enclose the desired output into an INCLUDE SECTION called report
  • Enclose in another section, an HTML form which will POST to the /bin/save script the result of the desired output into a dedicated Report topic
  • Wrap all of the above in
    <verbatim class="foswikiHidden">...</verbatim>
    so the code isn't evaluated on each view
  • Write %INCLUDE{"Faq52Report"}% in place of the original (slow) code
  • Place a link to Faq52?section=generate inside an IF statement which hides the link from users unless they have CHANGE permission on the Faq52Report topic
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:

IDEA! You have permission to re-generate this list

Support.FAQForm edit

TopicClassification FrequentlyAskedQuestion
Subject Other...
Topic Summary Demonstrates the output of a nested search that can be saved to a topic at the push of a button; useful for generating "static" versions of slow pages
Extension
Interested Parties
Related Topics FormattedSearch
Topic revision: r2 - 27 Dec 2011, ArthurClemens
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy