Альтернативные мобильные шаблоны для приложения mako+flask-django

У нас есть приложение, представляющее собой сплав flask и django, и оно использует mako в качестве механизма шаблонов, мы хотим предоставить альтернативные шаблоны в некоторых представлениях, когда пользователь находится на мобильном устройстве, в настоящее время я сделал две подпапки. в папке моих шаблонов и переопределите метод рендеринга, чтобы получить соответствующий mako

templates
   mobile
     base.mako
     index.mako
   desktop
     base.mako
     index.mako
     results.mako

Так, например, если я вызываю render("index.mako") и запрос имеет request.mobile==True, то он преобразует URL-адрес файла в mobile/index.mako , если 'mobile/{some template}.mako' не существует, он автоматически захватит 'desktop/{какой-то шаблон}.mako', так как все шаблоны существуют для рабочего стола. Теперь проблема связана с наследованием, скажем, у меня есть следующий шаблон

результаты.мако

<%inherit file="base.mako" />
<select>
------
</select>

и я вызываю render("results.mako") с request.mobile==True , путь будет преобразован в desktop/results.mako (поскольку results.mako не существует для мобильных устройств), а results.mako наследует от «desktop/base.mako» (поскольку он использует относительный путь), а не правильный «mobile/base.mako», который следует использовать, поскольку это мобильный телефон, а mobile/base.mako существует.

Любые идеи о том, как решить это элегантным способом (избегайте ifs внутри mako)? Может быть, каким-то образом изменив каталог, make считает, что шаблон находится?


person SteveL    schedule 01.07.2016    source источник


Ответы (1)


Я решил проблему, переопределив метод get_template объекта TemplateLookup mako.

    #override the template loading function in order to load the mobile ones when needed
    def get_template(self, uri):
        is_mobile_version=False
        has_mobile_view=False;

        u = re.sub(r'^\/+', '', uri).replace("mobile/","").replace("desktop/","")
        for dir in self.directories:
            dir = dir.replace(os.path.sep, posixpath.sep)

            mobile_file = posixpath.normpath(posixpath.join(dir, "mobile/" + u))

            if os.path.isfile(mobile_file):
                has_mobile_view = True

            if (local.request.cookies.get("mobile") == "true"):
                is_mobile_version = True

                local.response_headers['has_mobile_view'] = has_mobile_view
                local.response_headers["mobile"] = True

                if (has_mobile_view):
                    local.response_headers['is_mobile_version'] = is_mobile_version
                    return self._load(mobile_file, "mobile/" + u)

            desktop_file = posixpath.normpath(posixpath.join(dir, "desktop/" + u))
            if (os.path.isfile(desktop_file)):
                return self._load(desktop_file, uri)
            else:
                raise exceptions.TopLevelLookupException(
                    "Cant locate(desktop or mobile) template for uri %r" % uri)
    func_type=type(TemplateLookup.get_template)
    self.template_env.get_template = func_type(get_template, self.template_env, TemplateLookup)
person SteveL    schedule 01.07.2016