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