Problema
Temos páxinas que se leen con dificultade en dispositivos móviles, como iPhone e Android. Buscando por ahí adiante atopéi varios enfoques, e o máis extendido é analizar a petición do cliente (HTTP_USER_AGENT sobre todo) para ver si pertence a un dispositivo móvil. Unha vez determinado, aplicar a solución requeridaA base
Partín da base de Django mobile utils, que implementa unha solución robusta. Cando chega a petición (request), antes de chegar óviews.py
pasa por un middleware que intenta averiguar si o USER_AGENT é móbil. A función está no __init__.py
, e garda o request nunha variable local. Aquí é donde me falla, xa que non consigo recuperar as variables locais. Despóis de pasar polo middleware, o request orixinal está marcado como .is_mobile = True
. Hai un código para cargar os "templates" alternativos, dentro de loaders.py
; este loader mira dentro da variable local de request si ten o valor .is_mobile == True
, porque non se lle pode pasar como parámetro o propio request. Así que si falla o request local, falla todo.Por sorte, o autor tamén incluiu un context_processor, que simplemente se encarga de pasarlle un diccionario de variables ós templates. Por exemplo, si activamos o context_procesor de auth, en tódolos templates teremos dispoñibles un número de variables como
user
.
A solución
Utilizando o código anterior, podemos simplificalo para utilizar só o__init__.py
e o context_processor.py
. Os context_processors deben manterse simples según o manual oficial, así que si podemos pasar só unha variable, mellor que dúas. Dende o context_processor.py
orixinal:def mobile_browser(request): dict = {'mobile_browser': False} if hasattr(request, 'is_mobile'): dict['mobile_browser'] = request.is_mobile return dictPodemos pasar a outro context máis simple aínda, como:
def mobile_browser(request): dict = {'mobile_browser': False} if our_server.django_mobile_utils.is_mobile(request): dict['mobile_browser'] = True return dictVemos que o autor orixinal sigue tirando de request acumulado en local, pero nós imos testear directamente o request. Modificamos tamén o código do
__init__.py
. Das varias liñas de tipo:
request.mobile = True return requestCambiamos a:
return TrueE a última liña que pon
return request
cambiámola a return False
. Ou adornamos con variables, si nos gusta máis.Si estamos pola simplificación extrema, todas as globáis deste archivo pódense eliminar, así como a configuración no
settings.py
, no que chega con engadir:TEMPLATE_CONTEXT_PROCESSORS = ( "our_server.django_mobile_utils.context_processors.mobile_browser", ...
Aplicación
Agora temos no directorio django_mobile_utils os arquivos__init__.py
, context_processor.py
e un directorio data/mobile_agents.txt
, e o settings.py
modificado como corresponde. ¿Cómo ó usamos? Simplemente, nos templates utilizamos a variable booleana {{mobile_browser}}
como condicional, por exemplo para cargar unha folla de estilo diferente:{% if mobile_browser %} <link href="/media/css/mobile_style.css" rel="stylesheet" type="text/css" /> {% else %} <link href="/media/css/style.css" rel="stylesheet" type="text/css" /> {% endif %}