Previous Page TOC Next Page



- 8 -
HTML Extension Files


Hypertext extension files are used by Microsoft Internet Information Server to identify specially formatted HTML documents, including the special tags used to handle such items as looping constructs for multi-document result sets and if-then-else control blocks. If you are familiar with .htx files that are used with Internet Database Connector (IDC), .htx files used with Microsoft Index Server should come as no surpass to you. However, there are a few subtle differences between these two varieties of .htx files. For example, Index Server .htx files are referenced from an accompanying .idq file, whereas the Internet Database Connector references .htx files in an accompanying IDC file.

.htx File Tags


In addition to standard HTML tags and data, .htx files can also be composed of special HTML-like tags that permit the result-set documents to be processed and output to be generated based on the conditions that the tags validate. In the following section, you will learn how these tags are used to identify the block of HTML code that will be processed for each result-set document, to perform if-then-else test conditions, and to identify special formatting of output.

<%begindetail%> and <%enddetail%> Tags


The <%begindetail%> and <%enddetail%> tags surround the portion of the HTML extension file in which the query result-set documents will be merged. Each record returned in the result set will be processed against the HTML code contained within the detail section. From a programmers point of view, the <%begindetail%> and <%enddetail%> tags act much like a for each looping construct in that if no records are returned, the detail section is ignored. Column names (results data) are referenced within the detail section by enclosing them with <% and %> symbols.



An HTML extension file can contain only one set of <%begindetail%> and <%enddetail%> tags.

The following .htx file code shows how the <%begindetail%> and <%enddetail%> tags are used as well as how column results are referenced within the detail section.


<!--

    Process returned record set data and display the abstract and

    other associated record data.

-->

<%begindetail%>

<p>

<%CiCurrentRecordNumber%>.

<b><a href="<%EscapeURL <%path%>"><%filename%></a></b>

<b><i>Abstract: </i></b><%characterization%><br>

<font size=-1><%size%> bytes - <%write%></font>

<%enddetail%>

<%if%>, <%else%> and <%endif%> Tags


The <%if%>, <%else%> and <%endif%> tags together form a conditional logic control flow that can be used to determine how records are processed. The most common use of the if-then-else statement is to determine whether any records were returned by the query. If no records are returned, a standard No records found to match query. Please try again reply can be generated.

The following .htx file code shows how the built-in variable CiLastRecordNumber can be used to determine when no records were returned from the query.


<!--

    Example htx file code to check the status of the built-in

    variable CiLastRecordNumber to verify when no records were

    returned from the query.

-->

<%begindetail%>

<%if CiCurrentRecordNumber EQ 1%>

   Query results:

<%endif%>

<P>

<%CiCurrentRecordNumber%>.

<b><a href="<%EscapeURL <%path%>"><%filename%></a></b>

<b><i>Abstract: </i></b><%characterization%><br>

<font size=-1><%size%> bytes - <%write%></font>

<%enddetail%>

<P>

<%if CiLastRecordNumber EQ 0%>

   <I><B> No records found to match query.  Please try again.</B></I>

   <P>

<%endif%>

The syntax for using the <%if%>, <%else%> and <%endif%> tags is as follows:


<%if condition%>

    HTML code

<%else%>

    HTML code

<%endif%>

where the condition is of the following form:


valueX operator valueY

X and Y may be in the form of built-in variables, column names, an HTTP variable name (see Appendix B, "Internet Data Query (.idq) File and HTML Extension (.htx) File Variables," for a complete listing of HTTP variables), or a constant. Table 8.1 displays the list of valid condition operators.

Table 8.1. Valid condition operators.

Operator Condition (True if)
EQ valueX is equal to valueY
NE valueX is not equal to valueY
LT valueX is less than valueY
LE valueX is less than or equal to valueY
GT valueX is greater than valueY
GE valueX is greater than or equal to valueY
CONTAINS any part of valueX contains the string valueY
ISTYPEEQ valueX is of type valueY
ISEMPTY valueX is of type VT_EMPTY, or of type VT_NULL,or is of a textual type (VT_LPSTR, VT_LPWSTR, VT_BSTR,or vectors of the preceding types) and contains only empty characters (space, tab, and so on).


