This page contains sketch of the algorithm used when rendering and processing a form. It can help you understand various options and debug problems.

Step one: rendering the form

  • A (:pmform target:) markup is found.
  • The target description is retrieved from: (via PmFormConfig())
a) the $PmForm array,
b) if the target doesn't exist in $PmForm, a search is performed on a wiki page specified in $PmFormPageFmt variable (default: empty) - target names are separated from options list with a colon ':'.
  • The form-template is retrieved from a page specified in form= option of the target. This can be any section on any page. If no page is specified, {$SiteGroup}.LocalTemplates and {$SiteGroup}.PmFormTemplates are searched for the section (set via $PmFormTemplatesFmt).
  • Options marked XXX below:
    • (:pmform XXX:)
    • $PmForm['...']='XXX';
    • form-template -> (:template default XXX:)
are passed to the form-template. All {$$name}s are substituted with corresponding values retrieved from XXX.
  • The form-template is placed where (:pmform:) was, and markup processing is done (via PRR() function)
  • The (:input pmform target:) directive is processed using PmWiki core's InputActionForm() function, which is apparently used nowhere else. What does this function do?

Step two: filling the form

  • User fills the form fields and presses the submit button.

Step three: post-processing the form

  • The target is retrieved from the form data.
  • The target description is retrieved as in Step one.
  • The fmt-template is retrieved (similarly as the form-template was). (into $msgtmpl )
  • Two groups of options are collected:
    • safe options - from target description + from fmt-template,
    • full options - as above + data from the form.
  • The form is validated (the (:template require ...:) directives are executed).
If not passed, parsing is cancelled and errors are displayed.
If the form validated, processing is continued as described below. (Note somewhere that the strings "(:", ":)" and "$:" will each have a space inserted between the two characters, and that this can be configured by defining the $PmFormPostPatterns array in config.php.)
  • The value of the saveto option is retrieved from safe options and becomes the destination page.
  • If there's a (:pmform:) in the destination page with the same target as the currently processed one, options from the directive are merged with safe options. Important: Under exactly such a condition (apparently) the destination page can be modified even if user has no editing permission!
    If you use a different page for saving data, via saveto=, then you may need to add a (:pmform target:) into your second page in order to write the data without a password. Enclose this directive in an (:if false:) block to suppress the form itself.
  • The fmt-template is filled using full options (double-dollar markup - {$$name}).
  • The fmt-template is pasted into destination page based on the where option (safe options can have a wildcard specification for where), which defaults to new (which means: "If the page doesn't exist, create it and fill with the template").
  • If savevars were set in full options, PageTextVariables from the list are updated in the destination page.
  • If no errors found, the fmt-template is mailed. (This point needs more detail.) (function PmFormMail())
  • If no errors found and successpage was set in full options, browsing is redirected to page specified; if successpage is not set, current page is loaded with "?pmform=success" appended to the URL.
 0: 00.00 00.00 config start
 1: 00.00 00.00 config end
 2: 00.11 MarkupToHTML begin
 3: 00.15 MarkupToHTML end
 4: 00.16 MarkupToHTML begin
 5: 00.16 ReadApprovedUrls SiteAdmin.ApprovedUrls begin
 6: 00.17 ReadApprovedUrls SiteAdmin.ApprovedUrls end
 7: 00.18 MarkupToHTML end
 8: 00.18 MarkupToHTML begin
 9: 00.19 MarkupToHTML end
10: 00.19 now