__init__.py :  » Web-Server » Jon-Python » jonpy-0.08 » jon » wt » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Server » Jon Python 
Jon Python » jonpy 0.08 » jon » wt » __init__.py
# $Id: __init__.py,v 1.21 2010/03/20 18:29:22 jribbens Exp $

"""Web Template system"""

import sys, os, re
import jon.cgi as cgi


_code_cache = {}

_replace_validchunk = re.compile("^[A-Za-z0-9_]+$")

def replace(wt, template, namespace):
  """Substitute variables in template and output with jcgi.write

  Variables are indicated by surrounding them with "$$".
  If the name is suffixed with "()" then it must be a function not a variable.
  The default encoding is to call jcgi.html_encode
    unless the variable is prefixed with "%" in which case it is jcgi.url_encode
    or the variable is prefixed with "=" in which case no encoding is used.
  If the variable is empty (i.e. the template contains "$$$$") then a literal
  "$$" is output.
  """
  html = 0
  for chunk in template.split("$$"):
    html = not html
    if html:
      wt.req.write(chunk)
    else:
      if chunk == "":
        wt.req.write("$$")
      else:
        encode = cgi.html_encode
        if chunk[0] == "=":
          encode = lambda x: x
          chunk = chunk[1:]
        elif chunk[0] == "%":
          encode = cgi.url_encode
          chunk = chunk[1:]
        if not _replace_validchunk.match(chunk):
          raise ValueError("'%s' is not a valid identifier" % chunk)
        if callable(getattr(namespace, chunk)):
          out = getattr(namespace, chunk)()
        else:
          out = getattr(namespace, chunk)
        if not isinstance(out, unicode):
          out = str(out)
        wt.req.write(encode(out))


class TemplateCode(object):
  template_as_file = 0

  def __init__(self, outer, wt=None):
    self.outer = outer
    if wt:
      self.wt = wt
    else:
      self.wt = self.outer.wt
    self.req = self.wt.req

  def process(self, template, selected=None):
    process(self.wt, template, self, selected)

  def main(self, template):
    self.process(template)


class GlobalTemplate(TemplateCode):
  def main(self, template):
    self._pageTemplate = template
    if hasattr(self, "get_template"):
      self.process(self.get_template())
    else:
      if self.template_as_file:
        self.process(open(self.template_name(), "rb"))
      else:
        encoding = self.wt.get_template_encoding()
        if encoding is None:
          self.process(open(self.template_name(), "rb").read())
        else:
          self.process(unicode(open(self.template_name(), "rb").read(),
            encoding))

  def template_name(self):
    return self.wt.etc + "/template.html"

  class page(TemplateCode):
    pass

  class _page(TemplateCode):
    def main(self, template):
      # Contents of the page block are ignored, the original template
      # is substituted instead
      obj = self.outer.page(self.outer)
      if obj.template_as_file:
        import StringIO as cStringIO
        obj.main(StringIO.StringIO(self.outer._pageTemplate))
      else:
        obj.main(self.outer._pageTemplate)


_process_sb = re.compile("<!--wt:([A-Za-z0-9_]+)(/)?-->")

def process(wt, template, namespace, selected=None):
  pos = 0
  while 1:
    start = _process_sb.search(template, pos)
    if not start:
      break
    name = start.group(1)
    if start.lastindex == 2: # shorttag
      end = start.end()
      endmark = ""
    else:
      endmark = "<!--wt:/%s-->" % name
      end = template.find(endmark, start.end())
      if end == -1:
        raise ValueError("No end block for %s" % name)
    replace(wt, template[pos:start.start()], namespace)
    if name != "_null" and (selected == None or selected == name or
      (type(selected) == type([]) and name in selected) or
      (type(selected) == type(()) and name in selected)):
      obj = getattr(namespace, name)(namespace, wt)
      if obj.template_as_file:
        import cStringIO as StringIO
        obj.main(StringIO.StringIO(template[start.end():end]))
      else:
        obj.main(template[start.end():end])
      del obj
    pos = end + len(endmark)
  replace(wt, template[pos:], namespace)


class Handler(cgi.Handler):
  cache_code = 0

  def _get_template(self):
    for i in range(4):
      template = self.req.environ.get("REDIRECT_" * i + "WT_TEMPLATE_FILENAME")
      if template:
        return template
    raise Exception("Couldn't determine template filename")

  def _get_etc(self):
    sp = os.path.split(self.req.environ["DOCUMENT_ROOT"])
    if sp[1] == "":
      sp = os.path.split(sp[0])
    return sp[0] + "/etc"

  def _get_code(self):
    code = self.req.environ.get("PATH_TRANSLATED")
    if code is None:
      code = self.req.environ["SCRIPT_FILENAME"]
    return code

  def get_template_encoding(self):
    return None

  def pre_load(self):
    pass

  def pre_request(self, obj):
    pass

  def post_request(self, obj):
    pass

  def process(self, req):
    self.req = req
    self.etc = self._get_etc()
    self.pre_load()
    self.template = self._get_template()
    codefname = self._get_code()
    try:
      namespace = _code_cache[codefname]
    except KeyError:
      namespace = { "wt": sys.modules[__name__] }
      code = compile(open(codefname, "r").read(), codefname, "exec")
      exec code in namespace
      del code
      if self.cache_code:
        _code_cache[codefname] = namespace
    obj = namespace["main"](None, self)
    self.pre_request(obj)
    if obj.template_as_file:
      obj.main(open(self.template, "rb"))
    else:
      encoding = self.get_template_encoding()
      if encoding is None:
        obj.main(open(self.template, "rb").read())
      else:
        obj.main(unicode(open(self.template, "rb").read(), encoding))
    self.post_request(obj)


class DebugHandler(cgi.DebugHandlerMixIn, Handler):
  pass
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.