The following code demonstrates the use of the <%if%>, <%else%> and <%endif%> tags in conjunction with the HTTP variable HTTP_USER_AGENT to determine whether the type of Web browser is a version of Microsoft Internet Explorer.

<%if HTTP_USER_AGENT contains "Explorer"%>

    Microsoft Internet Explorer-supported HTML code

<%else%>

    other browser-supported code

<%endif%>


The <%EscapeHTML%>, <%EscapeURL%>, and <%EscapeRAW%> Tags


The <%EscapeHTML%>, <%EscapeURL%>, and <%EscapeRAW%> tags are used to determine how specified output text strings are to be formatted. The most common use of these tags is in conjunction with the variables CiRestriction and CiScope when building a form or generating an anchor.

The syntax used for these tags is either <%EscapeHTML variable%>, <%EscapeURL variable%>, or <%EscapeRAW variable%>. In each case, variable can be any valid .htx file parameter, variable, or constant value. The following code displays the use of a constant value with the <%EscapeURL%> tag.


<a href="<%EscapeURL vpath%>">http://<%server_name%><%vpath%>

Some HTML characters have special meaning (such as the < and > characters, which are used for delimiting HTML tags). The <%EscapeHTML%> tag provides a means for replacing these special characters with their escaped equivalents. For example, the symbol > will be replaced with &gt, and the symbol < will be replaced with &lt. The following .htx code shows how the <%EscapeHTML%> tag is used.


<%if CiMatchedRecordCount eq 0%>

   No virtual roots matched the query "<%EscapeHTML CiRestriction%>".

<%else%>

   Virtual roots <%CiFirstRecordNumber%> to <%CiLastRecordNumber%> of

     <%CiMatchedRecordCount%> matching the query

     "<%EscapeHTML CiRestriction%>" for catalog <%CiCatalog%>

<%endif%>

The <%EscapeRAW%> tag is used in cases where no escaping is needed (as in the case of a variable that is being used as the value of a form variable). The following .htx code displays the use of the <%EscapeRAW%> tag within a form to generate a hidden field that contains the value for the maximum records per page.


<INPUT TYPE="HIDDEN"

 NAME="CiMaxRecordsPerPage"

 VALUE="-<%EscapeRAW CiMaxRecordsPerPage%>">

Validating Query Execution Variables


Index Server includes three read-only query-execution variables whose query results can be checked in the associated .htx file to determine proper formatting of the output. The three parameters are CiOutOfData, CiQueryTimedOut and CiQueryIncomplete. Using the test-condition syntax mentioned previously, developers can test for unexpected query results in the .htx file by validating the status of the three variables.



It is a good practice to always test the status of the built-in variables by using the standard <%if. . .%> test syntax in your .htx file.


The CiOutOfDate Variable


The CiOutOfDate variable is used to test whether the content index has additional files to filter or scans to complete. When set to 1 (true), the content index is considered out of date and information returned as results may either be missing or considered old.



When this variable is set to 1, some information may be considered inaccurate because it is possible to get results for files that have already been deleted or whose current version does not match the query.

The following .htx file code tests the condition of the CiOutOfDate variable and notifies the end-user that the index is out of date.


<!--

     Notify the user when the index is out of date.

-->

<%if CiOutOfDate ne 0%>

    <P>

    <B>The index is out of date.</B>

    <BR>

<%endif%>

The CiQueryTimedOut Variable


The CiQueryTimedOut variable is used to test whether the CPU time used to execute the query has exceeded the limit specified in the systems registry. For nonsequentially executed queries, the variable is set to 1 (true) and is valid for all documents in the result set. For sequentially executed queries, the CiQueryTimedOut variable is valid only after all available results for the query have been displayed.

