Added templetor support to page creator
[kisspi.git] / kisspi.py
1 # -*- coding: utf-8 -*-
2
3 '''
4 kisspi module gives some tools that make easy to create a module and
5 manage modules inside kisspi cms.
6 '''
7
8 import os
9 import sys
10 import re
11 import web
12 import utils
13 import kisspidb as db
14
15 MODULES = {}
16 THEME = 'default'
17 DEFAULT_TITLE = 'KISSpi CMS'
18
19 def load_modules(path='modules'):
20     '''
21     Loads all modules in a global dict called MODULES, keys are names
22     and values are the imported module.
23     '''
24
25     global MODULES
26     sys.path += [path]
27     modules = os.listdir(path)
28     MODULES = dict([(i, __import__(i)) for i in modules if\
29         os.path.isdir(os.path.join(os.path.abspath('modules'), i))])
30
31     return MODULES
32
33 def parse_url(module, path):
34     '''
35     Checks a module url and returns the associated function to it. If
36     that path isn't specificated in module.urls returns None, None.
37     '''
38
39     for url, function in module.urls:
40         match = re.match(url+'$', path)
41         if match:
42             return function(), match.groups()
43     return None, None
44
45 def template(title='', body='', path='', method='GET'):
46     '''
47     Put the layaout and fill all parts with configfile, returns the
48     html code to show.
49     If not body is specified use default.
50     '''
51
52     head, pre_body, post_body, left, foot = 'head', 'pre-body', 'post-body', 'left', 'foot'
53     default_modules = modconf()
54
55     head = parse_layaout(default_modules['head'], path)
56     pre_body = parse_layaout(default_modules['pre_body'], path)
57     post_body = parse_layaout(default_modules['post_body'], path)
58     left = parse_layaout(default_modules['left'], path)
59     foot = parse_layaout(default_modules['foot'], path)
60     if not body:
61         body = parse_layaout(default_modules['default'], path)
62         title = DEFAULT_TITLE
63
64     render = get_render()
65     e = utils.get_err()
66     m = utils.get_msg()
67
68     globals = {'listdir': os.listdir}
69     render = web.template.render('static/themes/'+THEME+'/templates',
70             globals=globals)
71
72     return render.master(title, head, pre_body, body, post_body, left,
73             foot, errors=e, msgs=m)
74
75 def parse_layaout(args, real_path):
76     '''
77     template auxiliar function.
78
79     args is a pair list with the modpath as first item and the expr
80     that represent in witch pages it's shows that module.
81
82     real_path is the url path that it's visited now.
83
84     Returns the html code returned by all modules in args joined
85     '''
86
87     # The html of all modules of this layaout part
88     to_ret = ''
89     for modpath, real_path_expr in args:
90         match = re.match(real_path_expr+'$', real_path)
91         # Check if we wan't show that module
92         if match:
93             mod_name = modpath.split('/')[0]
94             path = '/'.join(modpath.split('/')[1:])
95             mod = MODULES[mod_name]
96             # Getting the module class to call
97             f, fargs = parse_url(mod, path)
98             function = f.GET
99             # Calling the module
100             returned = function(*fargs)
101             to_ret += returned
102     return to_ret
103
104 def modconf(file='modules/modconf'):
105     '''
106     Load a modules conf file.
107
108     Returns a dict with head, pre_body, post_body, ... with a list as
109     values. Each item in that list is a pair with module path and a
110     regular expresion that says where that module need to be shown.
111     '''
112
113     # TODO cache that
114     lines = open(file).readlines()
115     default_modules = {'head': [], 'pre_body': [], 'post_body': [],
116             'foot': [], 'left': [], 'default': []}
117
118     for line in lines:
119         # Ignoring comments
120         if line.strip().startswith('#'):
121             continue
122         
123         try:
124             layaout, module, path = line.split()
125         except ValueError:
126             # blank line
127             continue
128
129         default_modules[layaout].append((module, path))
130
131     return default_modules
132         
133
134 #########################################
135 # MODULE HELP FUNCTIONS                 #
136 #########################################
137
138 def get_session():
139     return web.ses
140
141 def get_input(**args):
142     return web.input(**args)
143
144 def redirect(path):
145     raise web.seeother(path)
146
147 def get_render():
148     return web.template.render('static/themes/'+THEME+'/templates')
149
150 def get_module_render(module):
151     return web.template.render('modules/'+module+'/templates')
152
153 def get_module_path(module):
154     return 'modules/'+module+'/'
155
156 websafe = web.net.websafe