source: products/vendor/Products.CacheSetup/current/Products/CacheSetup/patch_cmf.py @ 3296

Last change on this file since 3296 was 3296, checked in by fenix, 12 years ago

Load Products.CacheSetup?-1.2.1 into vendor/Products.CacheSetup?/current.

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1from Acquisition import aq_parent
2from Products.CMFCore.utils import getToolByName
3from Products.CacheSetup.config import log, CACHE_TOOL_ID, PLONE25
4from patch_utils import wrap_method, call_pattern
5from cmf_utils import _checkConditionalGET, _setCacheHeaders
6try:
7    from Products.PageTemplates.DeferExpr import LazyWrapper
8except:
9    LazyWrapper = None
10
11if PLONE25:
12    from StringIO import StringIO
13    from zope.app.publisher.interfaces.browser import IBrowserView
14else:
15    from Products.CMFPlone.patches.unicodehacks import FasterStringIO as StringIO
16    from zope.publisher.interfaces.browser import IBrowserView
17
18#### patch FSPageTemplate.pt_render
19
20# Goal: if a 304 can be determined, rendering the template is cut
21# off. Otherwise cache headers are set.
22
23from Products.CMFCore.FSPageTemplate import FSPageTemplate
24
25def FSPT_pt_render(self, source=0, extra_context={}):
26    pcs = getToolByName(self, CACHE_TOOL_ID, None)
27    # if portal_cache_settings not in place, fall back to the old method
28    if pcs is None or not pcs.getEnabled():
29        return call_pattern(self, 'pt_render', '__CacheSetup_FSPageTemplate_%s__', source, extra_context)
30
31    self._updateFromFS()  # Make sure the template has been loaded.
32
33    if not source:
34        request = self.REQUEST
35        object = self.getParentNode()
36        view = self.getId()
37        member = pcs.getMember()
38        (rule, header_set) = pcs.getRuleAndHeaderSet(request, object, view, member)
39        if header_set is not None:
40            expr_context = rule._getExpressionContext(request, object, view, member, keywords=extra_context)
41        else:
42            expr_context = None
43
44        # If we have a conditional get, set status 304 and return
45        # no content
46        if _checkConditionalGET(self, extra_context, rule, header_set, expr_context):
47            if PLONE25:
48                return ''
49            return u''
50
51    result = FSPageTemplate.inheritedAttribute('pt_render')(
52        self, source, extra_context
53        )
54    if not source:
55        _setCacheHeaders(self, extra_context, rule, header_set, expr_context)
56    return result
57
58#### patch PageTemplate.pt_render
59
60# Goal: actually set the 304 reponse header if applicable.
61
62from Products.PageTemplates.Expressions import getEngine
63if PLONE25:
64    from TAL.TALInterpreter import TALInterpreter
65    from Products.PageTemplates.PageTemplate import \
66        PageTemplateTracebackSupplement, PTRuntimeError
67else:
68    from zope.tal.talinterpreter import TALInterpreter
69    from zope.pagetemplate.pagetemplate import \
70        PageTemplateTracebackSupplement, PTRuntimeError
71
72def PT_pt_render(self, source=0, extra_context={}):
73    """Render this Page Template"""
74    pcs = getToolByName(self, CACHE_TOOL_ID, None)
75    # if portal_cache_settings not in place, fall back to the old method
76    if pcs is None or not pcs.getEnabled():
77        return call_pattern(self, 'pt_render', '__CacheSetup_PageTemplate_%s__', source, extra_context)
78
79    if not self._v_cooked:
80        self._cook()
81    __traceback_supplement__ = (PageTemplateTracebackSupplement, self, self.pt_getContext())
82
83    if self._v_errors:
84        e = str(self._v_errors)
85        raise PTRuntimeError, (
86            'Page Template %s has errors: %s' % (self.id, e))
87
88    if not source:
89        # If we have a conditional get, set status 304 and return no
90        # content
91        request = self.REQUEST
92        object = self.getParentNode()
93       
94        # we may get this if we have a Zope 3 browser view
95        if IBrowserView.providedBy(object):
96            view = getattr(object, '__name__', request['ACTUAL_URL'].split('/')[-1])
97            object = aq_parent(object)
98        else:
99            view = self.getId()
100        view = str(view)
101       
102        member = pcs.getMember()
103        (rule, header_set) = pcs.getRuleAndHeaderSet(request, object, view, member)
104        if header_set is not None:
105            expr_context = rule._getExpressionContext(request, object, view, member, keywords=extra_context)
106        else:
107            expr_context = None
108
109        if _checkConditionalGET(self, extra_context, rule, header_set, expr_context):
110            if PLONE25:
111                return ''
112            return u''
113       
114    if PLONE25:
115        output = self.StringIO()
116    else:
117        output = StringIO(u'')
118
119    c = self.pt_getContext()
120    c.update(extra_context)
121
122    context = getEngine().getContext(c)
123    TALInterpreter(self._v_program, self._v_macros,
124                   context,
125                   output,
126                   tal=not source, strictinsert=0)()
127
128    # The following looks like it was left over from when we still did macro caching
129    # I'm commenting it out for now as I don't think we do lazy expressions in cachefu anymore
130    #
131    ##clean up - XXX
132    ## try to eliminate circular references - this may be overkill
133    #if LazyWrapper is not None:
134    #    context._compiler = None
135    #    context.contexts = None
136    #    context.repeat_vars = None
137    #    if PLONE25:
138    #        items = context.global_vars.items()
139    #    else:
140    #        items = context.vars.items()
141    #    for k,v in items:
142    #        if isinstance(v, LazyWrapper):
143    #            v._expr = None
144    #            v._econtext = None
145    #            v._result = None
146    #    if PLONE25:
147    #        if context.vars:
148    #            while len(context.vars):
149    #                context.vars._pop()
150    #        context.global_vars.clear()
151    #        context.global_vars = None
152    #        context.local_vars.clear()
153    #        context.local_vars = None
154    #    else:
155    #        context.vars.clear()
156    #    context.vars = None
157    #    context._scope_stack = None
158
159    result = output.getvalue()
160    if not source:
161        _setCacheHeaders(self, extra_context, rule, header_set, expr_context)
162    return result
163
164
165def run():
166    log('Applying CMF patches...')
167    from Products.PageTemplates.PageTemplate import PageTemplate
168    wrap_method(PageTemplate, 'pt_render', PT_pt_render, '__CacheSetup_PageTemplate_%s__')
169    from Products.CMFCore.FSPageTemplate import FSPageTemplate
170    wrap_method(FSPageTemplate, 'pt_render', FSPT_pt_render, '__CacheSetup_FSPageTemplate_%s__')
171    log('CMF Patches applied.')
172
Note: See TracBrowser for help on using the repository browser.