Как я могу сделать «шаблоны AJAX» в Pylons? - PullRequest
2 голосов
/ 02 августа 2010

В последнее время я попадаю в Pylons и удивляюсь, как мне легко интегрировать функциональность AJAX в мои веб-сайты.

Предположим, у меня была форма входа в систему, к которой обычно получают доступ через site.com/user/login. Теперь, как правило, это будет обрабатываться через что-то вроде:

class UserController(BaseController):
   def login(self):
      render('/login.html')

login.html будет шаблоном, который наследует базу, имеет заголовок, нижний колонтитул и боковую панель навигации. Plani, простой сайт.

Как я мог AJAXify это? Мне нужно создать два шаблона login.html, верно? Что было бы хорошим способом обработать метод login () контроллера? Должен ли я установить переменную GET что-то вроде &ajax=true, а затем проверить это при выдаче render ()?

Я хочу хороший и понятный способ выбора способа отображения контента на моих контроллерах вместо какого-то уродливого взлома (как метод GET выше).

Мысли

Ответы [ 3 ]

3 голосов
/ 05 сентября 2010

Все современные библиотеки Javascript устанавливают заголовок «X-Requested-With: XMLHttpRequest» в своих оболочках AJAX. Для удобства Pylons устанавливает логическое значение request.is_xhr, если находит этот заголовок.

Условное наследование в Мако немного сложное из-за , как обрабатывается <% наследовать> , но вот что вы делаете:

  1. Измените вызов render () в вашем контроллере на render('/login.html', {'ajax': request.is_xhr})

  2. В вашем шаблоне выделите все, что вам не нужно, в шаблоне AJAX, используя наследование шаблона .

  3. Используйте <% наследовать> что-то вроде этого: <%inherit file="${None if context.get('ajax') else 'login_base.html'}"/>

(Примечание: в используемом синтаксисе render () нет ничего особенного. Вы могли бы просто использовать вместо него c.ajax = request.is_xhr и context.get('c').ajax)

2 голосов
/ 02 августа 2010

Я не уверен, почему ваш AJAX-код хочет, чтобы сделал GET на этой login странице - GET предназначен только для получения информации, а какая информация будет JS-кодом клиентом-сторона хочет получить из формы входа?

В любом случае, при условии, что на есть страницы, которые вы хотите, чтобы AJAX-код мог получать, чтобы получить полезную информацию, я рекомендую строку запроса, такуюкак ?format=json, чтобы разрешить таким запросам явно запрашивать «только полезную информацию в формате JSON, не оформляйте, пожалуйста».

Мало того, что этот подход позволяет вашему приложению знать, что это автоматический запрос (AJAX илив противном случае, кого это волнует? Дело в том, что нет косметических средств следует отправлять в ответ, просто полезная информация!), но, в частности, запрашиваемый формат - JSON (так что, если вам захочетсяпредоставить XML или что-то в качестве альтернативы, есть очевидный путь роста - ?format=xml и т. п.)

В этом нет ничего особенно специфичного для Python, а тем более специфического для Pylons - это подходЯ бы порекомендовал любому «смешанному» сайту (способному, по крайней мере, на некоторых страницах отвечать в более чем одном формате, например, HTML с украшениями или JSON, по выбору клиентов), независимо от того, какой язык на стороне сервера он планировал использовать.

Если ваш рендеринг всегда имеет форму, такую ​​как somefunction(sometemplate, somecontext), вы можете изменить настройки, чтобы somefunction также получил решающий бит о запрошенном формате - если запрошенный формат - JSON(или, кто знает, в будущем может быть XML или что-то еще), тогда somefunction знает, что он может игнорировать шаблон (который в конце концов является или должен иметь чисто представление связанной функциональности, и, следовательно, должен иметь презентация только содержимое) и просто переведите информацию, которая находится в контексте, в JSON или как угодно.

1 голос
/ 20 декабря 2010

Автор Мако сам написал сообщение в блоге , которое может показаться вам интересным.
Суть в том, что есть функция для визуализации одного "def" шаблона:

def render_def(template_name, name, **kwargs):
    from pylons.templating import pylons_globals
    globs = pylons_globals()

    if kwargs:
        globs = globs.copy()
        globs.update(kwargs)

    template = globs['app_globals'].mako_lookup.get_template(template_name).get_def(name)
    return template.render(**globs)
...