Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • manwood 87 posts 109 karma points
    Mar 29, 2013 @ 13:58
    manwood
    0

    Creating a simple mobile site with 51Degrees

    Hi

     

    I'm running Umbraco version 4.7 and want to setup a simple mobile site. The mobile site needs to work as follows:

     

    • if user agent is a mobile device, redirect and all pages from then on should be in mobile format
    • provide the mobile user with an option to view the full site, after which they would continue to use the full site (set a cookie?)
    I have installed the 51Degrees package (mainly becuse it handles the second requirement I believe) but can't find any simple walkthroughs for getting it working with Umbraco.
    Does anyone have any experience of doing this? Or can point me to any tutorials providing an explanation of getting it working with Umbraco (non-MVC)?
    Thanks

     

  • gary 385 posts 916 karma points
    Mar 29, 2013 @ 17:33
    gary
    1

    Hi

    I have 51Degrees running in Umbraco, in 4.7 and 6+, but only in the MVC format.

    I may be able to help you in some way, but you may have to "make it work" in webforms as I do not have any idea.

    The option I use is to have a different layout file for mobile, so only use the one view for both mobile and desktop, but call JqueryMobile and a different css file for the mobile part.

    To not use the re-direct to a mobile site requires a modification to the 51 config, which I can post for you if you want to go in this direction. The detection is really simple and am sure you can adapt to webforms if you need. 

    Tutorials are not very easy to find, I managed to strip bits from asp.net tutorials and some very hidden posts on 51Degrees site. But it does work very well, have had no complaints on the detection of devices.

    Let me know if I can help with anything and we can see where we end up.

    G

  • manwood 87 posts 109 karma points
    Mar 29, 2013 @ 17:49
    manwood
    0

    Hi Gary

    I'd have to be a fool to turn down your offer! Thank you, much appreciated.

    I was hoping to use different macros for mobile versions, so I'm not sure just styling my page will work - it might do, but I'm not sure what I can and can't do (easily) in JQueryMobile.

    It feels like it would be easier from a maintenance point of view to have separate templates and macros for mobile so I don't break the main site which is stable and working. I could certainly use MVC for just the mobile pages (if Umbraco permits this?) and leave the web forms untouched - is that an option? What version of MVC does Umbraco 4.7 support?

    My email is manwoodvice at gmail if you wanted to send any configs, files etc.

    It would be really nice to be able to document a working approach here for others in the same boat...

  • manwood 87 posts 109 karma points
    Mar 29, 2013 @ 17:59
    manwood
    0

    I could probably upgrade the whle site to Umbraco 6 (assuming it doesn't break anything) which might make the mobile side easier...

  • gary 385 posts 916 karma points
    Mar 29, 2013 @ 18:04
    gary
    0

    Hi

    Thoughts - you must stay in webforms if your site is currently built that way, can't swap between the two forms unfortuantely, however, it does not mean it cannot be achieved by a little collaboration.

    What we can do is a kinda walkthrough, get a bit working then move on to next, if ok with you, this will as you say create a working doc for others from both sides ie webforms and MVC.

    Would be good to know what version of 4.7 you are using to clarify the MVC version (it changed in 4.7 somewhere, but can't remember where).

    If you wanted some advice, it would be make a "copy" of your site and use different templates for the mobile site, you will wish you hadn't, but it is far easier to make a mistake on one site than breaking the whole lot. I did it this way to begin, learnt a lot and now build mobile first, but trying to "re-build" integrating mobile into a current site is very difficult.

    Just read your latest post, and upgrading is an option, but it may be better to learn on what you know, 4.7 to 6 has some differences that may add to the confusion.

    Let me know, 4.7 version, will dig out the config and paste here for you to get an alternate layout going.

    G

  • manwood 87 posts 109 karma points
    Mar 29, 2013 @ 18:24
    manwood
    0

    Ok version is: 

    <add key="umbracoConfigurationStatus" value="4.7.1.1" />

    When you say "copy" what do you mean exactly? I'm working from a backup locally at the moment, so no worries about breaking the actual site. 

    Happy to stick with web forms in 4.7 for the timebeing.

    (I've got to head out now but I'll pick this up tomorrow - appreciate your help :))

  • gary 385 posts 916 karma points
    Mar 29, 2013 @ 18:30
    gary
    0

    ok no worries, will post first steps for you to pick up in the morning.

    When I say copy, you will have two templates for each page, so one for desktop, and one for mobile.

    You will accept a browser call, if it is mobile, then it will call the mobile template, this can have a different master template, which will call anything mobile you need, so essentially it will be a copy of the site, for mobile, but will share the same url which is the cool part about doing it this way. If you are using Analytics it adds to the pageviews, but also detects if it was from a mobile device so loses no impact regarding SEO.

    Ok will post a bit later the config stuff, which is the same for both webforms and razor.

    G

  • gary 385 posts 916 karma points
    Mar 30, 2013 @ 09:36
    gary
    0

    With the 51Degrees package installed open App_Data > 51Degrees.mobi.config

    Delete this line, which is Line 7 (Visual Studio, maybe different but at least a clue where to look)

          <section name="redirect" type="FiftyOne.Foundation.Mobile.Configuration.RedirectSection, FiftyOne.Foundation" requirePermission="false" allowDefinition="Everywhere" restartOnExternalChanges="false" allowExeDefinition="MachineToApplication"/>

    Edit out this snippet Line 62 as below
      <!--  <redirect firstRequestOnly="false"
                  mobileHomePageUrl="~/mobile/default.aspx"
                  timeout="20"
                  devicesFile="~/App_Data/Devices.dat"
                  mobilePagesRegex="mobile">
        </redirect> -->
    Save and close.
    This cancels the re-direct to a mobile "site", but allows the detection of mobile devices using the 51Degrees Package.
    Open up Web.config
    in <system.webServer> <modules>   (line 163) add the following;
    <remove name="Detector"/>
    <add name="Detector"  type="FiftyOne.Foundation.Mobile.Detection.DetectorModule, FiftyOne.Foundation"/>
    (for the record, when I looked for this line in a current site, it wasn't there, but detection works fine, I added it and still works fine, safety says to add it)
    OK, that's it set up. Will post how to check it is working in another post. Hopefully make it easier to follow or question
    G

     

     

     

     

     

     

     

  • gary 385 posts 916 karma points
    Mar 30, 2013 @ 10:09
    gary
    0

    To test if it is running there are a couple of options.

    First - having built a few sites for mobile, my advice would be to install Safari for Windows if you don't already have it.

    It is so easy to swap between desktop and mobile, hit the folded paper in top right hand corner, develop, user agent then pick from i-pad etc as required. Re-sizing the browser gives the effect you need. This may save you hours of frustration, that I encountered.

    Second - there are emulators available via webMatrix for Iphone and Ipad, they are useful in the sense that they give you the "screen" in the device, but do not display things like svg files and there was something else kinda fundamental that they didn't show (can't remember) but when seen on a real device, it was there. Safari browser does show if developing on local machine. 

    If you are starting a "new" site my recommendation would be to use the same view (template) with an alternative layout file. To do this with Umbraco in MVC mode in really easy, in the view where you have the @{ Layout = null} NOTE - this is for Umbraco latest versions (4.10+ or 6+)

    enter

    @{

        Layout = Request.Browser.IsMobileDevice

             ? "Shared/_LayoutMobile.cshtml"

             : "Shared/_Layout.cshtml";

    }

    To explain - I keep my layouts in a folder named Shared as per normal MVC approach, this is not necessary, but keeps things neat.

    so, if request browser is mobile (true = ?) then use layout _LayoutMobile, if not then use standard _Layout file.

    Create 2 css files - one desktop.css and another mobile.css. add them to the _Layout files as appropriate.

    To the body tag add a color, ie background-color: #f01 (red) to desktop and #fff(white) to mobile.

    Now when you switch user agent in Safari - you should see the colour change, simple.

    NOTE - trying to keep this simple, sure many of you have experience with these methods, but for those who don't, hope it helps.

    However, if you have a current site that needs a mobile version, it is possibly easier to call an alternative view. (in next post)

     

     

     

  • gary 385 posts 916 karma points
    Mar 30, 2013 @ 10:51
    gary
    0

    To call an alternative view, simply (may not be the "best way", but feel free to do as you think is best) call it in a partial.

    @{ if (Request.Browser.IsMobileDevice == true)
       {
           @Html.Partial("thisPageMobile")
       }
       else{
        if (Request.Browser.IsMobileDevice == false)
        {       
        Layout = "Shared/_Layout.cshtml";
        }
    
    Body of your page
    }
    }

    In the partial you can call you _LayoutMobile so all should still function correctly.

    Why call another page? 

    You have a working site - trying to adapt it can be difficult, it is probably easier if it already responsive, if it is not, then it can be very frustrating trying to keep everything "working" while adapting it.

    Would like to think of this as a fix, rather than an approach and would certainly not advocate it's use if starting a new site.

    I did use this approach in 4.7.1, but as I have no knowledge of webforms, just ran a macro to a cshtml file that allowed me to do everything in razor.(as above)

    Will post this snippet as it does show how I used the "macro" part of it, and would suggest that you can call something similar to call you content in an alternative view.

    <%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %>
    <asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
     <umbraco:Macro FileLocation="~/macroScripts/event.cshtml" runat="server" />  
    </asp:Content>

    This was in a masterpage for a page called event, so my thinking would be to add a version of either the alternate master, or an if statement that calls a macro as per the second alternative above? I dont even know if you can use the Request.Browser.IsMobileDevice, but I am sure there is a way that is similar.

    In this way you can keep all of your "desktop" page as it was, then just develop new css for the mobile version. 

    Copy and paste desktop page into new "mobile" page, remove all divs, and start again - you can try to adapt what you have, but experience says you will benefit from a new approach.

    Ok, probably raised more questions than answered, so, will leave it there for now. Please, if I have written anything dumb, stupid or plain ignorant - don't shout - get involved and help to get it right for anyone who wants to adapt Umbraco for mobile in either MVC or webforms.

    I am no expert, as you may have gathered, but am willing to share my short-comings.

    regards

    G

     

     

     

     

     

     

     

     

  • manwood 87 posts 109 karma points
    Mar 30, 2013 @ 13:04
    manwood
    0

    Brilliant stuff thanks Gary. I'm going to have a think and a play around and see what might work in webforms. I'll come back to you...

    Cheers!

  • Mike Chambers 636 posts 1253 karma points c-trib
    Apr 02, 2013 @ 11:14
    Mike Chambers
    0

    fyi... http://blog.mobileesp.com/ a free alternative to 51Degrees.

  • gary 385 posts 916 karma points
    Apr 02, 2013 @ 11:17
    gary
    0

    Hi Mike 

    Thanks for info - 51Degrees is also free, sorry, maybe should have pointed that out.

    G

  • Mike Chambers 636 posts 1253 karma points c-trib
    Apr 02, 2013 @ 11:29
    Mike Chambers
    0

    Sorry.. when last I looked 51degrees was "ScientiaMobile" and paid only must have branched again... I can see they have a free lite detection offering now..

    http://51degrees.mobi/Products/DeviceDetection.aspx

    MobileEsp has advantages over the free "lite" 51degrees version... if you are after distinguishing type of mobile device...  :-)

  • manwood 87 posts 109 karma points
    Apr 09, 2013 @ 14:24
    manwood
    0

    Ok, so what I have done to enable in v4.7.1:

    • added the 51 degrees package
    • configured as per Gary's post above
    • created a user control that performs the mobile detection and redirect
    • created separate mobile templates that use the naming convention "xxxMobile" 
    • amended links in the site that support mobile views to include the querystring "redirectformobile=true" - when the switch reads this, it attempts to dynamically load the mobile template and then redirect using the "alttemplate" querystring param
    • the whole thing works nicely because I haven't had to change any content pages, only document types
    The user control code is below:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using umbraco.cms.businesslogic.web;
    using umbraco.NodeFactory;
    using Umbraco.Core.Services;
    namespace Zerocode.MobileSwitch
    {
        public partial class MobileSwitch : UserControl
        {
            private readonly string CookieName = "SiteMode";
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    HttpCookie cookie = Request.Cookies[this.CookieName];
                    bool redirectToMobile = this.ReadQueryString();
     
                    if (Request.Browser.IsMobileDevice && cookie == null)
                    {
                        cookie = this.CreateCookie();
                        cookie.Value = SiteMode.Mobile.ToString();
                        Response.Cookies.Add(cookie);
                        this.RedirectToMobile();
                        return;
                    }
                    SiteMode siteMode = (SiteMode)Enum.Parse(typeof(SiteMode), cookie.Value);
                    if (siteMode == SiteMode.Mobile && redirectToMobile)
                    {
                        this.RedirectToMobile();
                        return;
                    }
                    this.ConfigureSwitch(siteMode);
                }
            }
            private bool ReadQueryString()
            {
                var redirectToMobile = Request.QueryString["redirectformobile"];
                var redirectBool = false;
                if (String.IsNullOrWhiteSpace(redirectToMobile) || !Boolean.TryParse(redirectToMobile, out redirectBool))
                {
                    return false;
                }
                return redirectBool;
            }
            private void ConfigureSwitch(SiteMode siteMode)
            {
                switch (siteMode)
                {
                    case SiteMode.Mobile:
                        this.lbDesktopSite.Visible = true;
                        this.lbMobileSite.Visible = false;
                        break;
                    case SiteMode.Desktop:
                    default:
                        this.lbDesktopSite.Visible = false;
                        this.lbMobileSite.Visible = true;
                        break;
                }
            }
            protected void SetSiteMode(Object Sender, EventArgs e)
            {
                LinkButton button = Sender as LinkButton;
                SiteMode siteMode = (SiteMode)Enum.Parse(typeof(SiteMode), button.CommandArgument);
                HttpCookie cookie = this.CreateCookie();
                cookie.Value = siteMode.ToString();
                Response.Cookies.Add(cookie);
                switch (siteMode)
                {
                    case SiteMode.Mobile:
                        this.RedirectToMobile();
                        break;
                    case SiteMode.Desktop:
                    default:
                        this.RedirectToDesktop();
                        break;
                }
            }
            private HttpCookie CreateCookie()
            {
                HttpCookie cookie = new HttpCookie(this.CookieName);
                cookie.Expires = DateTime.Now.AddMonths(1);
                return cookie;
            }
            private void RedirectToDesktop()
            {
                Response.Redirect(Request.Url.AbsolutePath);
            }
            private void RedirectToMobile()
            {
                var node = Node.GetCurrent();
                var docType = DocumentType.GetByAlias(node.NodeTypeAlias);
                var mobileTemplate = docType.allowedTemplates.FirstOrDefault(x => x.Alias.Contains("Mobile"));
                if (mobileTemplate != null)
                {
                    var redirectUrl = this.BuildMobileRedirectUrl(mobileTemplate.Alias);
                    Response.Redirect(redirectUrl);
                    return;
                }
                Response.Redirect("~/?alttemplate=homemobile");
            }
            private string BuildMobileRedirectUrl(string templateAlias)
            {
                var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());
                
                nameValues.Remove("redirectformobile");
                nameValues.Set("alttemplate", templateAlias);
                
                string url = Request.Url.AbsolutePath;
                string updatedQueryString = "?" + nameValues.ToString();
                return url + updatedQueryString;
            }
            private enum SiteMode { Desktop, Mobile };
        }
    }
    And the control UI:
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MobileSwitch.ascx.cs" Inherits="Zerocode.MobileSwitch.MobileSwitch" %>
    <asp:LinkButton runat="server" ID="lbDesktopSite" CommandName="SetSiteMode" CommandArgument="Desktop" OnClick="SetSiteMode" Text="Desktop Site" />
    <asp:LinkButton runat="server" ID="lbMobileSite" CommandName="SetSiteMode" CommandArgument="Mobile" OnClick="SetSiteMode" Text="Mobile Site" />
  • gary 385 posts 916 karma points
    Apr 09, 2013 @ 14:34
    gary
    0

    Fantastic - pleased it worked for you.

    And a webforms example for others to follow. 

    Will add some points, just as soon as I find out how.

    Parabens as we say here in sunny Portugal.

    G

    Quick note - the MVC route seems so much simpler?

  • manwood 87 posts 109 karma points
    Apr 09, 2013 @ 16:22
    manwood
    0

    Yeah absolutely - MVC if you have the choice :)

    Thanks for your help (and very jealous you're in Portugal!)

  • manwood 87 posts 109 karma points
    Apr 09, 2013 @ 19:34
    manwood
    0

    Updated code behind for the control, the last version had a bug :o

     

        public partial class MobileSwitch : UserControl

        {

            private readonly string CookieName = "SiteMode";

     

            protected void Page_Load(object sender, EventArgs e)

            {

                if (!IsPostBack)

                {

                    HttpCookie cookie = Request.Cookies[this.CookieName];

                    bool redirectToMobile = this.ReadQueryString();

                    SiteMode siteMode = SiteMode.Desktop;

     

                    // First time site is requested on mobile device

                    // assume the user wants the mobile site, set cookie and redirect

                    if (Request.Browser.IsMobileDevice && cookie == null)

                    {

                        cookie = this.CreateCookie();

                        cookie.Value = SiteMode.Mobile.ToString();

     

                        Response.Cookies.Add(cookie);

     

                        this.RedirectToMobile();

                        return;

                    }

     

                    // On subsequent requests, read the cookie and redirect only

                    // where the user is in SiteMode.Mobile and the request contains an instruction to rediect

                    if (cookie != null)

                    {

                        siteMode = (SiteMode)Enum.Parse(typeof(SiteMode), cookie.Value);

     

                        if (siteMode == SiteMode.Mobile && redirectToMobile)

                        {

                            this.RedirectToMobile();

                            return;

                        }

                    }

     

                    // Where the user is either in SiteMode.Desktop, or in SiteMode.Mobile and

                    // the page has already been redirected and is now loading the alttemplate

                    this.ConfigureSwitch(siteMode);

                }

            }

     

            private bool ReadQueryString()

            {

                var redirectToMobile = Request.QueryString["redirectformobile"];

                var redirectBool = false;

     

                if (String.IsNullOrWhiteSpace(redirectToMobile) || !Boolean.TryParse(redirectToMobile, out redirectBool))

                {

                    return false;

                }

     

                return redirectBool;

            }

     

            private void ConfigureSwitch(SiteMode siteMode)

            {

                switch (siteMode)

                {

                    case SiteMode.Mobile:

                        this.lbDesktopSite.Visible = true;

                        this.lbMobileSite.Visible = false;

                        break;

                    case SiteMode.Desktop:

                    default:

                        this.lbDesktopSite.Visible = false;

                        this.lbMobileSite.Visible = true;

                        break;

                }

            }

     

            protected void SetSiteMode(Object Sender, EventArgs e)

            {

                LinkButton button = Sender as LinkButton;

                SiteMode siteMode = (SiteMode)Enum.Parse(typeof(SiteMode), button.CommandArgument);

     

                HttpCookie cookie = this.CreateCookie();

                cookie.Value = siteMode.ToString();

     

                Response.Cookies.Add(cookie);

     

                switch (siteMode)

                {

                    case SiteMode.Mobile:

                        this.RedirectToMobile();

                        break;

                    case SiteMode.Desktop:

                    default:

                        this.RedirectToDesktop();

                        break;

                }

            }

     

            private HttpCookie CreateCookie()

            {

                HttpCookie cookie = new HttpCookie(this.CookieName);

                cookie.Expires = DateTime.Now.AddMonths(1);

     

                return cookie;

            }

     

            private void RedirectToDesktop()

            {

                Response.Redirect(Request.Url.AbsolutePath);

            }

     

            private void RedirectToMobile()

            {

                var node = Node.GetCurrent();

                var docType = DocumentType.GetByAlias(node.NodeTypeAlias);

                var mobileTemplate = docType.allowedTemplates.FirstOrDefault(x => x.Alias.Contains("Mobile"));

     

                if (mobileTemplate != null)

                {

                    var redirectUrl = this.BuildMobileRedirectUrl(mobileTemplate.Alias);

     

                    Response.Redirect(redirectUrl);

                    return;

                }

     

                // Specify a default mobile template where no template is found dynamically

                Response.Redirect("~/?alttemplate=homemobile");

            }

     

            private string BuildMobileRedirectUrl(string templateAlias)

            {

                var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());

                

                nameValues.Remove("redirectformobile");

                nameValues.Set("alttemplate", templateAlias);

                

                string url = Request.Url.AbsolutePath;

                string updatedQueryString = "?" + nameValues.ToString();

     

                return url + updatedQueryString;

            }

     

            private enum SiteMode { Desktop, Mobile };

        }

  • MK 429 posts 906 karma points
    Apr 16, 2013 @ 20:43
    MK
    0

    Wow many thanks for this one!

  • manwood 87 posts 109 karma points
    Apr 16, 2013 @ 23:15
    manwood
    0

    I'm noticing issues with the 51degrees detection of mobile devices. I'm not 100% convinced it works that well. 

    Has anyone else had issues around device detection?

  • MK 429 posts 906 karma points
    Apr 18, 2013 @ 15:13
    MK
    0

    Hi manwood,

    Can you be a bit more specific regarding the problem?

    Been testing your solution with no problems on few devices and emulators and on several occasion and everything seems to work smoothly.

    Regards,

    mkariti

     

  • gary 385 posts 916 karma points
    Apr 18, 2013 @ 19:52
    gary
    0

    Hi

    Would just add that in a real random test on Opera emulator I did manage to find a couple of devices it didn't detect, but when I looked at the device I had never heard of it, so didn't worry about it. I also have fallback on my desktop site with the responsive design, so all is not lost.

    Overall have been happy with the detection. Would only add one comment and that might be the detection fails if cookies aren't enabled? As you will require both a mobile device and cookies enabled if I have read the code correctly?

    Regards

    Gary

  • MK 429 posts 906 karma points
    Jul 31, 2013 @ 10:51
    MK
    0

    Hi,

    Can any one please tel me what need to be done inorder to alter the code to send the mobile user only to mobile - i.e. cancell the option to ps site?

    For some reason I cant get it right - get redirect loops.

    Cheers

    mkariti

Please Sign in or register to post replies

Write your reply to:

Draft