Life of a topic: Store -> Browser

When you view a topic on Foswiki, the "View" script, a lot goes on under the covers, but the basic steps are illustrated here:
  • The base topic .txt file is read from the store.
  • The topic object is established, the preferences are all resolved.
    • The Default, Site, Web, User and Topic preferences are all merged
    • ACL checks are performed, and if the user is allowed to access the topic, work proceeds.
  • The view template is selected and used to organize the content. It breaks into 3 sections, header, body and footer.
  • The expansion/render process is run 3 times, for each context: header_text, body_text and footer_text:
    • Macros are expanded. This needs multiple passes, as expansion of macro content may generate more macro content.
    • The TML is then rendered into HTML
  • The "writeCompletePage" processes the results and delivers the response to the user.
This topic will break these steps down further, focusing on the heavy work - expanding macros and rendering the TML.

foswiki-life-of-topic.png

Expanding Macros: Foswiki::expandMacros()

TIP This is part of the Foswiki API. It can be invoked using either:
  • Foswiki::Func::expandCommonVariables() or
  • Foswiki::Meta::expandMacros()

  1. dispatch beforeCommonTagsHandler
  2. Protect <verbatim> block
  3. Protect <dirtyarea> areas
  4. Expand Macros
    • Left to Right, Inside-out
  5. Protect any added <verbatim> blocks
  6. dispatch commonTagsHandler
  7. Expand macros again. (commonTagsHandler may have inserted macros)
    • Left to Right, Inside-out
  8. Process TOC macro
  9. Restore <dirtyarea> areas
  10. Restore <verbatim> blocks
  11. dispatch afterCommonTagsHandler

See System.Macros for user documentation on macro expansion.

Rendering TML Foswiki::Render::getRenderedVersion()

TIP This is also part of the formal Foswiki API, and can be invoked either by calling:
  • Foswiki::Func::renderText() or
  • Foswiki::Meta::renderTML()

  1. Protect <verbatim> blocks
  2. Protect <literal> blocks
  3. Protect <dirtyarea> blocks
  4. Protect certain blocks
    • <? ... ?>
    • <doctype
    • <head
    • <textarea
    • <script
    • <style
  5. dispatch startRenderingHandler (DEPRECATED)
  6. Protect <pre> blocks
    • dispatch preRenderingHandler
    • dispatch insidePreHandler line-loop on removed pre blocks - (DEPRECATED)
    • dispatch outsidePreHandler line-loop on the rest - (DEPRECATED)
    • Protect <input tags
    • Process HTML/TML
      • > style blockquote email => <cite...
      • Handle inline <html>
      • Convert & to &amp when not part of a named or numeric entity
      • Process Anchors
      • Process ---+ headings
      • Process --- horizontal rule
      • Line loop
        • Process tables and lists markup
      • TML markup == __ * _ =
      • Explicit links
      • Autolinking
      • Remove <noautolink> blocks
      • Process WikiWords
        • dispatch renderWikiWordHandler for each WikiWord
    • Restore <noautolink> blocks
    • Restore protected <input tags
    • Restore <pre blocks
  7. dispatch endRenderingHandler DEPRECATED
  8. Restore Blocks
    • verbatim (convert to <pre> block)
    • <style
    • <script
    • <literal
    • <literal ??? why twice I think this is an error - only the Foswiki::putBackBlocks call is required. I think the other call persisted through some other changes - C.
    • <dirtyarea
    • <? ... ?> and <doctype comments
    • <head
    • <textarea
  9. Call loginManger endRenderingHandler This behaviour is deprecated. IIRC it was intended to support plugins that overrode the login process, and I'm pretty sure nothing uses it. C.
    • =Foswiki::LoginManager= uses this call to rewrite all internal links and form actions when $Foswiki::cfg{Sessions}{IDsInURLs} is enabled.
    • It also replaces to old Skin tokens: %SKINSELECT% and %SESSIONLOGON%, neither of which appear in any repository that I can find.
  10. dispatch postRenderingHandler

writeCompletePage Foswiki::writeCompletePage()

  • Insert strikeone protection
  • expand any zones (head, script)
  • dispatch completePageHandler
  • Process page cache
    • Cache the page
    • Render dirty areas
  • Remove dirtyarea tags
  • Optional, gzip compression
  • Generate Headers
  • Write the page to the browser.

Protecting Blocks

Blocks of content are protected from rendering by removing them from the content and replacing them with a neutral placeholder using characters that are not processed by rendering. Removed blocks are restored in the reverse order in which they were protected.

Blocks to be protected are matched using regular expressions that search the text for matched pairs of XML-style open/close tags (e.g. <verbatim>>...</verbatim>. Regexes are stupid, and protecting tags in content must be carefully ordered, and nesting avoided.

Note that protecting a block is not a guarantee that the content will be unaffected by rendering, as plugins postRenderingHandler is invoked after protected blocks are restored.

BasicForm edit

TopicClassification DeveloperDocumentation
TopicSummary Detailed look into how a topic is transformed from the stored .txt file to HTML
InterestedParties
Topic revision: r4 - 15 Feb 2018, GeorgeClark
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