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 }