Welcome to the navigation

Proident, magna ullamco cupidatat nulla aute elit, excepteur esse consequat, enim est minim eiusmod id dolor ex mollit quis nostrud in exercitation aliqua, anim non. Aute veniam, sit deserunt esse qui do reprehenderit anim sint elit, dolor mollit non duis nostrud culpa fugiat sunt nisi dolore ullamco tempor officia sed

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