"Fossies" - the Fresh Open Source Software Archive

Member "roundup-2.0.0/roundup/cgi/PageTemplates/PageTemplate.py" (26 Aug 2019, 6792 Bytes) of package /linux/www/roundup-2.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "PageTemplate.py": 1.6.1_vs_2.0.0.

    1 ##############################################################################
    2 #
    3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
    4 #
    5 # This software is subject to the provisions of the Zope Public License,
    6 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
    7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
    8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
   10 # FOR A PARTICULAR PURPOSE
   11 #
   12 ##############################################################################
   13 # Modified for Roundup:
   14 # 
   15 # 1. changed imports to import from roundup.cgi
   16 # 2. removed use of ExtensionClass
   17 # 3. removed use of ComputedAttribute
   18 """Page Template module
   19 
   20 HTML- and XML-based template objects using TAL, TALES, and METAL.
   21 """
   22 
   23 import sys
   24 
   25 from roundup.cgi.TAL.TALParser import TALParser
   26 from roundup.cgi.TAL.HTMLTALParser import HTMLTALParser
   27 from roundup.cgi.TAL.TALGenerator import TALGenerator
   28 from roundup.cgi.TAL.TALInterpreter import TALInterpreter
   29 from .Expressions import getEngine
   30 from roundup.anypy.strings import StringIO
   31 
   32 
   33 class PageTemplate:
   34     "Page Templates using TAL, TALES, and METAL"
   35 
   36     content_type = 'text/html'
   37     expand = 0
   38     _v_errors = ()
   39     _v_warnings = ()
   40     _v_program = None
   41     _v_macros = None
   42     _v_cooked = 0
   43     id = '(unknown)'
   44     _text = ''
   45     _error_start = '<!-- Page Template Diagnostics'
   46 
   47     def StringIO(self):
   48         # Third-party products wishing to provide a full Unicode-aware
   49         # StringIO can do so by monkey-patching this method.
   50         return StringIO()
   51 
   52     def pt_edit(self, text, content_type):
   53         if content_type:
   54             self.content_type = str(content_type)
   55         if hasattr(text, 'read'):
   56             text = text.read()
   57         self.write(text)
   58 
   59     def pt_getContext(self):
   60         c = {'template': self,
   61              'options': {},
   62              'nothing': None,
   63              'request': None,
   64              'modules': ModuleImporter,
   65              }
   66         parent = getattr(self, 'aq_parent', None)
   67         if parent is not None:
   68             c['here'] = parent
   69             c['container'] = self.aq_inner.aq_parent
   70             while parent is not None:
   71                 self = parent
   72                 parent = getattr(self, 'aq_parent', None)
   73             c['root'] = self
   74         return c
   75 
   76     def pt_render(self, source=0, extra_context={}):
   77         """Render this Page Template"""
   78         if not self._v_cooked:
   79             self._cook()
   80 
   81         __traceback_supplement__ = (PageTemplateTracebackSupplement, self)
   82 
   83         if self._v_errors:
   84             raise PTRuntimeError('Page Template %s has errors.' % self.id)
   85         output = self.StringIO()
   86         c = self.pt_getContext()
   87         c.update(extra_context)
   88 
   89         TALInterpreter(self._v_program, self._v_macros,
   90                        getEngine().getContext(c),
   91                        output,
   92                        tal=not source, strictinsert=0)()
   93         return output.getvalue()
   94 
   95     def __call__(self, *args, **kwargs):
   96         if 'args' not in kwargs:
   97             kwargs['args'] = args
   98         return self.pt_render(extra_context={'options': kwargs})
   99 
  100     def pt_errors(self):
  101         if not self._v_cooked:
  102             self._cook()
  103         err = self._v_errors
  104         if err:
  105             return err
  106         if not self.expand: return
  107         try:
  108             self.pt_render(source=1)
  109         except:
  110             return ('Macro expansion failed', '%s: %s' % sys.exc_info()[:2])
  111 
  112     def pt_warnings(self):
  113         if not self._v_cooked:
  114             self._cook()
  115         return self._v_warnings
  116 
  117     def pt_macros(self):
  118         if not self._v_cooked:
  119             self._cook()
  120         __traceback_supplement__ = (PageTemplateTracebackSupplement, self)
  121         if self._v_errors:
  122             raise PTRuntimeError('Page Template %s has errors.' % self.id)
  123         return self._v_macros
  124 
  125     def __getattr__(self, name):
  126         if name == 'macros':
  127             return self.pt_macros()
  128         raise AttributeError(name)
  129 
  130     def pt_source_file(self):
  131         return None  # Unknown.
  132 
  133     def write(self, text):
  134         assert type(text) is type('')
  135         if text[:len(self._error_start)] == self._error_start:
  136             errend = text.find('-->')
  137             if errend >= 0:
  138                 text = text[errend + 4:]
  139         if self._text != text:
  140             self._text = text
  141         self._cook()
  142 
  143     def read(self):
  144         self._cook_check()
  145         if not self._v_errors:
  146             if not self.expand:
  147                 return self._text
  148             try:
  149                 return self.pt_render(source=1)
  150             except:
  151                 return ('%s\n Macro expansion failed\n %s\n-->\n%s' %
  152                         (self._error_start, "%s: %s" % sys.exc_info()[:2],
  153                          self._text) )
  154 
  155         return ('%s\n %s\n-->\n%s' % (self._error_start,
  156                                       '\n '.join(self._v_errors),
  157                                       self._text))
  158 
  159     def _cook_check(self):
  160         if not self._v_cooked:
  161             self._cook()
  162 
  163     def _cook(self):
  164         """Compile the TAL and METAL statments.
  165 
  166         Cooking must not fail due to compilation errors in templates.
  167         """
  168         source_file = self.pt_source_file()
  169         if self.html():
  170             gen = TALGenerator(getEngine(), xml=0, source_file=source_file)
  171             parser = HTMLTALParser(gen)
  172         else:
  173             gen = TALGenerator(getEngine(), source_file=source_file)
  174             parser = TALParser(gen)
  175 
  176         self._v_errors = ()
  177         try:
  178             parser.parseString(self._text)
  179             self._v_program, self._v_macros = parser.getCode()
  180         except:
  181             self._v_errors = ["Compilation failed",
  182                               "%s: %s" % sys.exc_info()[:2]]
  183         self._v_warnings = parser.getWarnings()
  184         self._v_cooked = 1
  185 
  186     def html(self):
  187         if not hasattr(getattr(self, 'aq_base', self), 'is_html'):
  188             return self.content_type == 'text/html'
  189         return self.is_html
  190 
  191 class _ModuleImporter:
  192     def __getitem__(self, module):
  193         mod = __import__(module)
  194         path = module.split('.')
  195         for name in path[1:]:
  196             mod = getattr(mod, name)
  197         return mod
  198 
  199 ModuleImporter = _ModuleImporter()
  200 
  201 class PTRuntimeError(RuntimeError):
  202     '''The Page Template has template errors that prevent it from rendering.'''
  203     pass
  204 
  205 
  206 class PageTemplateTracebackSupplement:
  207     #__implements__ = ITracebackSupplement
  208 
  209     def __init__(self, pt):
  210         self.object = pt
  211         w = pt.pt_warnings()
  212         e = pt.pt_errors()
  213         if e:
  214             w = list(w) + list(e)
  215         self.warnings = w
  216