The following .htx file code tests the condition of the CiQueryTimedOut variable and notify the end-user that the query has timed out and is unable to continue processing.


<!--

    Let the user know when the query timed out.

-->

<%if CiQueryTimedOut ne 0%>

    <P>

    <B>The query timed and is unable to continue processing.</B>

    <BR>

<%endif%>

The CiQueryIncomplete Variable


The CiQueryIncomplete variable is used to identify when a portion of the query restriction was ignored and not processed. The variable is set to 1 to identify an incomplete query restriction and can occur under certain conditions, such as when a query is forced to use the content index.

The following .htx file code tests the condition of the CiQueryIncomplete variable and notifies the end-user of an expensive query condition.


<!--

    Notify the user when the query could not be executed because

    a portion of the query restriction was not processed.

-->

<%if CiQueryIncomplete ne 0%>

    <P>

    <B>Unable to complete query.  Query restriction not processed.</B>

    <BR>

<%endif%>

Results Formatting


One of the most important features of any indexing system is support for the formatting and presentation of results. Microsoft Index Server includes many built-in variables that you can take advantage of when determining how record results will be formatted and displayed to the end-user. The built-in variables you will learn about in this section include

These built-in variables can be used in conjunction with other .htx file tags such as the <%if%>, <%else%> and <%endif%> tags to determine how the results will be presented.

The CiMatchedRecordCount Variable


The CiMatchedRecordCount variable is used to identify how many documents matched the specified query. This variable is most commonly used to notify the user of exactly how many records matched the specified query. The following short code segment demonstrates how the CiMatchedRecordCount variable is used in an .htx file.


<%if CiMatchedRecordCount eq 0%>

   No documents found to match query: "<%CiRestriction%>".

<%endif%>

Although this code is quite simple, it notifies the user that no records were found to match the specified query. Sure, you could have simply returned the appropriate text that specifies exactly how many matching query documents were found with the following code segment:


<%CiMatchedRecordCount%> documents found to match query: "<%CiRestriction%>".

However, as you'll see in the sections that follow, you will generally need to notify the user of other conditions such as when the maximum number of records allowed in the result set was returned.

The CiMaxRecordsInResultSet Variable


The CiMaxRecordsInResultSet variable is set in the .idq file that references the .htx file and is used to specify the maximum number of query results to be returned in the result set. This parameter is most commonly used to limit server usage on any one query by limiting the number of records returned by the query.

Taking the sample code segments from the previous section one step further, you can use the CiMaxRecordsInResultSet variable to check for other conditions that affect the use of the CiMatchedRecordCount. Take, for example, a scenario where the .idq file has specified a maximum number of records in the result set as 500. If the user specifies a query that has 700 matching documents, only the first (best matching) 500 documents are returned. In such a case, you might want to notify the user that there may be other documents that were not returned because of the limitation placed on the query. This is where the variable CiMaxRecordsInResultSet is very useful. The following .htx file code demonstrates the use of the CiMaxRecordsInResultSet variable.


<%if CiMatchedRecordCount eq 0%>

   No documents found to match query: "<%CiRestriction%>".

<%else%>

   <%if CiMatchedRecordCount eq CiMaxRecordsInResultSet%>

      The highest ranking

   <%endif%>

   <%CiMatchedRecordCount%> documents for query

         "<%CiRestriction%> were returned.

<%endif%>

Looking at the preceding code segment, you see that if the CiMatchedRecordCount is equal to the CiMaxRecordsInResultSet, there is a good chance that additional documents also matched the query but were not returned because of the CiMaxRecordsInResultSet restriction. In this case, the text string The highest ranking would precede the text string that identifies the number of documents returned.

The CiBookmark and CiBookmarkSkipCount Variables


