Configure the Search Page - Enterprise Java Content management system - Hippo CMS

Configure the Search Page

Previous Step

Configure the Navigation Menu

The navigation menu and the pages it links to are now functional and conform to the web design. 

Take a Look at the Web Design

Open the web design in your browser, type something (anything) in the Search textbox in the top right and press Enter. You'll see the design for the search results page.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/build-a-website/developer-trail-10.0/sprint-1/search/search-web-design.png

Note that the main content area contains two columns:

  • Left (main) column: search results
  • Right column: search filter

Remember that both the search filter and the two column main content area are out of scope in this sprint, so concentrate on the search results in the left column.

Take a Look at the Out-of-the-Box Search Results Page

Remember that you added the "Search" out-of-the-box feature to your project when you set it up. This "Search" feature includes a working search results page that is actually active in your web site right now. It's just not connected to the search box where you type in your query yet. But you can access it by entering its URL in your browser together with a query request parameter.

Enter the following URL in your browser:  http://localhost:8080/site/search?query=news.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/build-a-website/developer-trail-10.0/sprint-1/search/search-unstyled.png

You will see some search results in the main content area but once again the styling is missing completely.

Make the Search Box Functional

Start by giving site visitors a way to actually enter a search query. The web design includes a search box in the page header. You already integrated this in your base page configuration but currently it's not linked to the search results page.

Open the file repository-data/webfiles/src/main/resources/site/freemarker/gogreen/base-layout.ftl found in your project.

Locate the element  <div class="searchbox"> in base-layout.ftl and the <form> element inside it. Note that the form's  action attribute currently contains a static URL "search.html". That's because you copied the HTML markup from the web design.

Replace the value of the < form> element's action attribute with " <@hst.link siteMapItemRefId="search" />". It should now look like this:

              <div class="searchbox">
                <form action="<@hst.link siteMapItemRefId="search" />" method="get">
                  <input type="text" class="searchbox-inputtext" id="searchbox-inputtext" name="query"
                    placeholder="Search" /> <label class="searchbox-icon" for="searchbox-inputtext"></label> <input
                    type="submit" class="searchbox-submit" value="Search" />
                </form>
              </div>

The use of the <@hst.link> tag ensures that the action URL is resolved in the current context.

Entering a search query in the search box (on any page) and clicking the "Search" button now results in the search results page for that query being displayed. It still doesn't look like the web design though.

Apply the Web Design the the Search Results Template

Open the file search.html found in the web design. Here you'll find the HTML markup for the search results.

Locate the element  <div class="body-wrapper"> in search.html.

Open the file repository-data/webfiles/src/main/resources/site/freemarker/gogreen/search-main.ftl found in your project. This is the Freemarker template for the search results.

Note that this template includes the pagination.ftl template like you have seen before in the news overview template:

<#if cparam.showPagination??>
  <#include "../include/pagination.ftl">
</#if>

Apply the HTML markup for the search results found in search.html to the Freemarker code in search-main.ftl. Note that you already applied the web design to the external pagination template that is included.

Some useful hints:

  • The search query string is available through the query object.
  • The search results are available through the pageable object and its items attribute.
  • The pageable object provides information about the number of results through its attributes total, startOffset and endOffset.

You should end up with something similar to this:

<#include "../include/imports.ftl">
<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">
        <#if pageable??>
          <#if pageable.total == 0>
            <h4>No results for '${query?html}'</h4>
          <#else>
            <h4>Displaying  ${pageable.startOffset +1 } to ${pageable.endOffset} of ${pageable.total} results for '${query?html}'</h4>
            <div id="search-results">
            <#list pageable.items as item>
              <@hst.link var="link" hippobean=item />
                <div class="blog-post">
                  <div class="blog-post-type">
                    <i class="icon-shop"> </i>
                  </div>
                  <div class="blog-span">
                    <h2>
                      <a href="${link}">${item.title?html}</a>
                    </h2>
                    <div class="blog-post-body">
                      <p>${item.introduction?html}</p>
                    </div>
                    <div class="blog-post-details">
                      <div class="blog-post-details-item blog-post-details-item-right">
                        <a href="${link}"> Read more<i
                          class="fa fa-chevron-right"></i>
                        </a>
                      </div>
                    </div>
                  </div>
                </div>
            </#list>
          </div>
        <#if cparam.showPagination>
          <#include "../include/pagination.ftl">
        </#if>
      </#if>
    <#else>
      <h3>Please fill in a search term.</h3>
    </#if>
      <div class="col-md-3 col-sm-3">
      </div>
    </div>
  </div>
