Zmiana szablonów Django w oparciu o User-Agent

Zrobiłem stronę Django, ale wypiłem Koolaid i chcę zrobić wersję IPhone . Po zastanowieniu się nad tym, wymyśliłem dwie opcje:

  1. zrobić zupełnie inną stronę, jak i.xxxx.com. powiązać go z tą samą bazą danych używając frameworka Django ' s sites.
  2. Znajdź jakiś czas oprogramowania pośredniczącego, które odczytuje user-agent i dynamicznie zmienia katalogi szablonów.

Naprawdę wolałbym opcję # 2, jednak; mam pewne zastrzeżenia, głównie ponieważ dokumentacja Django zniechęca do zmiany ustawień w locie . Znalazłem fragment który zrobiłby to, co chcę. Moim głównym problemem jest to, że jest tak bezproblemowy, jak to możliwe, chciałbym, aby był automatyczny i przejrzysty dla użytkownika.

Czy ktoś jeszcze zetknął się z tym samym problemem? Czy ktoś chciałby się podzielić, jak poradzili sobie z tworzeniem IPhone ' owych wersji stron Django?

Update

Wybrałem kombinację middleware i Podkręcanie wywołania szablonu.

Dla middleware, użyłem minidetector . Podoba mi się, ponieważ wykrywa mnóstwo mobilnych agentów użytkowników. Wszystko, co muszę zrobić, to sprawdzić prośbę.moim zdaniem mobilny.

Dla wywołania szablonu tweak:

 def check_mobile(request, template_name):
     if request.mobile:
         return 'mobile-%s'%template_name
     return template_name

Używam tego dla każdego widoku, który wiem, że mam obie wersje.

