How to build a Google mockup page in Kentico CMS

Sometimes you need to showcase  features of your software that require third-party services to be connected to your program. In our case, for example, we required a nice demo page to showcase our EMS functionality based on the  Google search results page. This article describes one of the ways to achieve this in Kentico CMS. 
I usually don’t recommend using the ASPX development approach to create Kentico functionality, because the Portal engine allows you to do the exact same thing and usually with much less programing involved, giving you an additional set of features which otherwise would have had to have been hand-coded from scratch. In this case, however, I am using a custom ASPX template. Of course I would be able to achieve the same functionality with the Portal engine development model, but it wouldn’t make much sense to create, for example, a Google widget or web part. It’s not like you are going to re-use this functionality over and over again on your website. It’s simply one page for showcasing some built-in functionality that won’t be reused anywhere else. Additionally, this page requires specific CSS styling and other custom references. Also, use of such created web part functionality would include custom styling, which would break the standard Kentico layout . These are some of the reasons I’ve chosen to implement the given functionality as an ASPX page and not as a web part.

At first I created a new ASPX page skeleton as described in our documentation. The most important thing is to specify, for example, the base class TemplatePage for this template (namespace CMS.UIControls). This will allow you to register the template in the CMSSiteManager. Once you do this, you can start creating the content of your template. First of all, I copied over the relevant HTML and CSS code from the official Google search page. The CSS code was copied into a new Kentico stylesheet with the code name GoogleMockup. This allows me to link the stylesheet the following way:

<link href="~/CMSPages/GetCSS.aspx?stylesheetname=GoogleMockup" type="text/css" rel="stylesheet"/>

Then I had to determine which part rendered the search box, so I could replace it with a standard .NET TextBox control. The fact that the HTML code is minified and that the IDs are shortened made this task somewhat difficult. After a closer inspection of the HTML code with FireBug, I figured out which part of the page to replace. In my case, the element to replace was in the gbfwa div element. After replacing the standard code, my HTML portion looked like this:

         class="gbqfwa ">
          <asp:TextBox id="gbqfqwb" CssClass="gbqfqwc gbqfqw" runat="server"></asp:TextBox>

The next thing to do was to replace the search button. To keep the design consistent, I decided to also replace the “I feel lucky” button so that my code looked like this:

          <asp:Button Text="Google Search" ID="gbqfba" CssClass= "gbqfba" runat="server" OnClick="gbqfba_Click" />
      <asp:Button Text="I'm Feeling Lucky" ID="gbqfbb" CssClass= "gbqfba" runat="server" />
The next step was to implement the search results page. I decided to keep everything in one template so I simply created a new .NET panel (pnlResults) containing the HTML of the search results page, which is dynamically shown if the page should display search results. However, the main search page HTML must be hidden if the search results are displayed. So I’ve added another panel encapsulating the search page HTML (pnlSearch). Here is a simple skeleton for that page:

   <head id="Head1" runat="server">
      <link href="~/CMSPages/GetCSS.aspx?stylesheetname=GoogleMockup" type="text/css" rel="stylesheet"/>
      <form id="form1" runat="server" defaultbutton="gbqfba">
            <ajaxToolkit:ToolkitScriptManager ID="manScript" runat="server" EnableViewState="false"
               ScriptMode="Release" />
            <cms:CMSPortalManager ID="manPortal" runat="server" EnableViewState="false" />
<!-- skipped code -->
   <asp:Panel runat="server" ID="pnlSearch">
<!-- skipped code -->
<asp:TextBox id="gbqfqwb" CssClass="gbqfqwc gbqfqw" runat="server"></asp:TextBox>
<!-- skipped code -->
          <asp:Button Text="Google Search" ID="gbqfba" CssClass= "gbqfba" runat="server" OnClick="gbqfba_Click" />
      <asp:Button Text="I'm Feeling Lucky" ID="gbqfbb" CssClass= "gbqfba" runat="server"/>
    <!-- skipped code -->
       <asp:Panel runat="server" ID="pnlResults" Visible="false" CssClass="searchPane">
<!-- skipped code -->
<asp:TextBox ID="gbqfqw" CssClass="gbqfqw" runat="server"></asp:TextBox>
<!-- skipped code -->
<!-- results listing -->
<!-- skipped code -->
To switch between the two views (results and search), I simply used a URL query string. If the user is in the search view and if he searches for any string, this string will be passed as a query string in the URL. So, if searching for “Kentico”, the URL will look like this:

<base URL>?search=Kentico

The same page would be loaded, but now it would detect the query string containing a search keyword and a search value. Now the search panel would be hidden on the page load event and the results panel would be displayed. The search value is retrieved from the query string and used to modify the search results. I’ve hard-coded the search results into the template for simplicity. An alternative approach would be to dynamically change the results and request the search results from Google, however this is not necessary in our case. To display our search keyword in the search results, I’ve simply used a .NET variable in the markup (<%= SearchString %>), which is defined in the CodeBehind as a public static string SearchString variable. (In a real-life scenario, please sanitize the input checking for XSS.) Then I implemented the body of the click event of the search button. The implementation is pretty simple; I just redirect the visitor to the same page with the already-mentioned query string and search value from the TextBox attached.

Now we have a dynamically changing page and some realistic-looking search results. Next, we have to use Kentico’s built-in features to personalize the content. We know, that we can use campaigns to personalize someone’s landing page. This scenario can be used when speaking about paid ads, where you enter the target URL, so you can include a custom query string parameter. So one of the search result links will be dynamically generated to point to the landing page and to include a campaign-specific query string. For simplicity, only two query strings are supported. The “SampleCampaign” and the “Google” query string. The Google query string is used if such a campaign was created in the system. If not, the default SampleCampaign would be used. The URL in the markup is replaced the same way as the search term in the results—with a .NET variable (<%= AddURL %>). To create this URL, the campaign parameter needs to be retrieved with our settings API. Additionally, the application base URL is taken as the target URL. The second dynamic URL (<%= StandardURL %>) is a standard search result URL. Since the results aren’t directly generated by Google, I cheated a bit. I logged the external search activity manually on the page load and redirected the visitor afterwards, the same way as with the ad dynamic link.  Additionally, I implemented some cleanup so these activities are deleted (together with the campaign cookie) when this mockup page is loaded without any query parameters. This is basically how this mockup page works. Additionally, you have to configure Kentico to make use of this metadata. Here are some sample macros that may be used in this case to display personalized variants of web parts or widgets:

External search for the string “searchvalue”-based visit:

Filter(Contact.Activities, " ActivityType == \"externalsearch\"  && ActivityValue==\"searchvalue\"").Count > 0

Google campaign related visit:

Cookies.Campaign == “Google”

For additional details please check the attached code files. You can import the template and the stylesheet as a standard Kentico import package.



As always, here is the download link to the export package, ready to be used on your Kentico instance.
Share this article on   LinkedIn

Boris Pocatko

Senior Solution Architect for Kentico


Steve Williams commented on

Hi Boris - this is great and works really well when a customer wants to see how external search phrases can be used to personalise a landing page with targeted content that speaks to the search terms - thanks for putting together !