Here is an example template that could be used to format a Google search results page:
{{>HEADER}}
<body bgcolor=white>
{{>PAGE_HEADING}}{{!The following div must be on the same line}}<div>
{{!The ONE_RESULT section displays a single search item}}
{{#ONE_RESULT}}
{{! Note: there are two SUBITEM_SECTIONs. They both show or hide together}}
{{#SUBITEM_SECTION}}<blockquote>{{/SUBITEM_SECTION}}
<p><a href={{JUMP_TO_URL:html_escape}} target=nw>{{LEAD_LINE}}</a><font size=-1>
{{#SNIPPET1_SECTION}}
<br>{{SNIPPET1}}
{{/SNIPPET1_SECTION}}
{{#SNIPPET2_SECTION}}
<br>{{SNIPPET2}}
{{/SNIPPET2_SECTION}}
{{#DESCRIPTION_SECTION}}
<br><span class=f>Description:</span> {{DESC}}
{{/DESCRIPTION_SECTION}}
{{#CATEGORY_SECTION}}
<br><span class=f>Category:</span> <a href={{CAT_URL:html_escape}} class=f>
{{CATEGORY}}</a>
{{/CATEGORY_SECTION}}
{{#LASTLINE_SECTION}}
<br><font color={{ALT_TEXT_COLOR}}>{{URL}}
{{#KS_SECTION}}} - {{KSIZE}}{{/KS_SECTION}}}
{{#CACHE_SECTION}}} - <a href={{CACHE_URL:html_escape}} class=f>Cached</A>
{{/CACHE_SECTION}}}
{{#SIM_SECTION}}} - <a href={{SIM_PAGES_URL:html_escape}} class=f>Similar pages</A>
{{/SIM_SECTION}}}
{{#STOCK_SECTION}}
- <a href={{STOCK_URL:html_escape}} class=f>Stock quotes: {{STOCK_SYMBOL}}</a>
{{/STOCK_SECTION}}
</font>
{{/LASTLINE_SECTION}}
{{#MORE_SECTION}}
<br>[ <a href={{MORE_URL:html_escape}} class=f>More results from {{MORE_LABEL}}</a> ]
{{/MORE_SECTION}}
</font><br>
{{! Note: there are two SUBITEM_SECTIONs. They both show or hide together}}
{{#SUBITEM_SECTION}}</blockquote>{{/SUBITEM_SECTION}}
{{/ONE_RESULT}}
</div> {{! this /div closes the div at the top of this file}}
{{>PAGE_FOOTING}}
Here is a sample procedure that could populate a dictionary for
expanding that template. The "one procedure" entry point is
fill_search_results_dictionary. The
SetTemplateValues function is a separate entry point for
initializing each top-level template with some standard values.
#include "template.h"
RegisterTemplateFilename(SEARCH_RESULTS_FN, "search_results.tpl");
#include "search_results.tpl.varnames.h" // defines ksr_HEADER, etc.
using google::Template;
using google::TemplateDictionary;
using google::STRIP_WHITESPACE;
// IsEmpty
// A simple utility function
static bool IsEmpty(const string &str) {
return str.empty();
}
// SetTemplateValues
// Use the TemplateDictionary object to set template-wide values that
// may be used in the top-level template and all its sub-sections
// and included templates. The template-wide values are all
// colors from the Palette object
void SetTemplateValues(TemplateDictionary *dictionary, const Palette* colors) {
// better would be to use ksr_LINK_COLOR, etc, assuming those are
// defined in search_results.tpl.varnames.h. But using literal
// text, as here, is legal as well.
dictionary->SetValue("LINK_COLOR", colors->link_color);
dictionary->SetValue("BAR_TEXT_COLOR", colors->bar_text_color);
dictionary->SetValue("TEXT_COLOR", colors->text_color);
dictionary->SetValue("FAINT_COLOR", colors->faint_color);
dictionary->SetValue("IMPORTANT_COLOR", colors->important_color);
dictionary->SetValue("BAR_COLOR", colors->bar_color);
dictionary->SetValue("ALT_TEXT_COLOR", colors->alt_text_color);
dictionary->SetValue("ALINK_COLOR", colors->alink_color);
dictionary->SetValue("VLINK_COLOR", colors->vlink_color);
}
// fill_search_results_dictionary
// Iterates through all the QueryResults contained in the Query object.
// For each one, it sets corresponding template dictionary values
// (or hides sections containing their variables, if appropriate) in
// a sub-dictionary and then adds that dictionary to the parent
void fill_search_results_dictionary(TemplateDictionary *dictionary,
const Query *query) {
dictionary->SetFilename(SEARCH_RESULTS_FN);
// These two functions are defined elsewhere
fill_header_dictionary(dictionary->AddIncludeDictionary(ksr_HEADER));
fill_page_heading_dictionary(dictionary->AddIncludeDictionary(ksr_PAGE_HEADING),
query);
ResultsList *results = query->GetResults();
int resCount = 0;
for (ResultsList::const_iterator iter = results->begin();
iter != results->end();
++iter) {
QueryResult *qr = (*iter);
// Create a new sub-dictionary named "Result Dict " for this entry
++resCount;
TemplateDictionary *result_dictionary =
dictionary->AddSectionDictionary(ksr_ONE_RESULT);
result_dictionary->SetValue(ksr_JUMP_TO_URL, qr->GetUrl());
if (qr->IsSubItem()) {
result_dictionary->ShowSection(ksr_SUBITEM_SECTION);
}
result_dictionary->SetValue(ksr_LEAD_LINE, qr->GetLeadLine());
result_dictionary->SetValueAndShowSection(ksr_SNIPPET1, qr->GetSnippet1(),
ksr_SNIPPET1_SECTION);
result_dictionary->SetValueAndShowSection(ksr_SNIPPET2, qr->GetSnippet2(),
ksr_SNIPPET2_SECTION);
result_dictionary->SetValueAndShowSection(ksr_DESC, qr->GetDescription(),
ksr_DESCRIPTION_SECTION);
result_dictionary->SetValueAndShowSection(ksr_CAT_URL, qr->GetCategoryUrl(),
ksr_CATEGORY_SECTION);
result_dictionary->SetValueAndShowSection("CATEGORY", qr->GetCategoryName(),
"CATEGORY_SECTION");
if (IsEmpty(qr->GetDisplayUrl()) &&
IsEmpty(qr->GetPageSize()) &&
IsEmpty(qr->GetCachedUrl()) &&
IsEmpty(qr->GetSimilarPagesUrl()) &&
(IsEmpty(qr->GetStockUrl()) ||
IsEmpty(qr->GetStockSymbol())) ) {
// there is nothing on the last line, so hide it altogether
} else {
result_dictionary->ShowSection("LASTLINE_SECTION");
result_dictionary->SetValue(ksr_URL, qr->GetDisplayUrl());
result_dictionary->SetValueAndShowSection(ksr_KSIZE, qr->GetPageSize(),
ksr_KS_SECTION);
result_dictionary->SetValueAndShowSection(ksr_CACHE_URL, qr->GetCachedUrl(),
ksr_CACHE_SECTION);
result_dictionary->SetValueAndShowSection(ksr_SIM_PAGES_URL,
qr->GetSimilarPagesUrl(),
ksr_SIM_SECTION);
result_dictionary->SetValueAndShowSection(ksr_STOCK_URL, qr->GetStockUrl(),
ksr_STOCK_SECTION);
result_dictionary->SetValueAndShowSection(ksr_STOCK_SYMBOL,
qr->GetStockSymbol(),
ksr_STOCK_SECTION);
}
result_dictionary->SetValueAndShowSection(ksr_MORE_URL, qr->GetMoreUrl(),
ksr_MORE_SECTION);
result_dictionary->SetValueAndShowSection(ksr_MORE_LABEL, qr->GetMoreLabel(),
ksr_MORE_SECTION);
}
fill_page_footing_dictionary(dictionary->AddIncludeDictionary(ksr_PAGE_FOOTING),
query);
}
void output_page(const Query* query) {
Template* tpl = Template::GetTemplate(SEARCH_RESULTS_FN, STRIP_WHITESPACE);
TemplateDictionary dict("search-results dict");
string output;
fill_search_results_dictionary(&dict, query);
tpl->Expand(&output, &dict);
// output now holds the expanded template
}