python下如何让web元素的生成更简单的分析


Posted in Python onJuly 17, 2008

1. 引用css。这可能是最常见的做法了,对一些特定的元素定义特定的样式。那么使用它,你需要在HTML
页面中加入<link>标签。
2. 引入js。许多特效也可以通过javascript来进行处理,比如动态显示效果,或对元素进行封装。使用
它你需要在HTML页面加入<script>标签,必要时还要加一些javascript代码。
3. HTML元素。需要设定一些特殊的属性,比如class=某个属性。这块还相对简单。

因此从上面的分析可以看出,在通常情况下,加入一个好看的web元素可能到许多地方的修改。因此我一
直在思考如何让这个过程可以更简化,麻烦的地方就是如何处理这些资源,如何让这些资源可以与原始的
HTML很好的结合呢?最终我想出的办法就是:代码组装。

对于css, javascript链接和代码,它们可以按调用的顺序依次拼成一段文本,然后插入到</head>元素前
面。然后对于html代码,在模板中直接输出。对于css, javascript的链接可以检查是否重复。

那么如何定义web元素类和如何在模板中对其进行处理?

一个web元素类定义如下:

class Snippet(object):
    css = ''
    csslink = ''
    jslink = ''
    html = ''
    js = ''

    def render(self):
        return ''

    def __str__(self):
        return self.render()

定义为类属性的将输出到HTML的头部,而render()的结果将显示在模板中调用类的地方。先看一下在模板
中调用的示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML Helper</title>
<script type="text/javascript" src="/static/js/jquery.js"></script>
</head>
<body>
{{
htmlbuf << htmlwidgets.Message('This is a test')
}}
</body>
</html>

这里你可以看到htmlbuf,它是什么,它就是用来采集每个Snippet类的类属性的。这里使用<<来将一个
Snippet对象加到htmlbuf中去。同时它还会将Snippet的HTML代码在调用位置输出。

如何输出?首先uliweb的模板将转为python代码,它有一个内置的out对象,可以调用它的方法来输出
HTML代码。那么htmlbuf对象将在调用模板前被创建,在调用模板后被处理,在创建时将传入out的write
属性。这一切都是在SImpleFrame.py中通过plugin方法来实现的,但是这只是定义了一个调用点,如:

fname, code = template.render_file(filename, vars, env, dirs)
out = template.Out()
template._prepare_run(vars, env, out)
callplugin(self, 'before_render_template', env, out)

if isinstance(code, (str, unicode)):
    code = compile(code, fname, 'exec')
exec code in env, vars
text = out.getvalue()
output = execplugin(self, 'after_render_template', text, vars, env)

before_render_template 会在调用模板前被调用。after_render_template 会在调用模板后被调用。因
此你可以通过plugin机制来加入额外的处理。这是在settings.py中定义的,如:

@plugin('before_render_template')
def before_render_template(sender, env, out):
    from uliweb.core import js
    from uliweb.core.SimpleFrame import url_for
    from uliweb.helpers import htmlwidgets

    htmlbuf = js.HtmlBuf(write=out.noescape, static_suffix=url_for('Portal.views.static', 
filename=''))
    env['htmlbuf'] = htmlbuf
    env['htmlwidgets'] = htmlwidgets

这里注入htmlbuf和htmlwidgets到模板的env环境中,所以可以在模板中直接使用。在htmlwidgets中已经
定义了一些Snippet。htmlbuf在创建时,会使用out.noescape方法,它将不会对Snippet中的代码进行转
义。static_suffix表示静态文件的前缀,缺省为/static/,这里由于使用了静态服务,所以通过url_for
来得到静态URL前缀。

