Sitecore Cookbook for Developers
上QQ阅读APP看书,第一时间看更新

Achieving asynchronous operations using a custom device

Sitecore allows building site-supporting multiple devices so that we can have different renderings for different devices, that is, desktop, mobile, print, crawler, and so on. You can also associate a fallback device with each device. If the context item does not contain layout details for the context device, then the layout engine applies the layout details for the fallback device. Learn about setting up the device layout from https://goo.gl/JYVSWJ.

Apart from these uses of devices, in this recipe, we will consider a business requirement to list products on the products page. Now clicking on individual products instead of redirecting the user to that product's page, we will asynchronously pull product details using JavaScript and display on the same page to get better user experience and performance of the page. We will achieve this using a custom device.

How to do it…

We will first create a custom device and layout to load only the product content asynchronously:

  1. Create a new Async device under /sitecore/layout/Devices. Set the Query string field value to async=true, as shown in the following image. It means that when requesting any URL having a query string as async=true, Sitecore automatically resolves an async device for this request; otherwise, it will resolve the default device:
    How to do it…
  2. Create an async.cshtml layout in the \Views folder with the following code, which has one async-content placeholder to place content requested through an async device. Register this layout to Sitecore—Async:
    <div id="asynccontent">
      @Html.Sitecore().Placeholder("async-content")
    </div>

    Now we will bind components to the async device and layout.

  3. In the Product template standard values, we already have Breadcrumb, Side Menu, and Title and Body renderings with Main Layout on the Default device. We will add only the Title and Body with the Async layout on the async device, as shown in the following image:
    How to do it…
  4. Now, preview any product page and compare its output after adding the async=true query string. You will find that a regular URL (with the Default device) shows full details with navigation components, while the async URL shows only product details, for example, http://sitecorecookbook/products/phones/iphone-6s and http://sitecorecookbook/products/phones/iphone-6s?async=true.

    Now you can use both these URLs as per your needs. Here, we will create a view rendering to list products on the product category page.

  5. Create a ProductList.cshtml view and write the following code. Register it in Sitecore as a Product List view rendering and map the ItemList model that we created in the previous recipe:
    @model SitecoreCookbook.Models.ItemList
    <script language="javascript">
      function LoadAsync(url) {
        $j = jQuery.noConflict();
        $j.get(url, function (data, status) {
        $j("#productcontent").html(data);  });
      }
    </script>
    <div class="async-list">
      @foreach (var row in Model.Items)
      {
        <a onclick="LoadAsync('@Sitecore.Links.LinkManager.GetItemUrl(row)?async=true')" href="javascript:">
          <div class="row">
            @Html.Sitecore().Field("Title", row, new { DisableWebEditing = true })
          </div>
        </a>
      }
    </div>
    <div id="productcontent"></div>
  6. Add this view to the Product Category template standard values and preview the product category page. You will find that when clicking on any product in the list, it will fetch product details with an async device request and display the productcontent div element, as shown in the following image. The URL is http://sitecorecookbook/products/phones/.
    How to do it…

How it works…

While working in the Experience Editor, we may find that the content loaded asynchronously is editable or sometimes you may find the content with a ribbon. To disable them, you can change the page mode temporarily for that request using the following code after the device gets resolved. You can do this by customizing the <httpRequestBegin> pipeline, which you will learn in the Customizing pipelines to achieve a custom 404 page recipe in Chapter 4, Leveraging the Sitecore Backend.

Sitecore.Context.Site.SetDisplayMode(Sitecore.Sites.DisplayMode.Normal, Sitecore.Sites.DisplayModeDuration.Temporary);

Note

You learned that we can get a different output of the same page using different devices. Devices get resolved using either a query string or user agent.