</div>

Open the site in your web browser: http://localhost:8080/site/.

Enter a search query (e.g. 'news') in the search box and press Enter. You will get a search results page for your query that conforms to the web design.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/build-a-website/developer-trail-10.0/sprint-1/search/search-final-result.png

Next Step

Add Related News

Full Source Code

base-layout.ftl

<!doctype html>
<#include "../include/imports.ftl">
<html class="no-js" lang="en">
<head>
<title>Hippo Go Green - Home</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" href="<@hst.webfile path="/css/bootstrap.css"/>">
<link rel="stylesheet" href="<@hst.webfile path="/css/font-awesome.css"/>">

<link href='<@hst.webfile path="/css/style.css"/>' rel='stylesheet' type='text/css'>
<link href='<@hst.webfile path="/css/responsive.css"/>' rel='stylesheet' type='text/css'>

<!-- Fonts -->
<link href="<@hst.webfile path="/fonts/open-sans.css"/>" rel='stylesheet' type='text/css'>
<link href="<@hst.webfile path="/fonts/raleway.css"/>" rel='stylesheet' type='text/css'>

<link rel="stylesheet" media="screen" type="text/css" href="<@hst.webfile path="/css/hippo-green.css"/>" />

<link rel="icon" href="<@hst.webfile path="/images/favicon.ico"/>" type="image/x-icon" />
<link rel="shortcut icon" href="<@hst.webfile path="/images/favicon.ico"/>" type="image/x-icon" />

<link rel="apple-touch-icon" href="<@hst.webfile path="/images/apple-touch-icon.png"/>" />

<link rel="alternate" type="application/rss+xml" title="Hippo Go Green RSS" href="rss" />

<@hst.headContributions categoryIncludes="htmlHead" xhtml=true/>

</head>
<body class="bgpattern-neutral">

  <div id="wrapper" class="boxed">
    <div class="top_wrapper">

      <div class="top-bar">
        <div class="container">
          <div class="row">
            <!-- lang navigation -->
            <div class="col-sm-7 langnav">
              <nav>
                <ul class="" id="language">

                  <li class="active"><i class="fa fa-ellipsis-h"></i> <span>United States</span>
                    <ul>
                      <li><a href="fr.html">France</a></li>
                    </ul></li>

                </ul>
              </nav>
            </div>
            <div class="col-sm-5" id="top-search">

              <div class="searchbox">
                <form action="<@hst.link siteMapItemRefId="search" />" method="get">
                  <input type="text" class="searchbox-inputtext" id="searchbox-inputtext" name="query"
                    placeholder="Search" /> <label class="searchbox-icon" for="searchbox-inputtext"></label> <input
                    type="submit" class="searchbox-submit" value="Search" />
                </form>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- Header -->
      <header id="header">
        <div class="container">

          <div class="row header">

            <!-- Logo -->
            <div class="col-xs-2 logo">
              <a href="index.html"><img src="<@hst.webfile path="/images/gogreenlogo2.png"/>" alt="" height="107" /></a>
            </div>
            <!-- //Logo// -->

            <!-- Main navigation -->
            <!-- Navigation File -->
            <div class="col-md-12">

              <!-- Mobile Button Menu -->
              <div class="mobile-menu-button">
                <i class="fa fa-list-ul"></i>
              </div>
              <!-- //Mobile Button Menu// -->

              <@hst.include ref="menu"/>

              <!-- Mobile Nav. Container -->
              <ul class="mobile-nav">
                <li class="responsive-searchbox">
                  <!-- Responsive Nave -->
                  <form action="index.html#" method="get">
                    <input type="text" class="searchbox-inputtext" id="searchbox-inputtext-mobile" name="s" />
                    <button class="icon-search"></button>
                  </form> <!-- //Responsive Nave// -->
                </li>
              </ul>
              <!-- //Mobile Nav. Container// -->
            </div>
            <!-- //Main navigation// -->
          </div>
        </div>
      </header>
      <!-- //Header// -->
    </div>

    <!-- body / main -->

    <div class="content-wrapper">
      <div class="top-title-wrapper">
        <div class="container">
          <div class="row">
            <div class="col-md-12 col-sm-12">
              <div class="page-info">
              </div>
            </div>
          </div>
        </div>
      </div>

      <@hst.include ref="main"/>

    </div>

    <!-- footer -->

    <@hst.include ref="footer"/>
    
  </div>
  
  <script src="<@hst.webfile path="/js/jquery-2.1.0.min.js"/>" type="text/javascript"></script>
  <script src="<@hst.webfile path="/js/bootstrap.min.js"/>" type="text/javascript"></script>
  <script src="<@hst.webfile path="/js/kanzi-menu.js"/>" type="text/javascript"></script>

  <@hst.headContributions categoryIncludes="htmlBodyEnd" xhtml=true/>