The CiBookmark variable identifies the first record on a page and is used as a reference point for navigating to the next page or the previous page. The CiBookmarkSkipCount variable is used in conjunction with the CiBookmark to specify the relative offset from the current page in which the next page will begin. For example, if the current page displays documents 1–10 with the CiBookmark set to the first document and the CiBookmarkSkipCount is set to 20, the next page displayed would be documents 21-30.



CiBookmarkSkipCount is generally set either to <%CiMaxRecordsPerPage%> (next page) or to<%CiMaxRecordsPerPage%> (previous page), but it can be set to any multiple of CiMaxRecordsPerPage. The CiBookmarkSkipCount variable is generally set as a hidden form variable.

The following sample code segment demonstrates the use of the CiBookmark and CiBookmarkSkipCount variables as hidden form variables.


<FORM ACTION="/scripts/samples/search/queryhit.idq" METHOD="GET">

   <INPUT TYPE="HIDDEN" NAME="CiBookMark"

      VALUE="<%CiBookMark%>" >

   <INPUT TYPE="HIDDEN" NAME="CiBookmarkSkipCount"

      VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

</FORM>

The CiContainsFirstRecord Variable


The CiContainsFirstRecord variable is used to identify whether the current page contains the first record of the query results. If the first record is included in the current page, the CiContainsFirstRecord variable is set to 1. An ideal use for this variable is to determine how navigational buttons are to be displayed. For example, if this is the first page of a record set displayed, you would not want to display a navigational button for the previous documents because no previous documents would exist. The following code sample demonstrates the use of the CiContainsFirstRecord variable.


<%if CiContainsFirstRecord eq 0%>

   <INPUT TYPE="SUBMIT" VALUE="Previous documents">

<%endif%>

Looking at the preceding code, you see that if the current page does not contain the first record (CiContainsFirstRecord eq 0), a submit button with the text string Previous documents is displayed.

The CiContainsLastRecord Variable


The CiContainsLastRecord variable is used in much the same way as the CiContainsFirstRecord variable except that it identifies whether the current page contains the last record of the query results. If the last record is included in the current page, the CiContainsLastRecord variable is set to 1. For example, for the last page of a record set, you would not want to display a navigational button for the next documents because no additional documents exist. The following code sample demonstrates the use of the CiContainsLastRecord variable.


<%if CiContainsLastRecord eq 0%>

   <INPUT TYPE="SUBMIT" VALUE="Next documents">

<%endif%>

Looking at the preceding code, you see that if the current page does not contain the last record (CiContainsLastRecord eq 0), a submit button with the text string Next documents is displayed.

The CiRecordsNextPage Variable


The CiRecordsNextPage variable identifies how many documents are contained on the next result set page. For example, if 17 records were returned from a query and the number of records displayed on the first page was 10 (equivalent to the CiMaxRecordsPerPage variable), the CiRecordsNextPage variable would be equal to 7 (17-10 = 7). The value of the CiRecordsNextPage can be any whole number up to the value of CiMaxRecordsPerPage. The following code segment demonstrates how the CiRecordsNextPage variable can be used in conjunction with a submit button to tell the user how many documents are contained within the next results page.


<%if CiRecordsNextPage GT 0%>

   <FORM ACTION="/scripts/myscript.idq" METHOD="GET">

   <INPUT TYPE="SUBMIT"

      VALUE="Next <%CiRecordsNextPage%> documents">

   </FORM>

The CiMaxRecordsPerPage Variable


The CiMaxRecordsPerPage variable is used in the .idq file to identify how the result set is split into pages containing an equal number of records (with the exception of the last page, which contains the remaining records of the result set). The most common use of the CiMaxRecordsPerPage variable for formatting output is to identify navigational buttons on the returned pages that allow the user to go to the previous or next page. The CiMaxRecordsPerPage variable can be used in conjunction with other variables such as CiContainsFirstRecord and CiContainsLastRecord as the following code segment demonstrates.


