Products

Solutions

Resources

Partners

Community

About

New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.


Responsive Design + Server Side Components ( RESS ) in DNN

Last week I did a presentation at the DevTeach web developmeent conference in Vancouver. I had hoped that attendees would appreciate the wit in the title of my session, "On the Mobile Web... sometimes RESS is more". Unfortunately, I discovered that the "RESS" acronym is not yet as widely known as I had imagined amongst web developers, so my attempt at being clever was lost on most people. Luckily, the abstract for my session contained a lot more detail and as a result I had a decent turnout for my session.

"With the explosion of mobile devices in recent years (BYOD), organizations of every size are faced with the problem of creating optimized mobile experiences for their online audience... In this session we will cover the various techniques for dealing with the mobile web. We will discuss dedicated mobile websites and the benefits of device detection technology. We will examine responsive web design (RWD) and explore the power of CSS media queries and responsive frameworks such as Bootstrap for customizing the display of content based on the screen size of a device. We will also delve into a new hybrid approach known as Responsive Design + Server Side Components (RESS) which uses a combination of client-side and server-side techniques to provide the best web experience for mobile devices."

I obviously wanted to leverage DNN to showcase all of these techniques in action. And since we have been shipping the 51 Degrees device detection capability in the platform since DNN 6.1, it was very easy to demonstrate how easy it is to detect any mobile device and redirect the visitor to an optimized experience. In my case, I used our multi-site capability to create another site at "m.mysite.com" using the Mobile template, and I created a default redirect rule for mobile devices. And using the new responsive Gravity skin in DNN 7.2 I was able to explain CSS media queries, Bootstrap, and the pros and cons of responsive web design. So that leaves the last technique and the focus of my session: RESS.

RESS stands for Responsive Design + Server Side Components. Essentially what it attempts to solve is the standard responsive design problem where ALL content is sent from the server to the mobile browser regardless of whether that content is expected to be utilized on the client device or not. Sending unnecessary content over the network is extremely inefficient and results in performance issues and a poor user experience. RESS adds an extra layer of intelligence on the server where it detects the device that issued the request and customizes the content that is sent to the client browser.

So how do we enable RESS in DNN?

In DNN 7.0 we introduced a new interface in the core platform named IModuleInjectionFilter. This interface has a single method named CanInjectModule() which provides an extensibility point that is available when a page is being assembled on the server. As DNN iterates through the various modules that are part of a page, it will call the interface for each module instance and allow you to provide custom business logic that will instruct the system on whether or not the module should be injected. This interface can be used for a variety of purposes including licensing, personalization, security, localization, A/B testing, etc... We will use this interface to allow us to specify if a specific module instance should be sent to a mobile device.

Copy the following code and paste it into a new class file named RESSInjectionFilter.cs that you save in the App_Code folder. You will notice that we are utilizing the Header property of each Module intance to provide special instructions on whether the module should be included in the page output or not. We are also taking advantage of the 51 Degrees device detection capability to identify mobile devices on the server.

#region "Using Statements"

using System.Web;
using DotNetNuke.UI.Modules;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Security.Permissions;

#endregion

namespace DotNetNuke.Services
{

    public class RESSInjectionFilter : IModuleInjectionFilter
    {

        public bool CanInjectModule(ModuleInfo objModule, PortalSettings objPortalSettings)
        {
            bool InjectModule = true;
            // RESS instructions stored in module header as an HTML comment <!-- MOBILE=HIDE -->
            if (objModule.Header.ToUpper().IndexOf("MOBILE=HIDE") != -1) {
                // if user does not have EDIT permissions
                if (ModulePermissionController.HasModulePermission(objModule.ModulePermissions, "EDIT") == false) {
                    // check device characteristics
                    dynamic objDevice = DotNetNuke.Services.ClientCapability.ClientCapabilityProvider.CurrentClientCapability;
                    InjectModule = !objDevice.IsMobile;
                }
            }
            return InjectModule;
        }

    }

}

To enable RESS in our site, we will use a default installation of DNN 7.2 and we will customize the home page so that the large banner images in the rotator are not sent to a mobile device. To do this, we will login to the site and go into Edit mode for the Home page. We will load the Module Settings dialog for the module instance containing the rotating banner. In the Advanced Settings we will add an HTML comment to the Header property of <!-- MOBILE=HIDE -->.

And as a result when we visit the site using a mobile device, the rotating banner will no longer be displayed. This may not seem very impressive on the surface, as it is fairly simply to simply hide content using client-side script. However, the real benefit of RESS is that the content was actually filtered on the server and was never sent across the wire. This reduces the network payload and improves the browsing experiencee for mobile devices significantly. In our example, it reduced the amount of information transferred by almost 500 KB!

I expect that in the coming year, RESS will get more mainstream adoption and attention as organizations make efforts to optimize their mobile user experience. And on a side note, I hope that this example also showcases the power of the new IModuleInjectionFilter interface which provides extensibility opportunities that were not previously possible in DNN.

