Welcome to the navigation

Dolore quis incididunt fugiat occaecat laboris exercitation eiusmod magna ullamco sint pariatur, ut in labore nulla aute ex in veniam, in ut consequat, et excepteur. Et ut elit, dolore quis magna do tempor veniam, in consectetur minim est pariatur, aliqua, esse amet, sunt laboris ex occaecat consequat, sit duis velit

Yeah, this will be replaced... But please enjoy the search!

Separate Smartphones, Tablets and other Devices using Episerver DisplayChannel and DeviceDetector.NET

Ever wanted to be able to separate mobile devices into separate channels independent of the screen resolution (without using media queries)? Here's how I solve it using DeviceDetector.NET

According to this page "EPiServer.Web.DisplayChannel is a base class that is used for creating display channels, to detect viewport settings, and select templates to render content for a targeted device format". 

When combining DisplayChannels with DeviceDetector.NET this become's really powerful. 

Installation

Begin by installing the DeviceDetector Nuget package

Install-Package DeviceDetector.NET

Add the DeviceDetectorRegexesDirectory path to web.config, the folder with the regexes can be found in the DeviceDetector Packages folder installed with the NuGet package

<add key="DeviceDetectorRegexesDirectory" value="C:\\DeviceDetector.NET.3.11.4\\"/> 

Implement your DisplayChannel(s) 

Some words about DeviceDetector

The identification of the devices is done by registering the regex setting and feeding the DeviceDetector with the current UserAgent. The actual magic is done when calling the Parse() method.

These are the currently supported device names

  • desktop
  • smartphone
  • tablet
  • feature phone
  • console
  • tv
  • car browser
  • smart display
  • camera
  • portable media player
  • phablet

Creating a SmartPhone DisplayChannel

public class SmartphoneDisplayChannel : DisplayChannel
{
    public override bool IsActive(HttpContextBase context)
    {
        DeviceDetectorSettings.RegexesDirectory = ConfigurationManager.AppSettings["DeviceDetectorRegexesDirectory"];
        var dd = new DeviceDetector(context.Request.UserAgent);
        dd.DiscardBotInformation();
        dd.SkipBotDetection();
        dd.Parse();

        // fetch the DeviceDetector device name 
        var deviceName = dd.GetDeviceName();
            
        return deviceName.Equals("smartphone");
    }

    public override string ChannelName => "Smartphone"; // or use ordinary property if you haven't updated c#
}

Creating a Tablet DisplayChannel

public class TabletDisplayChannel : DisplayChannel
{
    public override bool IsActive(HttpContextBase context)
    {
        DeviceDetectorSettings.RegexesDirectory = ConfigurationManager.AppSettings["DeviceDetectorRegexesDirectory"];
        var dd = new DeviceDetector(context.Request.UserAgent);
        dd.DiscardBotInformation();
        dd.SkipBotDetection();
        dd.Parse();

        // fetch the DeviceDetector device name 
        var deviceName = dd.GetDeviceName();
            
        return deviceName.Equals("tablet");
    }

    public override string ChannelName => "Tablet"; // or use ordinary property if you haven't updated c#
}

Using the DisplayChannels in a Controller

Example with a startpage controller returning a default viewmodel, one that return a smart phone viewmodel and one that will return a tablet view model.

// Default
[TemplateDescriptor(Default = true)]
public class StartpagePageController : PageController
{
    public ActionResult Index(StartpagePage currentPage)
    {
        var model = new StartpagePageViewModel()
        {
            // Yada yada
        };

        return View(model);
    }
}

// Smartphone
[TemplateDescriptor(Tags = new[] { "Smartphone" })]
public class StartpagePageSmartphoneController : PageController
{

    public ActionResult Index(StartpagePage currentPage)
    {
        var model = new StartpagePageSmartphoneViewModel()
        {
            // Yoda yoda
        };

        return View(model);
    }
}

// Tablet
[TemplateDescriptor(Tags = new[] { "Tablet" })]
public class StartpagePageTabletController : PageController
{

    public ActionResult Index(StartpagePage currentPage)
    {
        var model = new StartpagePageTabletViewModel()
        {
            // Yum yum
        };

        return View(model);
    }
}

Conclusion

This is very useful if you want to separate your templates not only relying on media queries, this will also work on blocks in Episerver.

The DisplayChannels will be listed in Episerver CMS for editors to preview, I didn't include any examples of how to implement different display resolutions etc, to do that implement IDisplayResolution accordingly to the documentation.

Cheers