<%if CiContainsFirstRecord eq 0%>

   <TD ALIGN=LEFT>

   <FORM ACTION="/scripts/myscript.idq" METHOD="GET">

   <INPUT TYPE="HIDDEN"

      NAME="CiRestriction" VALUE="<%CiRestriction%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsPerPage" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="SUBMIT"

      VALUE="Previous <%CiMaxRecordsPerPage%> documents">

   </FORM>

   </TD>

<%endif%>

<%if CiContainsLastRecord eq 0%>

   <TD ALIGN=RIGHT>

   <FORM ACTION="/scripts/myscript.idq" METHOD="GET">

   <INPUT TYPE="HIDDEN"

      NAME="CiRestriction" VALUE="<%CiRestriction%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsPerPage" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="SUBMIT"

      VALUE="Next <%CiRecordsNextPage%> documents">

   </FORM>

   </TD>

<%endif%>


An HTML document can consist of multiple forms. In the preceding sample code segment, each of the submit buttons (Next X documents and Previous X documents) is part of a form. Because only those HTML object values contained within a form are passed to the ACTION program, each object that will be used in the ACTION program must be referenced within each form.

The preceding sample code segment also demonstrates how HTML HIDDEN objects are used to pass variables to the ACTION program.

The CiCurrentPageNumber and CiTotalNumberPages Variables


The CiCurrentPageNumber and CiTotalNumberPages variables are used to identify the current page number in the result set and the total number of pages in the result set, respectively. The following sample code segment demonstrates the use of these two variables.


<%if CiTotalNumberPages GT 0%>

   <P>

   <I>Page <%CiCurrentPageNumber%> of <%CiTotalNumberPages%></I>

<%endif%>

Index Server Sample Query Form .htx File


Included with the Microsoft Index Server installation is the sample query form that, in addition to using to test your Index Server installation, you used in other chapters of this book to test queries. In this section, look closely at the contents of the sample query form's associated .htx file queryhit.htx, and analyze each of the sections contained therein.

Document Header Information


All HTML documents contain a minimal set of HTML tags that identify document header information. All HTML documents should include a title, and the queryhit.htx file is no exception. The file begins with the following code segment:


<HTML>

<!--

    <%CiTemplate%>

    This is the formatting page for query results.  This file defines

    how the result page header, rows, and footer will appear.

-->

<HEAD>

    <!-- The title lists the # of documents -->

    <%if CiMatchedRecordCount eq 0%>

        <TITLE><%CiRestriction%> -

           no documents matched.</TITLE>

    <%else%>

        <TITLE><%CiRestriction%> -

           documents <%CiFirstRecordNumber%> to <%CiLastRecordNumber%></TITLE>

    <%endif%>

</HEAD>

As you can see, the title of the document is based on the query restriction and the document range (page) currently being displayed. In the case of a query where no records were returned (CiMatchedRecordCount eq 0), the title would consist of the query restriction (<%CiRestriction%>) and the text string no documents matched. Using the sample query form, execute a query with the query restriction set to CiBookmarkSkipCount that will look for all documents that contain the word CiBookmarkSkipCount. Figure 8.1 displays the resulting page.

Figure 8.1. Sample query results displaying documents containing CiBookmarkSkipCount.

Because the CiMatchedRecordCount does not equal zero, the following code segment is executed and produces the title string CiBookmarkSkipCount–documents 1 to 3–Microsoft Internet Explorer.


<TITLE><%CiRestriction%> -

documents <%CiFirstRecordNumber%> to <%CiLastRecordNumber%></TITLE>


All document titles are displayed in Microsoft Internet Explorer with the trailing test string Microsoft Internet Explorer.


Pre-detail Information


The next segment of code for the queryhit.htx file sets the results page's text and background attributes, displays some header information, and identifies the number of documents found that match the query restriction.


<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#000066"

      VLINK="#808080" ALINK="#FF0000" TOPMARGIN=0>

