class MalformedTemplateError(Exception): pass def templateItem(channel, item, itemTemplate): """ Returns itemTemplate replaced with content from channel and item dictionaries. itemTemplate should have variables of the form $channel_variable and $variable, which will be replaced with appropriate content from channel and item respectively. The template may also contain conditional statements: $if_variable some content with $variable in it $else_variable some other content $endif_variable If a $variable is not present, it is replaced with the empty string. The $if construction is so you wont get comments when $comments is not defined. """ tbits = [] class Allow(object): def __init__(self, parent=None): self.parent = parent def __call__(self, msg): if self.parent: self.parent(msg) else: tbits.append(msg) class Disallow(object): def __init__(self, parent=None): self.parent = parent def __call__(self, msg): pass appender = Allow() tbitsIn = itemTemplate.split('$') appender(tbitsIn[0]) del tbitsIn[0] for t in tbitsIn: cmdMO = re.search(r"^\w+", t) if not cmdMO: raise MalformedTemplateError("'$' followed by non-word character") cmd = cmdMO.group(0) if cmd == 'endif': if None == appender.parent: raise MalformedTemplateError("$endif without $if") appender = appender.parent appender(t[5:]) continue # next t if cmd == 'else': if None == appender.parent: raise MalformedTemplateError("$else without $if") if Allow == type(appender): newtype = Disallow else: newtype = Allow appender = newtype(appender.parent) appender(t[4:]) continue # next t if cmd == 'if': cmdMO = re.match(re.compile(r"if\s+(\w+)(.*)", re.DOTALL), t) if not cmdMO: raise MalformedTemplateError("Malformed $if") var = cmdMO.group(1) content = cmdMO.group(2) val = None if var.startswith('channel_'): val = channel.get(var[8:], None) else: val = item.get(var, None) if val: appender = Allow(appender) else: appender = Disallow(appender) appender(content) continue content = '' if cmd.startswith('channel_'): content = channel.get(cmd[8:], '') else: content = item.get(cmd, '') appender(content) appender(t[len(cmd):]) return "".join(tbits)