</body>
</html>

search-main.ftl

<#include "../include/imports.ftl">
<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">
        <#if pageable??>
          <#if pageable.total == 0>
            <h4>No results for '${query?html}'</h4>
          <#else>
            <h4>Displaying  ${pageable.startOffset +1 } to ${pageable.endOffset} of ${pageable.total} results for '${query?html}'</h4>
            <div id="search-results">
            <#list pageable.items as item>
              <@hst.link var="link" hippobean=item />
                <div class="blog-post">
                  <div class="blog-post-type">
                    <i class="icon-shop"> </i>
                  </div>
                  <div class="blog-span">
                    <h2>
                      <a href="${link}">${item.title?html}</a>
                    </h2>
                    <div class="blog-post-body">
                      <p>${item.introduction?html}</p>
                    </div>
                    <div class="blog-post-details">
                      <div class="blog-post-details-item blog-post-details-item-right">
                        <a href="${link}"> Read more<i
                          class="fa fa-chevron-right"></i>
                        </a>
                      </div>
                    </div>
                  </div>
                </div>
            </#list>
          </div>
        <#if cparam.showPagination>
          <#include "../include/pagination.ftl">
        </#if>
      </#if>
    <#else>
      <h3>Please fill in a search term.</h3>
    </#if>
      <div class="col-md-3 col-sm-3">
      </div>
    </div>
  </div>
</div>

See also...

Configure the Search Page

Previous Step

Configure the Navigation Menu

The navigation menu and the pages it links to are now functional and conform to the web design. 

Take a Look at the Web Design

Open the web design in your browser, type something (anything) in the Search textbox in the top right and press Enter. You'll see the design for the search results page.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/build-a-website/developer-trail-10.0/sprint-1/search/search-web-design.png

Note that the main content area contains two columns:

  • Left (main) column: search results
  • Right column: search filter

Remember that both the search filter and the two column main content area are out of scope in this sprint, so concentrate on the search results in the left column.

Take a Look at the Out-of-the-Box Search Results Page

Remember that you added the "Search" out-of-the-box feature to your project when you set it up. This "Search" feature includes a working search results page that is actually active in your web site right now. It's just not connected to the search box where you type in your query yet. But you can access it by entering its URL in your browser together with a query request parameter.

Enter the following URL in your browser:  http://localhost:8080/site/search?query=news.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/build-a-website/developer-trail-10.0/sprint-1/search/search-unstyled.png

You will see some search results in the main content area but once again the styling is missing completely.

Make the Search Box Functional

Start by giving site visitors a way to actually enter a search query. The web design includes a search box in the page header. You already integrated this in your base page configuration but currently it's not linked to the search results page.

Open the file repository-data/webfiles/src/main/resources/site/freemarker/gogreen/base-layout.ftl found in your project.

Locate the element  <div class="searchbox"> in base-layout.ftl and the <form> element inside it. Note that the form's  action attribute currently contains a static URL "search.html". That's because you copied the HTML markup from the web design.

Replace the value of the < form> element's action attribute with " <@hst.link siteMapItemRefId="search" />". It should now look like this:

              <div class="searchbox">
                <form action="<@hst.link siteMapItemRefId="search" />" method="get">
                  <input type="text" class="searchbox-inputtext" id="searchbox-inputtext" name="query"
                    placeholder="Search" /> <label class="searchbox-icon" for="searchbox-inputtext"></label> <input
                    type="submit" class="searchbox-submit" value="Search" />
                </form>
              </div>