<TABLE>

   <TR>

      <TD><IMG SRC ="/samples/search/64x_book.jpg" ALIGN=Middle></TD>

      <TD VALIGN=MIDDLE><H1>Index Server</H1><br>

      <center><h2>Search Results</h2></center></TD>

   </TR>

</TABLE>

<!-- Print a header that lists the query and the number of hits -->

<H5>

    <%if CiMatchedRecordCount eq 0%>

        No documents matched the query "<%CiRestriction%>".

    <%else%>

        Documents <%CiFirstRecordNumber%> to <%CiLastRecordNumber%> of

        <%if CiMatchedRecordCount eq CiMaxRecordsInResultSet%>

            the best

        <%endif%>

        <%CiMatchedRecordCount%> matching the query "<%CiRestriction%>".

    <%endif%>

</H5>

In the preceding code segment, the CiMaxRecordsInResultSet variable is checked against the CiMatchedRecordCount variable to determine whether additional document matches exist but were not returned. If this is the case, the text string the best is added to the text string that identifies result set information so that the user knows that the result set contains only the best CiMaxRecordsInResultSet documents.

Top-of-Form Navigational Buttons


The next segment of code in the queryhit.htx file determines the navigational buttons displayed above the records on the current page.


<!--

    This table has a link to a new query page, a previous button, and

    a next page button.  The buttons are only displayed when appropriate.

-->

<TABLE WIDTH=80%>

<!-- Query.htm set HTMLQueryForm as the name of the page to return to

     for a new query.-->

<TD> <A HREF="<%HTMLQueryForm%>">New query</A> </TD>

<!-- Define a "previous" button if this isn't the first page -->

<%if CiContainsFirstRecord eq 0%>

   <TD ALIGN=LEFT>

   <FORM ACTION="/scripts/samples/search/queryhit.idq" METHOD="GET">

   <INPUT TYPE="HIDDEN"

      NAME="CiBookMark" VALUE="<%CiBookMark%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiBookmarkSkipCount" VALUE="-<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsInResultSet"

     VALUE="<%EscapeRAW CiMaxRecordsInResultSet%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiRestriction" VALUE="<%CiRestriction%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsPerPage" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiScope" VALUE="<%CiScope%>" >

   <INPUT TYPE="HIDDEN"

      NAME="TemplateName" VALUE="<%TemplateName%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiSort" VALUE="<%CiSort%>" >

   <INPUT TYPE="HIDDEN"

      NAME="HTMLQueryForm" VALUE="<%HTMLQueryForm%>" >

   <INPUT TYPE="SUBMIT" VALUE="Previous <%CiMaxRecordsPerPage%> documents">

   </FORM>

   </TD>

<%endif%>

<!-- Define a "next" button if this isn't the last page -->

<%if CiContainsLastRecord eq 0%>

   <TD ALIGN=RIGHT>

   <FORM ACTION="/scripts/samples/search/queryhit.idq" METHOD="GET">

   <INPUT TYPE="HIDDEN"

      NAME="CiBookMark" VALUE="<%CiBookMark%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiBookmarkSkipCount" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsInResultSet"

      VALUE="<%EscapeRAW CiMaxRecordsInResultSet%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiRestriction" VALUE="<%CiRestriction%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsPerPage" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiScope" VALUE="<%CiScope%>" >

   <INPUT TYPE="HIDDEN"

      NAME="TemplateName" VALUE="<%TemplateName%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiSort" VALUE="<%CiSort%>" >

   <INPUT TYPE="HIDDEN"

      NAME="HTMLQueryForm" VALUE="<%HTMLQueryForm%>" >

   <INPUT TYPE="SUBMIT" VALUE="Next <%CiRecordsNextPage%> documents">

   </FORM>

   </TD>

<%endif%>

</TABLE>

<HR>

In the preceding code segment, a simple hypertext link is used to allow the user to execute a new query. This hypertext link uses the <%HTMLQueryForm%> variable, which in effect points to the original .idq file for the sample query form document (queryhit.idq).