TODO:

  • dowiedzieć się, jak uzyskać dostęp żądanie.mobile w rozszerzonej wersji render_to_response więc nie mam aby użyć check_mobile ('template_name.html")
  • użycie poprzedniego automagicznie alternatywnego szablonu, jeśli nie istnieje żadna wersja mobilna.
Author: imjoevasquez, 2008-10-03

10 answers

Zamiast dynamicznie zmieniać katalogi szablonów, możesz zmodyfikować żądanie i dodać wartość, która informuje Widok, czy użytkownik jest na iPhonie, czy nie. Następnie zawiń render_to_response (lub cokolwiek używasz do tworzenia obiektów HttpResponse), aby pobrać wersję iphone szablonu zamiast standardowej wersji html, jeśli używają iphone ' a.

 20
Author: afarnham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 20:44:38

Wykryj agenta użytkownika w middleware, Zmień powiązania url, zysk!

Jak? Obiekty żądań Django mająatrybut urlconf, który może być ustawiony przez middleware.

From django docs:

Django określa root URLconf moduł do użycia. Zazwyczaj jest to wartość ustawienia ROOT_URLCONF, ale jeśli przychodzący obiekt HttpRequest ma atrybut o nazwie urlconf (ustawiony przez middleware request processing), jego wartość zostanie użyta w miejsce Ustawienie ROOT_URLCONF.

  1. W yourproj/middlware.py, napisz klasę, która sprawdza łańcuch http_user_agent:

    import re
    MOBILE_AGENT_RE=re.compile(r".*(iphone|mobile|androidtouch)",re.IGNORECASE)
    class MobileMiddleware(object):
        def process_request(self,request):
            if MOBILE_AGENT_RE.match(request.META['HTTP_USER_AGENT']):
                request.urlconf="yourproj.mobile_urls"
    
  2. Nie zapomnij dodać tego do MIDDLEWARE_CLASSES w settings.py:

    MIDDLEWARE_CLASSES= [...
        'yourproj.middleware.MobileMiddleware',
    ...]
    
  3. Utwórz mobilny urlconf, yourproj/mobile_urls.py:

    urlpatterns=patterns('',('r'/?$', 'mobile.index'), ...)
    
 11
Author: Aneil Mallavarapu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 17:57:50
 4
Author: Swaroop C H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-11 17:04:52

Rozwijam djangobile, rozszerzenie Django mobile: http://code.google.com/p/djangobile/

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-19 12:46:33

Powinieneś rzucić okiem na kod źródłowy django-mobileadmin , który rozwiązał dokładnie ten problem.

 2
Author: ak.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-09 22:00:13

Innym sposobem byłoby stworzenie własnego loadera szablonów, który ładuje szablony specyficzne dla agenta użytkownika. Jest to dość ogólna technika i może być używana do dynamicznego określania, jaki szablon ma zostać załadowany w zależności od innych czynników, takich jak żądany język (dobry towarzysz istniejącej maszyny Django i18n).

Książka Django ma sekcję na ten temat .

 2
Author: zgoda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-16 09:41:23

Jest fajny artykuł, który wyjaśnia, jak renderować te same dane za pomocą różnych szablonów http://www.postneo.com/2006/07/26/acknowledging-the-mobile-web-with-django

Nadal musisz automatycznie przekierować użytkownika na stronę mobilną, ale można to zrobić za pomocą kilku metod (Twój trik check_mobile też zadziała)

 2
Author: Amit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 19:06:33

A może przekierowanie użytkownika do i.xxx.com po przeanalizowaniu jego UA w jakimś oprogramowaniu pośrednim? Szczerze wątpię, że użytkownicy mobilni dbają o to, jak wygląda adres url, nadal mogą uzyskać dostęp do twojej witryny za pomocą głównego adresu url.

 1
Author: Dmitry Shevchenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 21:08:31

Najlepszy możliwy scenariusz: użyj minidetector, aby dodać dodatkowe informacje do żądania, a następnie użyj wbudowanego w kontekst żądania django, aby przekazać je do swoich szablonów w ten sposób

from django.shortcuts import render_to_response
from django.template import RequestContext

def my_view_on_mobile_and_desktop(request)
    .....
    render_to_response('regular_template.html', 
                       {'my vars to template':vars}, 
                       context_instance=RequestContext(request))

Następnie w szablonie możesz wprowadzić takie rzeczy jak:

<html>
  <head>
  {% block head %}
    <title>blah</title>
  {% if request.mobile %}
    <link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-mobile.css">
  {% else %}
    <link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-desktop.css">
  {% endif %}
  </head>
  <body>
    <div id="navigation">
      {% include "_navigation.html" %}
    </div>
    {% if not request.mobile %}
    <div id="sidebar">
      <p> sidebar content not fit for mobile </p>
    </div>
    {% endif %>
    <div id="content">
      <article>
        {% if not request.mobile %}
        <aside>
          <p> aside content </p>
        </aside>
        {% endif %}
        <p> article content </p>
      </aricle>
    </div>
  </body>
</html>
 1
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-11 07:43:09

Prostym rozwiązaniem jest stworzenie owijki wokół django.shortcuts.render. Mój plik umieściłem w utils bibliotece w katalogu głównym mojej aplikacji. Wrapper działa poprzez automatyczne renderowanie szablonów w folderze "mobile" lub "desktop".

W utils.shortcuts:

from django.shortcuts import render
from user_agents import parse

def my_render(request, *args, **kwargs):
  """
  An extension of django.shortcuts.render.

  Appends 'mobile/' or 'desktop/' to a given template location
  to render the appropriate template for mobile or desktop

  depends on user_agents python library
  https://github.com/selwin/python-user-agents

  """
  template_location = args[0]
  args_list = list(args)

  ua_string = request.META['HTTP_USER_AGENT']
  user_agent = parse(ua_string)

  if user_agent.is_mobile:
      args_list[0] = 'mobile/' + template_location
      args = tuple(args_list)
      return render(request, *args, **kwargs)
  else:
      args_list[0] = 'desktop/' + template_location
      args = tuple(args_list)
      return render(request, *args, **kwargs)

W view:

from utils.shortcuts import my_render

def home(request):    return my_render(request, 'home.html')
 0
Author: Samora Dake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 21:09:45