The use of the <@hst.link> tag ensures that the action URL is resolved in the current context.

Entering a search query in the search box (on any page) and clicking the "Search" button now results in the search results page for that query being displayed. It still doesn't look like the web design though.

Apply the Web Design the the Search Results Template

Open the file search.html found in the web design. Here you'll find the HTML markup for the search results.

Locate the element  <div class="body-wrapper"> in search.html.

Open the file repository-data/webfiles/src/main/resources/site/freemarker/gogreen/search-main.ftl found in your project. This is the Freemarker template for the search results.

Note that this template includes the pagination.ftl template like you have seen before in the news overview template:

<#if cparam.showPagination??>
  <#include "../include/pagination.ftl">
</#if>

Apply the HTML markup for the search results found in search.html to the Freemarker code in search-main.ftl. Note that you already applied the web design to the external pagination template that is included.

Some useful hints:

  • The search query string is available through the query object.
  • The search results are available through the pageable object and its items attribute.
  • The pageable object provides information about the number of results through its attributes total, startOffset and endOffset.

You should end up with something similar to this:

<#include "../include/imports.ftl">
<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">
        <#if pageable??>
          <#if pageable.total == 0>
            <h4>No results for '${query?html}'</h4>
          <#else>
            <h4>Displaying  ${pageable.startOffset +1 } to ${pageable.endOffset} of ${pageable.total} results for '${query?html}'</h4>
            <div id="search-results">
            <#list pageable.items as item>
              <@hst.link var="link" hippobean=item />
                <div class="blog-post">
                  <div class="blog-post-type">
                    <i class="icon-shop"> </i>
                  </div>
                  <div class="blog-span">
                    <h2>
                      <a href="${link}">${item.title?html}</a>
                    </h2>
                    <div class="blog-post-body">
                      <p>${item.introduction?html}</p>
                    </div>
                    <div class="blog-post-details">
                      <div class="blog-post-details-item blog-post-details-item-right">
                        <a href="${link}"> Read more<i
                          class="fa fa-chevron-right"></i>
                        </a>
                      </div>
                    </div>
                  </div>
                </div>
            </#list>
          </div>
        <#if cparam.showPagination>
          <#include "../include/pagination.ftl">
        </#if>
      </#if>
    <#else>
      <h3>Please fill in a search term.</h3>
    </#if>
      <div class="col-md-3 col-sm-3">
      </div>
    </div>
  </div>
</div>

Open the site in your web browser: http://localhost:8080/site/.

Enter a search query (e.g. 'news') in the search box and press Enter. You will get a search results page for your query that conforms to the web design.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/build-a-website/developer-trail-10.0/sprint-1/search/search-final-result.png

Next Step

Add Related News

Full Source Code

base-layout.ftl

<!doctype html>
<#include "../include/imports.ftl">
<html class="no-js" lang="en">
<head>
<title>Hippo Go Green - Home</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" href="<@hst.webfile path="/css/bootstrap.css"/>">
<link rel="stylesheet" href="<@hst.webfile path="/css/font-awesome.css"/>">

<link href='<@hst.webfile path="/css/style.css"/>' rel='stylesheet' type='text/css'>
<link href='<@hst.webfile path="/css/responsive.css"/>' rel='stylesheet' type='text/css'>

<!-- Fonts -->
<link href="<@hst.webfile path="/fonts/open-sans.css"/>" rel='stylesheet' type='text/css'>
<link href="<@hst.webfile path="/fonts/raleway.css"/>" rel='stylesheet' type='text/css'>

<link rel="stylesheet" media="screen" type="text/css" href="<@hst.webfile path="/css/hippo-green.css"/>" />

<link rel="icon" href="<@hst.webfile path="/images/favicon.ico"/>" type="image/x-icon" />
<link rel="shortcut icon" href="<@hst.webfile path="/images/favicon.ico"/>" type="image/x-icon" />

<link rel="apple-touch-icon" href="<@hst.webfile path="/images/apple-touch-icon.png"/>" />

<link rel="alternate" type="application/rss+xml" title="Hippo Go Green RSS" href="rss" />

<@hst.headContributions categoryIncludes="htmlHead" xhtml=true/>

