The content of the Template file is merely HTML mixed with ASP Style script tags (<%= %> and <% %>) that are used to essentially merge the topic information into the template. The scripts are very powerful in that you can run code in them (using Visual FoxPro) to provide custom logic. Here's an exerpt from the TOPIC.WCS template and its header:
<html> <head> <title><%= TRIM(oHelp.oTopic.Topic) %></title> <LINK rel="stylesheet" type="text/css" href="templates/wwhelp.css"> </head> <body topmargin=0 leftmargin=0> <table border=0 width="100%" bgcolor="lightblue" class="banner" cellspacing="3" > <tr><td valign="center"><% if !EMPTY(oHelp.oTopic.SeeAlso) %> <span id="more" class="body" style="cursor:hand;color:darkblue" OnClick="SeeAlsoTopics.style.display='';more.style.display='none';less.style.display='';"> <img src="bmp/seealso.gif" border=0 alt="Related Topics" style="Font:normal bold 6pt Symbol;cursor:Hand"></span> </span> <span id="less" class="body" style="display:none" OnClick="SeeAlsoTopics.style.display='none';more.style.display='';less.style.display='none'"> <img src="bmp/seealso.gif" border=0 style="Font:normal bold 6pt Symbol;cursor:Hand"></span> </span> <div id="SeeAlsoTopics" STYLE="Display:None;margin-left:10pt" Class="body"> <span style="font:8pt Verdana"><i><%= oHelp.cProjectname %></i></span></td></tr> <tr><td><span style="font:10pt Verdana"><b><%= TRIM(oHelp.oTopic.Topic) %></b></span> </td></tr> </table> <div style="margin-left:10pt;margin-right=10pt"> <br> <div class="body"><%= oHelp.FormatHTML(oHelp.oTopic.Body) %></div> ... more code omitted here
As you can see this is plain HTML intermixed with ASP style expression that provide the actual content that is displayed from the topic. Two kinds of tags are supported:
<%= Expressions %>
like the following:
<html> <head> <title><%= TRIM(oHelp.oData.Topic) %></title>
You can also use entire blocks of code using the FoxPro language:
<% lcOutput = "" FOR x = 1 to 20 lcOutput = lcOutput + "Line " + TRANS(x) + "<hr>" ENDFOR Response.Write(lcOutput) %>
In addition you can mix the two. For example the following code conditionally excludes a block of HTML based on whether the Syntax field contains any data:
<table border='0' cellpadding='3' width='99%'>
<% IF !EMPTY(oHelp.oData.Syntax) %>
<tr>
<td width='122' valign='top' align='right' class='labels'><p align='right'>Syntax:</td>
<td><pre><%= TRIM(oHelp.oData.Syntax) %></pre>
</td>
</tr>
<% ENDIF %>
The concept is straight forward each template contains plain HTML plus some script tags to create the final merged content. If you've worked with ASP before this will feel familiar.
Note that Help Builder ships with default templates, so you don't have to modify the existing ones. Even if you do and you feel uncomfortable with the script code, you can still modify only the HTML and leave alone the script tags of the document. You can modify the entire visual layout of the document without ever touching the script blocks.
The most important thing to know about is the oHelp.oTopic subobject which contains all the content of the currently selected help topic. So oHelp.oTopic.Body returns the body of the current topic. oHelp.oTopic.Topic returns the title of the current topic and so on. For the field information take a look at the Topic data field layout field.
Because the wwHelp object is fairly complex you can also write fairly sophisticated code against it. You can run queries against the help file for example and retrieve topics of your choice then render them. The WHATSNEW template is a good example of this sort of code based content creation:
<% cCurrentPk = oHelp.oTopic.Pk cHTML = "" oTopics = oHelp.GetTopics("ARRAY","type # 'WHATSNEW'",; "updated DESC TOP 35","ParentPk,Pk") If !ISNULL(oTopics) AND oTopics.nCount > 0 cHTML = cHTML + "<H3>Recently updated topics</H3><p>" cHTML = cHTML + "<table align='center'>" cHTML = cHTML + "<tr><td><b> Name</b></td>" cHTML = cHTML + "<td><b>Description</b></td>" For lnLoop = 1 To oTopics.nCount oHelp.LoadTopic(oTopics.aTopics[lnLoop,2]) cHTML = cHtml + "<tr><td Align = 'Left' VAlign = 'Top'>" + TopicLink(oHelp.oTopic.Topic,oHelp.oTopic.Topic) +; "<br>" + DTOC(oHelp.oTopic.Updated) + "<td Align ='Left' VAlign ='Top'>" lcBody = oHelp.FormatHTML(oHelp.oTopic.Body) nBreak = ATC("<p>",lcBody) IF nBreak = 0 nBreak = ATC("<br>",lcBody) EndIf IF nBreak > 1 cHTML = cHTML + LEFT(lcBody,nBreak - 1) ELSE cHTML = cHTML + lcBody ENDIF cHTML = cHTML + "</td></tr>" EndFor oHelp.LoadTopic(cCurrentPk) cHTML = cHTML + "</table><p>" Response.Write( cHTML ) EndIf %>
This code runs a query and retrieves the 35 topics that were last updated and displays them in an HTML table. The output generated is plain HTML and embedded into the document via Response.Write() - again like ASP.
This is very powerful indeed. There are also a handful of highlevel helper functions available that make quick work of table generation. All of this information is available in the Developer features section of the Help File.