@plugin('after_render_template')
def after_render_template(sender, text, vars, env):
    import re
    r_links = re.compile('<link\s.*?\shref\s*=\s*"?(.*?)["\s>]|<script\s.*?\ssrc\s*=\s*"?
(.*?)["\s>]', re.I)
    if 'htmlbuf' in env:
        htmlbuf = env['htmlbuf']
        if htmlbuf.modified:
            b = re.search('(?i)</head>', text)
            if b:
                pos = b.start()
                #find links
                links = [x or y for x, y in r_links.findall(text[:pos])]
                htmlbuf.remove_links(links)
                t = htmlbuf.render()
                if t:
                    return ''.join([text[:pos], t, text[pos:]])
            else:
                return t+text
    return text

这里将在模板处理完毕后查找生成的HTML文本中的</head>标签,然后将相应的信息插入到它的前面。同
时这里增加了对原HTML中已经存在的链接进行了判断,如果存在则删除之,这是通过remove_links来处理
的。

经过这些的处理,你只要定义一个Snippet,Uliweb将自动为你处理css, js的链接包括代码,和HTML代码
的生成。因此你就可以简单的:

{{
htmlbuf << htmlwidgets.Message('This is a test')
}}

来生成一个消息的提示信息。

我会慢慢扩展这个htmlwidgets库。

再简单描述一下如何配置:

1. 在settings.py中

INSTALLED_APPS = ['Documents', 'Examples', 'Portal', 'Post', 
    'uliweb.builtins.auth', 'uliweb.helpers.htmlwidgets']

这里要加入'uliweb.helpers.htmlwidgets',让static目录生效

2. 加入:

@plugin('before_render_template')
def before_render_template(sender, env, out):

@plugin('after_render_template')
def after_render_template(sender, text, vars, env):

3. 可以使用了。 

Python 相关文章推荐
python基础教程之基本数据类型和变量声明介绍
Aug 29 Python
python使用socket创建tcp服务器和客户端
Apr 12 Python
解决pip install xxx报错SyntaxError: invalid syntax的问题
Nov 30 Python
Django为窗体加上防机器人的验证码功能过程解析
Aug 14 Python
postman传递当前时间戳实例详解
Sep 14 Python
Python使用turtle库绘制小猪佩奇(实例代码)
Jan 16 Python
pymysql 插入数据 转义处理方式
Mar 02 Python
浅析Python 条件控制语句
Jul 15 Python
详解tensorflow之过拟合问题实战
Nov 01 Python
如何基于Python pygame实现动画跑马灯
Nov 18 Python
Pytorch - TORCH.NN.INIT 参数初始化的操作
Feb 27 Python
Python基于百度AI实现抓取表情包
Jun 27 Python
py中的目录与文件判别代码
Jul 16 #Python
Python Mysql自动备份脚本
Jul 14 #Python
python远程登录代码
Apr 29 #Python
复制粘贴功能的Python程序
Apr 04 #Python
推荐下python/ironpython:从入门到精通
Oct 02 #Python
在漏洞利用Python代码真的很爽
Aug 26 #Python
python编程-将Python程序转化为可执行程序[整理]
Apr 09 #Python
You might like
随时给自己贴的图片加文字的php代码
2007/03/08 PHP
PHP中集成PayPal标准支付的实现方法分享
2012/02/06 PHP
PHP中fwrite与file_put_contents性能测试代码
2013/08/02 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
jquery $.ajax入门应用二
2008/11/19 Javascript
javascript 页面只自动刷新一次
2009/07/10 Javascript
IE图片缓存document.execCommand(&quot;BackgroundImageCache&quot;,false,true)
2011/03/01 Javascript
基于jquery中children()与find()的区别介绍
2013/04/26 Javascript
jquery遍历数组与筛选数组的方法
2013/11/05 Javascript
点击按钮出现60秒倒计时的简单js代码(推荐)
2016/06/07 Javascript
AngularJS服务service用法总结
2016/12/13 Javascript
jQuery表格的维护和删除操作
2017/02/03 Javascript
实现div内部滚动条滚动到底部和顶部的代码
2017/11/15 Javascript
使用 Vue 绑定单个或多个 Class 名的实例代码
2018/01/08 Javascript
JS中Promise函数then的奥秘探究
2018/07/30 Javascript
opencv 识别微信登录验证滑动块位置
2018/08/07 Javascript
详解vue中的computed的this指向问题
2018/12/05 Javascript
ES6基础之字符串和函数的拓展详解
2019/08/22 Javascript
element-ui table行点击获取行索引(index)并利用索引更换行顺序
2020/02/27 Javascript
[01:22:42]2014 DOTA2华西杯精英邀请赛 5 24 DK VS LGD
2014/05/26 DOTA
pycharm 使用心得(七)一些实用功能介绍
2014/06/06 Python
Python操作mongodb数据库进行模糊查询操作示例
2018/06/09 Python
pyqt5的QComboBox 使用模板的具体方法
2018/09/06 Python
Python实现判断一个整数是否为回文数算法示例
2019/03/02 Python
Django路由层URLconf作用及原理解析
2020/09/24 Python
css3实现3D文本悬停改变效果的示例代码
2019/01/16 HTML / CSS
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
英国门销售网站:Green Tree Doors
2020/01/07 全球购物
小学少先队活动方案
2014/02/18 职场文书
《谁的本领大》教后反思
2014/04/25 职场文书
化工操作工岗位职责
2014/04/29 职场文书
世界水日宣传活动总结
2015/02/09 职场文书
中学感恩教育活动总结
2015/05/05 职场文书
借钱欠条怎么写
2015/07/03 职场文书
Go 语言下基于Redis分布式锁的实现方式
2021/06/28 Golang