librelist archives

« back to archive

Serving different sets of templates to standard and mobile browsers

Serving different sets of templates to standard and mobile browsers

From:
Luca Lesinigo
Date:
2011-11-07 @ 23:20
I wanted to keep the same views but use different sets of templates for 
"normal" browsers and mobile ones[1] - something similar has already been 
asked on this mailinglist[2] and I also tried on StackOverflow[3].

I don't really know why I didn't think about this solution before - it's 
so simple! Anyway, here is what I did:

import flask
# patch flask.render_template()
_render_template = flask.render_template
def _my_render_template(*args, **kwargs):
    if detect_mobile_browser(flask.request.user_agent.string):
        args = ('m/' + args[0],) + args[1:]
    return _render_template(*args, **kwargs)
flask.render_template = _my_render_template

It seems to work fine for me, and it keeps all the other code unmodified -
exactly the cleanliness I was aiming for!
I'm importing the whole flask package and "patch" flask.render_template() 
because my views are in other python modules where they do "from flask 
import request_template" - this way every flask import after the above 
snippet will get the 'patched' version of render_template()

I'm posting this to the list to ask for review, comments and possible 
improvements if you have any.
Do you guys think it should be posted in the snippets too?

Thanks.

[1] what actually constitutes a mobile browser and how to correctly detect
it is another whole story and beyond the scope of this post
[2] 
http://flask.pocoo.org/mailinglist/archive/2010/8/28/normal-and-mobile-website/
[3] 
http://stackoverflow.com/questions/7961290/how-to-organize-code-for-a-flask-application-with-multiple-set-of-templates

--
Luca Lesinigo

Re: [flask] Serving different sets of templates to standard and mobile browsers

From:
Oliver Berger
Date:
2011-11-08 @ 12:50
#1 for such reasons "we" evaluated (8 years ago) the x-wap-profile
header (points to a xml [*]) of all the handsets. we put resolution,
javascript support etc. into a table together with the user-agent
header. So we were able to group them into certain technological ranges
and map them hierarchically to our templates.
The result was good in supporting unknown handsets but made us also able
to deliver specialized content/templates for a single handset...

... I don't even know if still every handset has such a header.


regards,
Oliver

[*]

http://www.openmobilealliance.org/tech/affiliates/wap/wap-248-uaprof-20011020-a.pdf



On 08.11.2011 00:20, Luca Lesinigo wrote:
> I wanted to keep the same views but use different sets of templates for 
"normal" browsers and mobile ones[1] - something similar has already been 
asked on this mailinglist[2] and I also tried on StackOverflow[3].
> 
> I don't really know why I didn't think about this solution before - it's
so simple! Anyway, here is what I did:
> 
> import flask
> # patch flask.render_template()
> _render_template = flask.render_template
> def _my_render_template(*args, **kwargs):
>     if detect_mobile_browser(flask.request.user_agent.string):
>         args = ('m/' + args[0],) + args[1:]
>     return _render_template(*args, **kwargs)
> flask.render_template = _my_render_template
> 
> It seems to work fine for me, and it keeps all the other code unmodified
- exactly the cleanliness I was aiming for!
> I'm importing the whole flask package and "patch" 
flask.render_template() because my views are in other python modules where
they do "from flask import request_template" - this way every flask import
after the above snippet will get the 'patched' version of 
render_template()
> 
> I'm posting this to the list to ask for review, comments and possible 
improvements if you have any.
> Do you guys think it should be posted in the snippets too?
> 
> Thanks.
> 
> [1] what actually constitutes a mobile browser and how to correctly 
detect it is another whole story and beyond the scope of this post
> [2] 
http://flask.pocoo.org/mailinglist/archive/2010/8/28/normal-and-mobile-website/
> [3] 
http://stackoverflow.com/questions/7961290/how-to-organize-code-for-a-flask-application-with-multiple-set-of-templates
> 
> --
> Luca Lesinigo

Re: [flask] Serving different sets of templates to standard and mobile browsers

From:
Ron DuPlain
Date:
2011-11-10 @ 16:12
Hi Luca,

On Mon, Nov 7, 2011 at 6:20 PM, Luca Lesinigo <luca@lesinigo.it> wrote:
> I wanted to keep the same views but use different sets of templates
> for "normal" browsers and mobile ones[1] - something similar has
> already been asked on this mailinglist[2] and I also tried on
> StackOverflow[3].
>
> I don't really know why I didn't think about this solution before -
> it's so simple! Anyway, here is what I did:
>
> import flask
> # patch flask.render_template()
> _render_template = flask.render_template
> def _my_render_template(*args, **kwargs):
>    if detect_mobile_browser(flask.request.user_agent.string):
>        args = ('m/' + args[0],) + args[1:]
>    return _render_template(*args, **kwargs)
> flask.render_template = _my_render_template
>
> It seems to work fine for me, and it keeps all the other code
> unmodified - exactly the cleanliness I was aiming for!
>
> I'm importing the whole flask package and "patch"
> flask.render_template() because my views are in other python modules
> where they do "from flask import request_template" - this way every
> flask import after the above snippet will get the 'patched' version of
> render_template()
>
> I'm posting this to the list to ask for review, comments and possible
> improvements if you have any.
>

You can provide a custom template loader without monkey patching
Flask's render_template function.  See:

https://gist.github.com/1355170

The code is a bit longer than your snippet, but it includes two
important features: (1) it defaults to the default template if the
mobile template is not found, and (2) provides for straightforward
unit testing.  Reviewing Flask's template loader override hooks, there
are many, which makes me think a Flask.template_loader_class attribute
would simplify things greatly.

For mobile design, there's an issue as to whether to use separate
templates or media queries.  If you're using jQuery Mobile or
something similar, you have to go with separate templates because the
page structure is entirely different from the desktop site (in our
experience at WillowTree Apps, jQuery Mobile has strict patterns of
page flow).  If you're into irc, there's brief discussion here:

http://dev.pocoo.org/irclogs/%23pocoo.2011-09-22.log
starting at 2011-09-22T22:56:36

As for browser detection, User-Agent provides a quick fix but falls
apart when (a) the user wants the desktop site, (b) the user has e.g.
an Android tablet [which has a similar agent to the handset], or (c)
the agent is switched/spoofed or from an alternative browser.
User-Agent might work for you; that's up to your acceptance tests.
Otherwise, you can work with sessions or URL arguments.

Let me know if I can elaborate further,

Ron


PS - We use User-Agent for most simple sites at
http://www.willowtreeapps.com/ and it works (and is cheap to
implement).


> Do you guys think it should be posted in the snippets too?
>
> Thanks.
>
> [1] what actually constitutes a mobile browser and how to correctly 
detect it is another whole story and beyond the scope of this post
> [2] 
http://flask.pocoo.org/mailinglist/archive/2010/8/28/normal-and-mobile-website/
> [3] 
http://stackoverflow.com/questions/7961290/how-to-organize-code-for-a-flask-application-with-multiple-set-of-templates
>
> --
> Luca Lesinigo
>