Comments

Jordan
I had no idea about the IModuleInjectionFilter . That is indeed a very useful interface.
I wonder if there is a way to build this into the skin containers. IE, if a container css class contains "MobileHide" as one of its classes then the filter would not return it. Then you could just create a Not for Mobile container and put whatever content you want in that container to be absent from mobile devices. This would make it easier for clients who like to manage their own content.
Thanks for the great post.
Jordan Thursday, December 12, 2013 10:50 AM (link)
Shaun Walker
@Jordan - Interesting suggestion... I believe that it would be possible to do what you describe, as this interface provides you with full flexibility on the server-side to access the DNN environment. I implemented the solution described in this blog because I wanted a simple way for a content editor to be able to control which modules get injected, and I also wanted to minimize any performance implications ( which I achieved because all Module properties are cached by default ).
Shaun Walker Thursday, December 12, 2013 1:15 PM (link)
Jay Mathis
Wouldn't the above suggestion be easier and more intuitive if implemented as a checkbox on the Module Settings UI?
Jay Mathis Friday, December 13, 2013 10:42 AM (link)
Shaun Walker
@Jay Mathis - this blog was intended to describe how you can achieve RESS in DNN today without any core platform changes. If this enhancement were actually productized then you are correct, we would want to include a simple option in the Module Settings user interface. It would be interesting to know how many people would find this to be a useful core enhancement. Perhaps I should create an idea in Community Voice.
Shaun Walker Friday, December 13, 2013 12:26 PM (link)
Shaun Walker
The idea has been submitted: http://www.dnnsoftware.com/voice/cid/425100. Please go ahead and vote for it if you think it adds value.
Shaun Walker Friday, December 13, 2013 12:30 PM (link)
Phil Speth
I second that!
Phil Speth Friday, December 13, 2013 7:54 PM (link)
Lucas Jans
How might this impact Dnn's PageOutput caching via the provider model? (It's hard to find any documentation on this provider type.) Would it be possible to variate a cache on device type (mobile/tablet/desktop) plus the additional options already available (query string, max variations.)

PageOutput caching is essential for any high trafficked website.
Lucas Jans Saturday, December 14, 2013 3:17 PM (link)
Shaun Walker
@Lucas - the solution I described about would not work with DNN's page output caching capability because there is currently no support for varying a page cache. However, the solution would work with DNN's module output caching - which is sometimes a preferable caching option anyways because you often have a mixture of static and personalized content on a page.
Shaun Walker Monday, December 16, 2013 1:43 PM (link)
Istvan-Zoltan Fejer
The problem with this right now is that it hides modules from tablet too. Is there any way around this?
Istvan-Zoltan Fejer Wednesday, June 11, 2014 4:53 AM (link)
Jeff Andre
Forgive the post by a non-developer, but I'm looking for the ability to do exactly this, and was hoping to find something "canned" if you will that I could purchase to add to my DNN server, but haven't had any luck.

Since my installation of DNN doesn't have an "App_Code" folder, I'm assuming that's a standard nomenclature for development folder structures when writing DNN code. Does the code snippet you posted have to be compiled to then be added to the DNN installation?

Having seen some .cs files in the App_GlobalResources folder, I was hoping that this was the location it might belong to, but placing your RESSInjectionFilter.cs file in that folder doesn't appear to do anything.

Again, sorry for the elementary question. Any help in getting this working would be appreciated.
Jeff Andre Monday, June 30, 2014 2:48 PM (link)
Shaun Walker
@Jeff - you can create your own folder named App_Code in the root of your DNN site and then place the code above into a RESSInjectionFilter.cs file in that folder. This will instruct ASP.NET to compile the code for you.
Shaun Walker Monday, June 30, 2014 8:08 PM (link)

Comment Form

Only registered users may post comments.

NewsArchives


Aderson Oliveira (22)
Alec Whittington (11)
Alessandra Daniels (3)
Alex Shirley (10)
Andrew Hoefling (3)
Andrew Nurse (30)
Andy Tryba (1)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (37)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Bogdan Litescu (1)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (213)
Chris Paterra (55)
Clint Patterson (108)
Cuong Dang (21)
Daniel Bartholomew (2)
Daniel Mettler (181)
Daniel Valadas (48)
Dave Buckner (2)
David Poindexter (12)
David Rodriguez (3)
Dennis Shiao (1)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (80)
Francisco Perez Andres (17)
Geoff Barlow (12)
George Alatrash (12)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (274)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Kelly Ford (4)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matt Rutledge (2)
Matthias Schlomann (16)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Miguel Gatmaytan (3)
Mike Horton (19)
Mitchel Sellers (40)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Oliver Hine (1)
Patricio F. Salinas (1)
Patrick Ryan (1)
Peter Donker (54)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Sacha Trauwaen (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott Schlesier (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Steven Fisher (1)
Tony Henrich (3)
Torsten Weggen (3)
Tycho de Waard (4)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (40)
Will Strohl (180)
William Severance (5)
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out