The next two <%if%> <%endif%> statements in the preceding code segment test the CiContainsFirstRecord and CiContainsLastRecord variables to determine whether navigational buttons should be generated. Note that the CiBookmark, CiBookmarkSkipCount, CiMaxRecordsInResultSet, CiRestriction, CiMaxRecordsPerPage, CiScope, TemplateName, CiSort and HTMLQueryForm variables are all passed to the ACTION program as hidden variables.

Detail Section Information


The next segment of code from the queryhit.htx file is the detail section in which the portion of the .htx file against which the parameters for each document on the current page are processed. Essentially, the <%begindetail%> <%enddetail%> section is like the foreach and while loops, which are common to most programming languages.


<!-- The begindetail/enddetail section describes how each row of output

     is be formatted.  The sample below prints:

     - record number

     - document title (if one exists) or virtual path of the file

     - the abstract for the file

     - the url for the file

     - the file's size and last write time

     - an HREF to the file for the hit highlighter.

       The parameters the hit highlighter include the CiQueryFile and

       CiTemplateFile. The CiQueryFile is not really needed as long as

       you don't have any custom properties. However, if you add custom

       properties, make sure the .idq file you use for queries is same

       as the one specified for CiQueryFile. The CiTemplateFile is used

       by webhits to format the output text.

     - rank of the document

-->

<dl>

<%begindetail%>

   <p>

   <dt>

   <%CiCurrentRecordNumber%>.

   <%if DocTitle isempty%>

      <b><a href="<%EscapeURL vpath%>"><%filename%></a></b>

   <%else%>

      <b><a href="<%EscapeURL vpath%>"><%DocTitle%></a></b>

   <%endif%>

   <dd>

   <b><i>Abstract:  </i></b><%characterization%>

   <br>

   <cite>

   <a href="<%EscapeURL vpath%>">http://<%server_name%><%vpath%></a>

   <font size=-1> -

   <%if size eq ""%>

      (size and time unknown)

   <%else%>

      size <%size%> bytes - <%write%> GMT

   <%endif%>

   </font>

   <br>

   <a href="http://<%server_name%>/scripts/samples/search/webhits.exe<%escapeURL vpath%>?CiRestriction=<%escapeURL CiRestriction%>&CiTemplateFile=/scripts/samples/search/queryhit.htw&CiQueryFile=/scripts/samples/search/queryhit.idq&CiUserParam3=<%escapeURL HTMLQueryForm%>">

   <b>Highlight Hits</b></a><br>

   Rank: <%rank%><br>

   </cite>

<%enddetail%>

You can use any valid variable within the detail section. Those variables shown in the preceding example are probably the most common variables used in most query results forms. However, remember that Index Server also supports inline highlighting (known as webhits) of matching strings. You can implement this feature via the webhits.exe program as demonstrated in the last portion of the preceding detail section.

Bottom-of-Form Navigational Buttons


To ease the transition from one results page to another, navigational buttons are placed at both the top and bottom of each page. The code for the navigational buttons at the bottom of the page is exactly the same as the code for those at the top, except that <%if%> <%endif%> tags are used to determine whether or not to display a horizontal rule (<HR>) before the navigational buttons.


</dl>

<P>

<!-- Only display a line if there were any hits that matched the query -->

<%if CiMatchedRecordCount ne 0%>

    <HR>

<%endif%>

<TABLE WIDTH=80%>

<!-- Query.htm set HTMLQueryForm as the name of the page to return to

     for a new query.-->

<TD> <A HREF="<%HTMLQueryForm%>">New query</A> </TD>

<!-- Define a "previous" button if this isn't the first page -->

