经过几天的思考和努力,在uliweb中实现了一个theme的支持,目录这个theme功能并不在uliweb的核心代码中,而是在uliweb-tests中。
1. 支持对静态文件的theme功能。即通过url_for_static()函数,向其传入theme=True,这样可以对要处理的静态文件,生成形如:/{static_url}/{theme_path}/{filename}的内容。而theme_path是在settings.ini中的一个配置,示例:
[THEME]
current = 'blue'
[THEME_DEFINE]
black = 'themes/black'
blue = 'themes/blue'
THEME_DEFINE中定义了所有可用的theme,一个theme一行。象上面black是theme的名字,后面是theme路径。
在THEME中定义了当前使用的theme的名字。
所以在url_static_for()中使用的是theme的名字。uliweb在处理时会自动从配置文件中找到这个名字对应的路径,然后添加到theme_path中。如果找不到,则theme_path段不出现。
这样,如果那个静态文件是设计成theme方式的,可以通过在url_for_static(theme=True)来激活。同时还要添加THEME和THEME_DEFINE中的相关的配置。
2. 静态文件的处理
上面的url_for_static()中解决了url的生成,它只是简单的生成包含了theme_path的URL,并不会检查真正是否存在对应的一个物理文件。在最早的想法,我是希望可以自适应的。也就是,如果找不到会自动查找缺省目录下的文件。但是存在一些问题。如果静态文件的处理就是使用了uliweb提供的,那么,这个文件是否存在的确是可以判断的。但是URL的生成与真正的文件的服务其实是在两个过程中实现的,因此必然在生成URL的时候也要进行文件的检查,这样会影响一定的效率。如果静态文件不是使用uliweb提供的,那么静态文件的处理可能是交给web server来做的,甚至有可能在不同的机器上,判断文件是否存在就成为问题。因此只能做了简单的处理:URL生成不检查文件是否存在。所以后面在静态文件处理时,也不会当文件找不到使用缺省文件进行处理。
这里的确失去了一些自动性。也因此要求使用theme时,静态文件一定都要是完整的,不要有缺失的文件。一个做法就是:在生成某个theme时,将相关的所有文件先全部复制,然后再修改其中的内容。这样就不会少文件了。
3. 模板的处理
上面只解决了静态文件的处理。但是有可能模板也存在相同的问题。那么一旦启用theme这个app连带着对所有的模板的处理都加上了theme的支持。这一点与静态文件不一致。静态文件是要通过调用url_for_static(theme=True)来处理某个具体的文件。而模板则是没有特别的设定,并且是对所有的模板调用生效。要注意的是,这个模板的处理是指在调用Dispatch.template()时起的作用。不直接或间接使用这个函数来处理的模板,是无法得到theme支持的。而Dispatch.template()在uliweb自动套用view模板时会调用,因此所有的view函数会自动得到theme的支持。
那么它的处理机制就是在真正调用template模块前,将theme路径与原搜索模板路径进行了处理,将合成后的theme的路径放在前面,原模板路径放在后面。这样保证先搜索theme路径,再搜索原模板路径。因此当找不到对应的theme模板时是会调用原模板的。因此当theme模板文件不存在也没有关系。这一点与静态文件也是不同的。
因为这个theme刚做出来,所以处理方式也没有定型。但是对于静态文件的处理基本定型,剩下就是对模板的处理,可能有多种模式。因此这块是可以扩展和完善的。甚至包括未来theme与用户的关联。
这个示例已经在uliweb-tests中了,有兴趣可以试一试。示例很简单,就是有两个theme,背景色不同而已。通过修改THEME/current的值可以看到背景色的变化。
暂时没有评论