【问题标题】:How can I make 'AJAX templates' in Pylons?如何在 Pylons 中制作“AJAX 模板”?
【发布时间】:2010-08-02 05:15:06
【问题描述】:

我最近开始接触 Pylons,想知道如何才能轻松地将 AJAX 功能集成到我的网站中。

基本上,假设我有一个通常通过site.com/user/login 访问的登录表单。现在,通常,这将通过以下方式处理:

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

login.html 将是一个继承基础的模板,具有页眉、页脚和导航侧边栏。一个平面、简单的网站。

我怎么能 AJAXify 这个?我需要创建两个 login.html 模板,对吗?处理控制器的 login() 方法的好方法是什么?我应该设置一个类似&ajax=true 的 GET 变量,然后在发出 render() 时检查它吗?

我想要一种简洁明了的方式来选择我的控制器如何呈现内容,而不是一些丑陋的 hack(如上面的 GET 方法)。

想法?

【问题讨论】:

  • 介意对我们的答案提供一些反馈吗?我们很好奇我们还需要说些什么才能获得“最佳答案”复选标记。

标签: javascript python ajax pylons


【解决方案1】:

所有现代 Javascript 库都在其 AJAX 包装器中设置了“X-Requested-With: XMLHttpRequest”标头。为方便起见,如果 Pylons 找到此标头,则设置 request.is_xhr 布尔值。

由于how <%inherit> is handled,在 Mako 中条件继承有点棘手,但您可以这样做:

  1. 将控制器中的 render() 调用更改为 render('/login.html', {'ajax': request.is_xhr})

  2. 在您的模板中,使用 template inheritance 将您不需要的 AJAX 模板中的任何内容分开。

  3. 使用类似这样的 : &lt;%inherit file="${None if context.get('ajax') else 'login_base.html'}"/&gt;

(注意:使用的 render() 语法没有什么特别之处。您可以轻松地使用 c.ajax = request.is_xhrcontext.get('c').ajax 代替)

【讨论】:

    【解决方案2】:

    我不确定为什么您的 AJAX 代码会想要在该 login 页面上执行 GET -- GET 仅用于获取信息,而 JS 代码客户端将提供哪些信息-side 想从登录表单中获取?

    无论如何,假设有 个页面您希望 AJAX 代码能够 GET 以获得有用的信息,我建议使用诸如 ?format=json 之类的查询字符串以允许此类请求明确询问仅用于“有用的 JSON 格式信息,请勿装饰”。

    这种方法不仅可以让您的应用知道这是一个自动请求(AJAX 或其他,谁在乎?关键是,要发送化妆品作为响应,只是 有用的信息!),但特别是请求的格式是 JSON(因此,如果您想提供 XML 或其他替代方式,有一条明显的增长路径——?format=xml 等)。

    在这方面没有什么特别是 Python 特定的,更不用说 Pylons 特定的了——这是我为任何“混合”网站推荐的方法(至少在某些页面中,能够以一种以上的格式响应,例如带有装饰的 HTML 或 JSON,由客户选择),无论它计划使用哪种服务器端语言。

    但是,如果您的渲染始终采用 somefunction(sometemplate, somecontext) 之类的形式,您可以进行一些调整以确保 somefunction 也获得有关请求格式的关键信息——如果请求的格式是 JSON(或者,谁知道,将来可能是 XML 或其他)然后somefunction 知道它可以忽略模板(毕竟它是或应该是纯粹的 view 相关功能,因此应该有 presentation 仅内容),然后继续将上下文中的信息呈现为 JSON 或其他内容。

    【讨论】:

    • 1.12 版本的 Routes 提供格式为文件扩展的语法 routes.groovie.org/setting_up.html#format-extensions,恕我直言,它看起来比查询字符串更好。
    • GET 推理类似于:&lt;a href="/user/login"&gt;Login&lt;/a&gt;。这将显示为标准登录链接。然后,我会让我的 Javascript 附加 &amp;format=json 属性,这样,当点击时,我可以在灯箱中打开登录表单,而不是加载一个全新的页面。
    • @Carl,但是您需要从服务器获取哪些信息才能打开登录表单?难道它不能成为 JS 功能的一部分吗?毕竟服务器 已经 早先服务过?-) 无论如何,如果您 确实 需要该页面的一些信息,然后请求/user/login?format=json,或者如果您更喜欢@Daniel 的评论建议的方法,或者冷漠/user/login.json,似乎是正确的方法。毕竟,AJAX 查询与您明天可能想要为您的服务器创建的其他程序化客户端(例如原生 iPhone 或 Android 应用程序等)没有什么不同。
    【解决方案3】:

    Mako 的作者自己写了一个blog post,你可能会觉得有趣。
    重点是渲染模板的单个“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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 2011-05-23
      • 2011-05-23
      • 2010-09-30
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多