金字塔和变色龙中的ajax小部件
我希望能够在服务器端轻松创建由变色龙和金字塔支持的ajax“小部件”。
Pyramid 是否提供任何可以使编写小部件变得容易的管道代码?
我当前的方法是我有一个使用 home.pt 作为渲染器的主视图。 home.pt 使用宏 base.pt 定义页面结构并为 home.pt 提供填充槽。 base.pt 还使用我编写的登录“widget”宏(请参阅下面的 account_login_widget.pt)。
从理论上讲,这一切听起来都很棒...我有一个可在许多页面中使用的可重用登录小部件,但我当前的方法效果不佳。我的登录小部件在其渲染器中使用 ${username} 等变量(服务器需要定义)。我希望登录小部件及其渲染尽可能独立。但按照我目前的做法,主视图代码需要了解登录小部件的需求,并在字典中提供用户名、formrender 和其他变量。绝对不好...
我觉得我已经接近正确的想法,但缺少一些东西...
有什么想法吗?
base.pt:
<html>
<head></head>
<body>
<div id="container">
<div id="header">
<span metal:use-macro="load: account_login_widget.pt"></span>
</div>
<div id="middle">
<span metal:define-slot="content"></span>
</div>
<div id="footer"></div>
</div>
</body>
</html>
home.pt:
<div metal:use-macro="load: base.pt">
<span metal:fill-slot="content">
<div>my stuff</div>
</span>
</div>
account_login_widget.pt:
<span metal:define-macro="account_login_widget">
<script type="text/javascript">
(function($) {
$.fn.my_function = function() {
$('#login_form').submit(function(e) {
e.preventDefault();
// ajax call
$.post(some_url, some_data, function(response) {
$('#account_login_widget').html(response);
});
};
return this;
};
})(jQuery);
// Define the entry point
$(document).ready(function() {
$(document).my_function();
});
</script>
<div id="account_login_widget">
<div id="login_bar" tal:condition="not username">
${form_renderer.begin(...)}
... my form ...
${form_renderer.end()}
<span tal:condition="login_failed">Login failed</span>
<div id="forgot_password_link"><a href="#">Forgot Password?</a></div>
<div id="create_account_link"><a href="${signup_url}">Create Account</a></div>
</div>
<div tal:condition="username">
Welcome <strong>${username}</strong>! <a href="${logout_url}">Logout</a>
</div>
</div>
</span>
I would like to be able to easily create ajax 'widgets' backed by chameleon and pyramid on the server side.
Does Pyramid provide any plumbing code that would make writing widgets easy?
My current approach is I have a home view which uses home.pt as the renderer. home.pt uses a macro base.pt which defines the page structure and provides a slot for home.pt to fill. base.pt also uses a login 'widget' macro that I have written (see: account_login_widget.pt below).
In theory, this all sounds great...I have a reusable login widget that I can use in many pages, but my current approach doesn't work very well. My login widget uses variables like ${username} in its renderer (which the server needs to define). I want the login widget and its rendering to be as independent as possible. But with my current way of doing things, the home view code needs to be aware of the login widget's needs and provide username, formrender and other variables in the dictionary. Definitely not good...
I feel like I'm close to the right idea, but missing some things...
Any thoughts?
base.pt:
<html>
<head></head>
<body>
<div id="container">
<div id="header">
<span metal:use-macro="load: account_login_widget.pt"></span>
</div>
<div id="middle">
<span metal:define-slot="content"></span>
</div>
<div id="footer"></div>
</div>
</body>
</html>
home.pt:
<div metal:use-macro="load: base.pt">
<span metal:fill-slot="content">
<div>my stuff</div>
</span>
</div>
account_login_widget.pt:
<span metal:define-macro="account_login_widget">
<script type="text/javascript">
(function($) {
$.fn.my_function = function() {
$('#login_form').submit(function(e) {
e.preventDefault();
// ajax call
$.post(some_url, some_data, function(response) {
$('#account_login_widget').html(response);
});
};
return this;
};
})(jQuery);
// Define the entry point
$(document).ready(function() {
$(document).my_function();
});
</script>
<div id="account_login_widget">
<div id="login_bar" tal:condition="not username">
${form_renderer.begin(...)}
... my form ...
${form_renderer.end()}
<span tal:condition="login_failed">Login failed</span>
<div id="forgot_password_link"><a href="#">Forgot Password?</a></div>
<div id="create_account_link"><a href="${signup_url}">Create Account</a></div>
</div>
<div tal:condition="username">
Welcome <strong>${username}</strong>! <a href="${logout_url}">Logout</a>
</div>
</div>
</span>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
处理此问题的一个好方法是将您的 account_login_widget 与其自己的视图相关联,例如:
然后您应该能够访问 http://yourapp /login_widget 并仅返回小部件的 HTML。
剩下要做的就是调用视图并将生成的 HTML 包含在模板中。也就是说,
您需要的不是:
render_view
但模板中不存在;您必须自己提供。为此,最好使用渲染前事件: http: //docs.pylonsproject.org/projects/pyramid/dev/narr/hooks.html#beforerender-event完成。如果您需要通过 AJAX 动态(重新)加载小部件,此方法也会有所帮助。
A good way of dealing with this is to associate your account_login_widget with its own view, like:
You should then be able to visit http://yourapp/login_widget and get back only the widget's HTML.
What's left to do is to call the view and include the resulting HTML in your template. That is, instead of:
you'll want something like:
render_view
however doesn't exist in templates; you'll have to provide it yourself. It's best to use the Before Render Event for this: http://docs.pylonsproject.org/projects/pyramid/dev/narr/hooks.html#beforerender-eventDone. This approach will also help should you ever need to (re)load widgets dynamically through AJAX.