<%if CiContainsFirstRecord eq 0%>

   <TD ALIGN=LEFT>

   <FORM ACTION="/scripts/samples/search/queryhit.idq" METHOD="GET">

   <INPUT TYPE="HIDDEN"

      NAME="CiBookMark" VALUE="<%CiBookMark%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiBookmarkSkipCount" VALUE="-<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsInResultSet"

     VALUE="<%EscapeRAW CiMaxRecordsInResultSet%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiRestriction" VALUE="<%CiRestriction%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsPerPage" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiScope" VALUE="<%CiScope%>" >

   <INPUT TYPE="HIDDEN"

      NAME="TemplateName" VALUE="<%TemplateName%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiSort" VALUE="<%CiSort%>" >

   <INPUT TYPE="HIDDEN"

      NAME="HTMLQueryForm" VALUE="<%HTMLQueryForm%>" >

   <INPUT TYPE="SUBMIT" VALUE="Previous <%CiMaxRecordsPerPage%> documents">

   </FORM>

   </TD>

<%endif%>

<!-- Define a "next" button if this isn't the last page -->

<%if CiContainsLastRecord eq 0%>

   <TD ALIGN=RIGHT>

   <FORM ACTION="/scripts/samples/search/queryhit.idq" METHOD="GET">

   <INPUT TYPE="HIDDEN"

      NAME="CiBookMark" VALUE="<%CiBookMark%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiBookmarkSkipCount" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsInResultSet"

      VALUE="<%EscapeRAW CiMaxRecordsInResultSet%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiRestriction" VALUE="<%CiRestriction%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiMaxRecordsPerPage" VALUE="<%EscapeRAW CiMaxRecordsPerPage%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiScope" VALUE="<%CiScope%>" >

   <INPUT TYPE="HIDDEN"

      NAME="TemplateName" VALUE="<%TemplateName%>" >

   <INPUT TYPE="HIDDEN"

      NAME="CiSort" VALUE="<%CiSort%>" >

   <INPUT TYPE="HIDDEN"

      NAME="HTMLQueryForm" VALUE="<%HTMLQueryForm%>" >

   <INPUT TYPE="SUBMIT" VALUE="Next <%CiRecordsNextPage%> documents">

   </FORM>

   </TD>

<%endif%>

</TABLE>


In the event that no documents are found to match the query, the bottom-of-form navigational buttons can be eliminated. You can accomplish this by simply placing the code that generated those navigational buttons within a test statement as follows:

<%if CiMatchedRecordCount GT 0%>

  generate buttons

<%endif%>


Additional Query Status Information


The final segment of code within the queryhit.htx file simply checks the status of the query and displays appropriate information based on the value of specified variables. A standard Page X of Y text string is generated for all results pages that include results documents.


<P><BR>

<!--

     If the index is out of date (for example, if it's still being created

     or updated after changes to files in an indexed directory) let the

     user know.

-->

<%if CiOutOfDate ne 0%>

    <P>

    <I><B>The index is out of date.</B></I><BR>

<%endif%>

<!--

    If the query was not executed because it needed to enumerate to

    resolve the query instead of using the index, but CiForceUseCi

    was TRUE, let the user know

-->

<%if CiQueryIncomplete ne 0%>

    <P>

    <I><B>The query is too expensive to complete.</B></I><BR>

<%endif%>

<!--

    If the query took too long to execute (for example, if too much work

    was required to resolve the query), let the user know

-->

<%if CiQueryTimedOut ne 0%>

    <P>

    <I><B>The query took too long to complete.</B></I><BR>

<%endif%>

<!-- Output a page number and count of pages -->

<%if CiTotalNumberPages gt 0%>

    <P>

    Page <%CiCurrentPageNumber%> of <%CiTotalNumberPages%>

    <P>

<%endif%>

</HTML>

Summary


Hypertext extension files are the key component for formatting query result set pages. Through the use of the many variables available in .htx files, query authors have great flexibility in determining how results pages will be displayed and navigated by the end-user. By including access to features such as document abstracts and inline highlighting of matched words, query authors can generate .htx files that produce results pages that are easy to understand.

Previous Page Page Top TOC Next Page