</head>
<body class="bgpattern-neutral">

  <div id="wrapper" class="boxed">
    <div class="top_wrapper">

      <div class="top-bar">
        <div class="container">
          <div class="row">
            <!-- lang navigation -->
            <div class="col-sm-7 langnav">
              <nav>
                <ul class="" id="language">

                  <li class="active"><i class="fa fa-ellipsis-h"></i> <span>United States</span>
                    <ul>
                      <li><a href="fr.html">France</a></li>
                    </ul></li>

                </ul>
              </nav>
            </div>
            <div class="col-sm-5" id="top-search">

              <div class="searchbox">
                <form action="<@hst.link siteMapItemRefId="search" />" method="get">
                  <input type="text" class="searchbox-inputtext" id="searchbox-inputtext" name="query"
                    placeholder="Search" /> <label class="searchbox-icon" for="searchbox-inputtext"></label> <input
                    type="submit" class="searchbox-submit" value="Search" />
                </form>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- Header -->
      <header id="header">
        <div class="container">

          <div class="row header">

            <!-- Logo -->
            <div class="col-xs-2 logo">
              <a href="index.html"><img src="<@hst.webfile path="/images/gogreenlogo2.png"/>" alt="" height="107" /></a>
            </div>
            <!-- //Logo// -->

            <!-- Main navigation -->
            <!-- Navigation File -->
            <div class="col-md-12">

              <!-- Mobile Button Menu -->
              <div class="mobile-menu-button">
                <i class="fa fa-list-ul"></i>
              </div>
              <!-- //Mobile Button Menu// -->

              <@hst.include ref="menu"/>

              <!-- Mobile Nav. Container -->
              <ul class="mobile-nav">
                <li class="responsive-searchbox">
                  <!-- Responsive Nave -->
                  <form action="index.html#" method="get">
                    <input type="text" class="searchbox-inputtext" id="searchbox-inputtext-mobile" name="s" />
                    <button class="icon-search"></button>
                  </form> <!-- //Responsive Nave// -->
                </li>
              </ul>
              <!-- //Mobile Nav. Container// -->
            </div>
            <!-- //Main navigation// -->
          </div>
        </div>
      </header>
      <!-- //Header// -->
    </div>

    <!-- body / main -->

    <div class="content-wrapper">
      <div class="top-title-wrapper">
        <div class="container">
          <div class="row">
            <div class="col-md-12 col-sm-12">
              <div class="page-info">
              </div>
            </div>
          </div>
        </div>
      </div>

      <@hst.include ref="main"/>

    </div>

    <!-- footer -->

    <@hst.include ref="footer"/>
    
  </div>
  
  <script src="<@hst.webfile path="/js/jquery-2.1.0.min.js"/>" type="text/javascript"></script>
  <script src="<@hst.webfile path="/js/bootstrap.min.js"/>" type="text/javascript"></script>
  <script src="<@hst.webfile path="/js/kanzi-menu.js"/>" type="text/javascript"></script>

  <@hst.headContributions categoryIncludes="htmlBodyEnd" xhtml=true/>

</body>
</html>

search-main.ftl

<#include "../include/imports.ftl">
<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">
        <#if pageable??>
          <#if pageable.total == 0>
            <h4>No results for '${query?html}'</h4>
          <#else>
            <h4>Displaying  ${pageable.startOffset +1 } to ${pageable.endOffset} of ${pageable.total} results for '${query?html}'</h4>
            <div id="search-results">
            <#list pageable.items as item>
              <@hst.link var="link" hippobean=item />
                <div class="blog-post">
                  <div class="blog-post-type">
                    <i class="icon-shop"> </i>
                  </div>
                  <div class="blog-span">
                    <h2>
                      <a href="${link}">${item.title?html}</a>
                    </h2>
                    <div class="blog-post-body">
                      <p>${item.introduction?html}</p>
                    </div>
                    <div class="blog-post-details">
                      <div class="blog-post-details-item blog-post-details-item-right">
                        <a href="${link}"> Read more<i
                          class="fa fa-chevron-right"></i>
                        </a>
                      </div>
                    </div>
                  </div>
                </div>
            </#list>
          </div>
        <#if cparam.showPagination>
          <#include "../include/pagination.ftl">
        </#if>
      </#if>
    <#else>
      <h3>Please fill in a search term.</h3>
    </#if>
      <div class="col-md-3 col-sm-3">
      </div>
    </div>
  </div>
</div>

See also...