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 布尔操作实现代码
Mar 23 Python
十个Python程序员易犯的错误
Dec 15 Python
对python3 一组数值的归一化处理方法详解
Jul 11 Python
Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法
Apr 18 Python
处理python中多线程与多进程中的数据共享问题
Jul 28 Python
python3 Scrapy爬虫框架ip代理配置的方法
Jan 17 Python
深入了解python列表(LIST)
Jun 08 Python
详细分析Python collections工具库
Jul 16 Python
安装pyecharts1.8.0版本后导入pyecharts模块绘图时报错: “所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置 ”的解决方法
Aug 18 Python
Python和Bash结合在一起的方法
Nov 13 Python
Python爬虫教程之利用正则表达式匹配网页内容
Dec 08 Python
python函数的两种嵌套方法使用
Apr 02 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
造就帕卡马拉的帕卡斯是怎么被发现的
2021/03/03 咖啡文化
php录入页面中动态从数据库中提取数据的实现
2006/10/09 PHP
php5.2.0内存管理改进
2007/01/22 PHP
PHP统一页面编码避免乱码问题
2015/04/09 PHP
jquery Validation表单验证使用详解
2020/09/12 Javascript
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
Jquery插件之Fancybox丰富的弹出层效果附源码下载
2015/12/02 Javascript
JavaScript中eval()函数用法详解
2015/12/14 Javascript
分享一个原生的JavaScript拖动方法
2016/09/25 Javascript
vue-router 学习快速入门
2017/03/01 Javascript
vuejs父子组件之间数据交互详解
2017/08/09 Javascript
Three.js基础学习教程
2017/11/16 Javascript
在Vue中使用axios请求拦截的实现方法
2018/10/25 Javascript
Vue.js 中的实用工具方法【推荐】
2019/07/04 Javascript
微信小程序 scroll-view的使用案例代码详解
2020/06/11 Javascript
解决vue的router组件component在import时不能使用变量问题
2020/07/26 Javascript
利用JavaScript模拟京东按键输入功能
2020/12/01 Javascript
[14:24]Optic Gaming vs PSG LGD BO3
2018/06/07 DOTA
Python生成随机数组的方法小结
2017/04/15 Python
Python 统计字数的思路详解
2018/05/08 Python
python绘图pyecharts+pandas的使用详解
2020/12/13 Python
巧用CSS3 border实现图片遮罩效果代码
2012/04/09 HTML / CSS
HTML5中在title标题标签里设置小图标的方法
2020/06/23 HTML / CSS
Order by的几种用法
2013/06/16 面试题
建筑学推荐信
2013/11/03 职场文书
工程造价与管理专业应届生求职信
2013/11/23 职场文书
木工主管岗位职责
2013/12/08 职场文书
《莫高窟》教学反思
2014/02/25 职场文书
环保公益广告语
2014/03/13 职场文书
村委会贫困证明范本
2014/09/17 职场文书
幼儿园教师求职信
2015/03/20 职场文书
2015年机关党委工作总结
2015/05/23 职场文书
2015年英语教学工作总结
2015/05/25 职场文书
学校少先队工作总结
2015/08/12 职场文书
劳动合同变更协议书范本
2019/04/18 职场文书
详解OpenCV获取高动态范围(HDR)成像
2022/04/29 Python