[Checkins] SVN: z3c.cssresource/trunk/src/z3c/cssresource/ Totally
reimplemented this code and gave it a different name. Now we
Stephan Richter
srichter at cosmos.phy.tufts.edu
Tue Aug 15 11:57:07 EDT 2006
Log message for revision 69510:
Totally reimplemented this code and gave it a different name. Now we
have a really small mini-language that can be embedded into any
programming language.
This will temporary break the functionality until I am done with
renaming.
Changed:
U z3c.cssresource/trunk/src/z3c/cssresource/README.txt
U z3c.cssresource/trunk/src/z3c/cssresource/SETUP.cfg
U z3c.cssresource/trunk/src/z3c/cssresource/__init__.py
D z3c.cssresource/trunk/src/z3c/cssresource/cssresource.py
A z3c.cssresource/trunk/src/z3c/cssresource/interfaces.py
U z3c.cssresource/trunk/src/z3c/cssresource/meta.zcml
A z3c.cssresource/trunk/src/z3c/cssresource/processor.py
A z3c.cssresource/trunk/src/z3c/cssresource/replace.py
U z3c.cssresource/trunk/src/z3c/cssresource/tests.py
D z3c.cssresource/trunk/src/z3c/cssresource/z3c.cssresource-meta.zcml
A z3c.cssresource/trunk/src/z3c/cssresource/z3c.zrtresource-meta.zcml
U z3c.cssresource/trunk/src/z3c/cssresource/zcml.py
U z3c.cssresource/trunk/src/z3c/cssresource/zcml.txt
A z3c.cssresource/trunk/src/z3c/cssresource/zrtresource.py
-=-
Modified: z3c.cssresource/trunk/src/z3c/cssresource/README.txt
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/README.txt 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/README.txt 2006-08-15 15:57:07 UTC (rev 69510)
@@ -1,31 +1,38 @@
-==================
-CSS File Resources
-==================
+===================
+Templated Resources
+===================
One of the design goals of Zope is to allow designers to check in HTML
template, CSS and Javascript files, which just work (with some additional
-information). For templates we use Zope's Page Templates to accomplish this
-objective. For CSS and Javascript we did not need such a feature, since
-nothing should be dynamic, due to chaching.
+information). For HTML code we use Zope's Page Templates to accomplish this
+objective. For CSS and Javascript we did not need such a feature until now,
+since those files were largely static or variables could be inserted using
+other ways at runtime.
-However, now URLs -- for example for background images -- are frequently
-inserted into CSS files. However, the path layout for the designer might not
-equal that to the resource file structure. This package provides a simple
-mechanism to replace strings by another.
+However, in CSS URLs -- for example for background images -- are now
+frequently inserted into CSS directives. However, the path layout for the
+designer might not equal the resource file structure. This package provides a
+simple mechanism to replace strings by another.
-To accomplish this task, a custom CSS file resource is provided. The replace
-syntax is provided inside CSS comments. The commands are as follows:
+To accomplish this, a templated resource is provided. The template syntax is
+provided in a way that it does not interfere with the syntax of the
+resource. For both, Javascript and CSS, this is a comment of the form ``/*
+... */``.
-- ``/* zope-global-replace: "ORIGINAL" "FINAL" */``
+Here is the general syntax::
-(Yes, for now it is only one.)
+ <COMMAND-BEGIN> <ZRT-COMMAND>: <COMMAND-ARGUMENTS> <COMMAND-END>
+Here is an example for CSS:
+
+ /* zrt-replace: ".." "@@" */
+
To demonstrate this feature, we first have to create a CSS file.
>>> import tempfile
>>> fn = tempfile.mktemp('.css')
>>> open(fn, 'w').write('''\
- ... /* zope-global-replace: "../img1" "++resource++/img" */
+ ... /* zrt-replace: "../img1" "++resource++/img" */
... h1 {
... color: red;
... background: url('../img1/mybackground.gif');
@@ -35,19 +42,23 @@
... color: red;
... background: url('../img2/mybackground.gif');
... }
- ... /* zope-global-replace: "../img2" "++resource++/img" */
+ ... /* zrt-replace: "../img2" "++resource++/img" */
... ''')
-As you can see, the command can be placed anywhere.
+The global replace command replaces a string with another. It is only active
+in the lines *after* it was declared. Thus, in this case, the second command
+is meaningless.
-Now we create a CSS resource from the resource factory:
+Now we create a ZRT resource from the resource factory ...
- >>> from z3c.cssresource import CSSFileResourceFactory
- >>> cssFactory = CSSFileResourceFactory(fn, None, 'site.css')
+ >>> from z3c.zrtresource import ZRTFileResourceFactory
+ >>> cssFactory = ZRTFileResourceFactory(fn, None, 'site.css')
>>> from zope.publisher.browser import TestRequest
>>> css = cssFactory(TestRequest())
+and render the resource:
+
>>> print css.GET()
h1 {
color: red;
@@ -56,55 +67,182 @@
<BLANKLINE>
h2 {
color: red;
- background: url('++resource++/img/mybackground.gif');
+ background: url('../img2/mybackground.gif');
}
- <BLANKLINE>
+As you can see only the first URL was replaced, because of the incorrect
+position of the second statement.
+
And that's all! In your ZCML you can use this factory as follows::
- <resource
+ <zrt-resource
name="site.css"
path="css/site.css"
- factory="z3c.cssresource.CSSFileResourceFactory"
/>
-Global Replace
---------------
+Replacing Strings
+=================
-As seen in the example above, ``zope-global-replace`` calls can be placed
+The ``zrt-replace`` command replaces any matches with the output string as
+many times as specified. Here is the syntax:
+
+ zrt-replace: <EXPR-TYPE>"<INPUT-EXPR>" <EXPR-TYPE>"<OUTPUT-EXPR>" <NUM>
+
+As seen in the example above, ``zrt-replace`` calls can be placed
anywhere in the file. Let's make sure that some special cases work as well:
- >>> from z3c.cssresource import CSSFileResource
- >>> resource = CSSFileResource(None, None)
+ >>> from z3c.zrtresource import processor, replace
+ >>> def process(text):
+ ... p = processor.ZRTProcessor(
+ ... text, commands={'replace': replace.Replace})
+ ... return p.process(None, None)
- >>> print resource.process('''\
- ... /* zope-global-replace: "foo" "bar" */
+ >>> print process('''\
+ ... /* zrt-replace: "foo" "bar" */
... foo''')
bar
- >>> print resource.process('''\
- ... /* zope-global-replace: "foo" "bar" */
+ >>> print process('''\
+ ... /* zrt-replace: "foo" "bar" */
... foo''')
bar
- >>> print resource.process('''\
- ... /* zope-global-replace: "foo" "bar" */
+ >>> print process('''\
+ ... /* zrt-replace: "foo" "bar" */
... foo''')
bar
But the following does not work:
- >>> print resource.process('''\
- ... /* zope-global-replace : "foo" "bar" */
+ >>> print process('''\
+ ... /* zrt-replace : "foo" "bar" */
... foo''')
- /* zope-global-replace : "foo" "bar" */
+ /* zrt-replace : "foo" "bar" */
foo
- >>> print resource.process('''\
- ... /* zope -global-replace : "foo" "bar" */
+ >>> print process('''\
+ ... /* zrt -replace : "foo" "bar" */
... foo''')
- /* zope -global-replace : "foo" "bar" */
+ /* zrt -replace : "foo" "bar" */
foo
+Until now we have only considered multiple replacements. Let's now restrict
+the number of replacements with the final argument. Initially all occurences
+of a matching string are replaced:
+ >>> print process('''\
+ ... /* zrt-replace: "foo" "bar" */
+ ... foo foo foo foo foo''')
+ bar bar bar bar bar
+
+When we specify a number of replacements, then only that amount is replaced:
+
+ >>> print process('''\
+ ... /* zrt-replace: "foo" "bar" 1 */
+ ... foo foo foo foo foo''')
+ bar foo foo foo foo
+
+ >>> print process('''\
+ ... /* zrt-replace: "foo" "bar" 3 */
+ ... foo foo foo foo foo''')
+ bar bar bar foo foo
+
+ >>> print process('''\
+ ... /* zrt-replace: "foo" "bar" 6 */
+ ... foo foo foo foo foo''')
+ bar bar bar bar bar
+
+
+The String Expression
+---------------------
+
+Until now we have only dealt with simple string replacement, since it is the
+default expression type. Another way of spelling the expression type is:
+
+ >>> print process('''\
+ ... /* zrt-replace: str"foo" "bar" */
+ ... foo''')
+ bar
+
+ >>> print process('''\
+ ... /* zrt-replace: "foo" str"bar" */
+ ... foo''')
+ bar
+
+ >>> print process('''\
+ ... /* zrt-replace: str"foo" str"bar" */
+ ... foo''')
+ bar
+
+
+The Regex Expression
+--------------------
+
+Regular expressions make only sense as input expressions, so they are only
+supported there:
+
+ >>> print process('''\
+ ... /* zrt-replace: re"foo" "bar" */
+ ... foo''')
+ bar
+
+ >>> print process('''\
+ ... /* zrt-replace: re"[a-z]*foo" "bar" */
+ ... myfoo''')
+ bar
+
+We also support groups:
+
+ >>> print process('''\
+ ... /* zrt-replace: re"([a-z]*)foo" "bar" */
+ ... myfoo''')
+ bar
+
+ >>> print process('''\
+ ... /* zrt-replace: re"([a-z]*)foo" "bar" */
+ ... myfoo''')
+ bar
+
+ >>> print process('''\
+ ... /* zrt-replace: re"([a-z]*)foo" "bar" */
+ ... myfoo mybar''')
+ bar mybar
+
+Yes, even group replacement works:
+
+ >>> print process('''\
+ ... /* zrt-replace: re"([a-z]*)foo" "bar\\1" */
+ ... myfoo a9foo''')
+ barmy a9bar
+
+ >>> print process('''\
+ ... /* zrt-replace: re"(?P<prefix>[a-z]*)foo" "bar\\g<prefix>" */
+ ... myfoo a9foo''')
+ barmy a9bar
+
+
+The TALES Expression
+--------------------
+
+What would be a Zope-based templating language without TALES expressions. This
+is particularly useful, if you want create absolute URLs and other dynamic
+bits based on the request and the context:
+
+ >>> import zope.interface
+ >>> from zope.traversing.interfaces import IContainmentRoot
+ >>> class Root(object):
+ ... zope.interface.implements(IContainmentRoot)
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> def process(text):
+ ... p = processor.ZRTProcessor(
+ ... text, commands={'replace': replace.Replace})
+ ... return p.process(Root(), TestRequest())
+
+ >>> print process('''\
+ ... /* zrt-replace: "foo" tal"string:${context/@@absolute_url}/@@/foo" */
+ ... foo''')
+ http://127.0.0.1/@@/foo
+
+
Modified: z3c.cssresource/trunk/src/z3c/cssresource/SETUP.cfg
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/SETUP.cfg 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/SETUP.cfg 2006-08-15 15:57:07 UTC (rev 69510)
@@ -1,3 +1,3 @@
<data-files zopeskel/etc/package-includes>
- z3c.cssresource-*.zcml
+ z3c.zrtresource-*.zcml
</data-files>
Modified: z3c.cssresource/trunk/src/z3c/cssresource/__init__.py
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/__init__.py 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/__init__.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -1,2 +1,2 @@
# Make a package
-from cssresource import CSSFileResource, CSSFileResourceFactory
+from zrtresource import ZRTFileResource, ZRTFileResourceFactory
Deleted: z3c.cssresource/trunk/src/z3c/cssresource/cssresource.py
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/cssresource.py 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/cssresource.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -1,57 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""CSS Resource
-
-$Id$
-"""
-import re
-
-from zope.app.publisher.fileresource import File
-from zope.app.publisher.browser.fileresource import FileResource
-
-# Allows matches of the form: /* ZOPE-COMMAND: "ORIGINAL" "FINAL" */
-directive_regex = r' */\* *%s: *"([^ "]*)" *"([^ "]*)" *\*/'
-global_replace = re.compile(directive_regex %'zope-global-replace')
-
-class CSSFileResource(FileResource):
-
- def process(self, data):
- # Find all directives
- directives = re.compile(
- directive_regex %'zope-global-replace').findall(data)
- # Remove directives from file
- data = re.compile(
- (directive_regex+'\n') %'zope-global-replace').sub('', data)
- # Now execute directives
- for orig, final in directives:
- data = data.replace(orig, final)
- return data
-
- def GET(self):
- data = super(CSSFileResource, self).GET()
- return self.process(data)
-
-
-class CSSFileResourceFactory(object):
-
- def __init__(self, path, checker, name):
- self.__file = File(path, name)
- self.__checker = checker
- self.__name = name
-
- def __call__(self, request):
- resource = CSSFileResource(self.__file, request)
- resource.__Security_checker__ = self.__checker
- resource.__name__ = self.__name
- return resource
Added: z3c.cssresource/trunk/src/z3c/cssresource/interfaces.py
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/interfaces.py 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/interfaces.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -0,0 +1,92 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Templated Resource Interfaces
+
+$Id$
+"""
+__docformat__='restructuredtext'
+
+import zope.interface
+import zope.schema
+
+
+class UnknownZRTCommand(ValueError):
+ """An unknown ZRT Command was specified"""
+
+
+class ArgumentError(ValueError):
+ """Error while parsing the command arguments."""
+
+
+class IZRTProcessor(zope.interface.Interface):
+ """ZRT Processor"""
+
+ source = zope.schema.Bytes(
+ title=u'Source',
+ description=u'The source of the expression.')
+
+ def compile():
+ """Compile the source to binary form."""
+
+ def process(context, request):
+ """Process the source with given context and request.
+
+ Return the result string.
+ """
+
+
+class IZRTCommand(zope.interface.Interface):
+ """A ZRT command"""
+
+ isAvailable = zope.schema.Bool(
+ title=u'Is Available',
+ description=u'Tell whether the command is still available.')
+
+ def process(text, context, request):
+ """Process the given text with given context and request.
+
+ Return the result string.
+ """
+
+class IZRTExpression(zope.interface.Interface):
+ """An expression to be used in a command."""
+
+ source = zope.schema.Bytes(
+ title=u'Source',
+ description=u'The source of the expression.')
+
+ context = zope.schema.Object(
+ title=u'Context',
+ description=u'Context of the template, usually a site.',
+ schema=zope.interface.Interface)
+
+ request = zope.schema.Object(
+ title=u'Request',
+ description=u'Request of the template, usually a site.',
+ schema=zope.interface.Interface)
+
+
+class IZRTInputExpression(IZRTExpression):
+
+ def process(text, outputExpr):
+ """Evaluate the expression and update the """
+
+
+class IZRTOutputExpression(IZRTExpression):
+
+ def process(**kw):
+ """Process the expression and return the output string.
+
+ The keyword arguments are additional namespaces.
+ """
Property changes on: z3c.cssresource/trunk/src/z3c/cssresource/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: z3c.cssresource/trunk/src/z3c/cssresource/meta.zcml
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/meta.zcml 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/meta.zcml 2006-08-15 15:57:07 UTC (rev 69510)
@@ -5,9 +5,9 @@
<meta:directives namespace="http://namespaces.zope.org/browser">
<meta:directive
- name="css-resource"
+ name="zrt-resource"
schema=".zcml.ICSSResourceDirective"
- handler=".zcml.cssresource"
+ handler=".zcml.zrtresource"
/>
</meta:directives>
Added: z3c.cssresource/trunk/src/z3c/cssresource/processor.py
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/processor.py 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/processor.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -0,0 +1,100 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Templated Resource Processor
+
+$Id$
+"""
+__docformat__='restructuredtext'
+import re
+import zope.interface
+from z3c.zrtresource import interfaces
+
+# <COMMAND-BEGIN> <ZRT-COMMAND>: <COMMAND-ARGUMENTS> <COMMAND-END>
+NAME = r'[a-zA-Z0-9_-]*'
+COMMAND_REGEX = r'%%s(%s):\s*(.*?)\s*%%s' %NAME
+
+TEXTBLOCK=0
+COMMAND=1
+
+class ZRTProcessor(object):
+ """A ZRT Processor"""
+ zope.interface.implements(interfaces.IZRTProcessor)
+
+ commandStartRegex = r'/\*\s*zrt-'
+ commandEndRegex = r'\*/'
+
+ def __init__(self, source, commands=None):
+ self.source = source
+ if not commands:
+ commands = {}
+ self.commands = commands
+ self._bytecode = None
+
+ def compile(self):
+ """See interfaces.IZRTProcessor"""
+ bytecode = []
+ pos = 0
+ # Regular Expression to find commands.
+ regex = re.compile(COMMAND_REGEX %(self.commandStartRegex,
+ self.commandEndRegex))
+ # Find all commands
+ for match in regex.finditer(self.source):
+ command, args = match.groups()
+
+ # Make sure the command exists
+ if command not in self.commands:
+ raise interfaces.UnknownZRTCommand(command)
+
+ # Add the previous text block and update position
+ bytecode.append((TEXTBLOCK, self.source[pos:match.start()]))
+ pos = match.end() + 1
+
+ # Add the command
+ bytecode.append(
+ (COMMAND, (command, args, match.start(), match.end())))
+
+ # Add the final textblock
+ bytecode.append((TEXTBLOCK, self.source[pos:]))
+
+ self._bytecode = bytecode
+
+
+ def process(self, context, request):
+ """See interfaces.IZRTProcessor"""
+ if self._bytecode is None:
+ self.compile()
+
+ # List active commands
+ active = []
+ result = []
+ for type, value in self._bytecode:
+ # If the type is a command, simply add it to the list of commands
+ if type is COMMAND:
+ cmd, args, start, end = value
+ active.append(
+ self.commands[cmd](args, start, end))
+ # If we have a textblock, then work on it.
+ elif type is TEXTBLOCK:
+ # Process any command
+ for cmd in active:
+ value = cmd.process(value, context, request)
+ # If the command is no longer available, remove it
+ if not cmd.isAvailable:
+ active.remove(cmd)
+ # This block is fully processed now.
+ result.append(value)
+ else:
+ raise ValueError(type)
+
+ return ''.join(result)
Property changes on: z3c.cssresource/trunk/src/z3c/cssresource/processor.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3c.cssresource/trunk/src/z3c/cssresource/replace.py
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/replace.py 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/replace.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -0,0 +1,123 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Templated Resource Processor
+
+$Id$
+"""
+__docformat__='restructuredtext'
+import re
+import zope.interface
+from zope.app.pagetemplate import engine
+from z3c.cssresource import interfaces
+
+# <EXPR-TYPE>"<INPUT-EXPR>" <EXPR-TYPE>"<OUTPUT-EXPR>" <NUM>
+NAME = r'[a-zA-Z0-9_-]*'
+ARGS_REGEX = re.compile(r' *(%s)"([^ "]*)" *(%s)"([^ "]*)" *([0-9]*)' %(NAME, NAME))
+
+
+class BaseExpression(object):
+
+ def __init__(self, source, context, request):
+ self.source = source
+ self.context = context
+ self.request = request
+
+
+class StringInputExpression(BaseExpression):
+ """A simple string input expression"""
+ zope.interface.implements(interfaces.IZRTInputExpression)
+
+ def process(self, text, outputExpr, count=None):
+ regex = re.compile(re.escape(self.source))
+ return regex.subn(outputExpr.process(), text, count or 0)
+
+
+class StringOutputExpression(BaseExpression):
+ """A simple string input expression"""
+ zope.interface.implements(interfaces.IZRTOutputExpression)
+
+ def process(self, **kw):
+ # Ignore any keyword arguments, since this is static replacement
+ return self.source
+
+
+class RegexInputExpression(BaseExpression):
+ """A regex string input expression"""
+ zope.interface.implements(interfaces.IZRTInputExpression)
+
+ def process(self, text, outputExpr, count=None):
+ regex = re.compile(self.source)
+ return regex.subn(outputExpr.process(), text, count or 0)
+
+
+class TALESOutputExpression(BaseExpression):
+ """A simple string input expression"""
+ zope.interface.implements(interfaces.IZRTOutputExpression)
+
+ def process(self, **kw):
+ expr = engine.TrustedEngine.compile(self.source)
+ kw.update({'context': self.context, 'request': self.request})
+ econtext = engine.TrustedEngine.getContext(kw)
+ return expr(econtext)
+
+
+class Replace(object):
+ """A ZRT Command to replace sub-strings of the text"""
+ zope.interface.implements(interfaces.IZRTCommand)
+
+ inputExpressions = {
+ '': StringInputExpression,
+ 'str': StringInputExpression,
+ 're': RegexInputExpression,
+ }
+
+ outputExpressions = {
+ '': StringOutputExpression,
+ 'str': StringOutputExpression,
+ 'tal': TALESOutputExpression,
+ }
+
+ def __init__(self, args, start, end):
+ self.start = start
+ self.end = end
+ self.processArguments(args)
+
+ @property
+ def isAvailable(self):
+ return self.num is None or self.num > 0
+
+ def processArguments(self, args):
+ match = ARGS_REGEX.match(args)
+ if match is None:
+ raise interfaces.ArgumentError(args)
+
+ self.itype, self.input, self.otype, self.output, self.num = match.groups()
+ self.num = self.num and int(self.num) or None
+
+ if self.itype not in self.inputExpressions:
+ raise ValueError(self.itype)
+
+ if self.otype not in self.outputExpressions:
+ raise ValueError(self.otype)
+
+
+ def process(self, text, context, request):
+ iexpr = self.inputExpressions[self.itype](
+ self.input, context, request)
+ oexpr = self.outputExpressions[self.otype](
+ self.output, context, request)
+ text, num = iexpr.process(text, oexpr, self.num)
+ if self.num is not None:
+ self.num -= num
+ return text
Property changes on: z3c.cssresource/trunk/src/z3c/cssresource/replace.py
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: z3c.cssresource/trunk/src/z3c/cssresource/tests.py
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/tests.py 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/tests.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -19,13 +19,26 @@
import doctest
import unittest
+import zope.component
from zope.app.testing import placelesssetup
from zope.testing.doctestunit import DocFileSuite
+from zope.traversing import testing
+from zope.traversing.interfaces import ITraversable
+from zope.traversing.namespace import view
+
+def setUp(test):
+ placelesssetup.setUp(test)
+ testing.setUp()
+ zope.component.provideAdapter(view, (None, None), ITraversable, name="view")
+
+
def test_suite():
return unittest.TestSuite((
DocFileSuite('README.txt',
+ setUp=setUp,
+ tearDown=placelesssetup.tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
),
DocFileSuite('zcml.txt',
Deleted: z3c.cssresource/trunk/src/z3c/cssresource/z3c.cssresource-meta.zcml
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/z3c.cssresource-meta.zcml 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/z3c.cssresource-meta.zcml 2006-08-15 15:57:07 UTC (rev 69510)
@@ -1 +0,0 @@
-<include package="z3c.cssresource" file="meta.zcml" />
Copied: z3c.cssresource/trunk/src/z3c/cssresource/z3c.zrtresource-meta.zcml (from rev 69499, z3c.cssresource/trunk/src/z3c/cssresource/z3c.cssresource-meta.zcml)
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/z3c.cssresource-meta.zcml 2006-08-15 02:20:28 UTC (rev 69499)
+++ z3c.cssresource/trunk/src/z3c/cssresource/z3c.zrtresource-meta.zcml 2006-08-15 15:57:07 UTC (rev 69510)
@@ -0,0 +1 @@
+<include package="z3c.zrtresource" file="meta.zcml" />
Modified: z3c.cssresource/trunk/src/z3c/cssresource/zcml.py
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/zcml.py 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/zcml.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -23,7 +23,7 @@
from zope.security.checker import CheckerPublic, NamesChecker
from zope.app.publisher.browser import metadirectives, resourcemeta
-import z3c.cssresource
+import z3c.zrtresource
class ICSSResourceDirective(metadirectives.IBasicResourceInformation):
@@ -56,7 +56,7 @@
checker = NamesChecker(resourcemeta.allowed_names, permission)
- factory = z3c.cssresource.CSSFileResourceFactory(file, checker, name)
+ factory = z3c.zrtresource.CSSFileResourceFactory(file, checker, name)
_context.action(
discriminator = ('resource', name, browser.IBrowserRequest, layer),
Modified: z3c.cssresource/trunk/src/z3c/cssresource/zcml.txt
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/zcml.txt 2006-08-15 15:11:36 UTC (rev 69509)
+++ z3c.cssresource/trunk/src/z3c/cssresource/zcml.txt 2006-08-15 15:57:07 UTC (rev 69510)
@@ -1,5 +1,5 @@
==========================
-``css-resource`` Directive
+``zrt-resource`` Directive
==========================
This package provides a new directive to use the special resource
@@ -8,7 +8,7 @@
>>> from zope.configuration import xmlconfig
>>> context = xmlconfig.string('''
... <configure i18n_domain="zope">
- ... <include package="z3c.cssresource" file="meta.zcml" />
+ ... <include package="z3c.zrtresource" file="meta.zcml" />
... </configure>
... ''')
@@ -17,22 +17,16 @@
>>> import tempfile
>>> fn = tempfile.mktemp('.css')
>>> open(fn, 'w').write('''\
- ... /* zope-global-replace: "../img1" "++resource++/img" */
+ ... /* zrt-replace: "../img1" "++resource++/img" */
... h1 {
... color: red;
... background: url('../img1/mybackground.gif');
... }
- ...
- ... h2 {
- ... color: red;
- ... background: url('../img2/mybackground.gif');
- ... }
- ... /* zope-global-replace: "../img2" "++resource++/img" */
... ''')
>>> context = xmlconfig.string('''
... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope">
- ... <css-resource
+ ... <zrt-resource
... name="test.css"
... file="%s" />
... </configure>
@@ -53,9 +47,3 @@
color: red;
background: url('++resource++/img/mybackground.gif');
}
- <BLANKLINE>
- h2 {
- color: red;
- background: url('++resource++/img/mybackground.gif');
- }
- <BLANKLINE>
Copied: z3c.cssresource/trunk/src/z3c/cssresource/zrtresource.py (from rev 69499, z3c.cssresource/trunk/src/z3c/cssresource/cssresource.py)
===================================================================
--- z3c.cssresource/trunk/src/z3c/cssresource/cssresource.py 2006-08-15 02:20:28 UTC (rev 69499)
+++ z3c.cssresource/trunk/src/z3c/cssresource/zrtresource.py 2006-08-15 15:57:07 UTC (rev 69510)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""CSS Resource
+
+$Id$
+"""
+__docformat__='restructuredtext'
+from zope.app.component.hooks import getSite
+from zope.app.publisher.fileresource import File
+from zope.app.publisher.browser.fileresource import FileResource
+
+from z3c.zrtresource import processor, replace
+
+
+class CSSFileResource(FileResource):
+
+ def GET(self):
+ data = super(CSSFileResource, self).GET()
+ # Process the file
+ p = processor.ZRTProcessor(data, commands={'replace': replace.Replace})
+ return p.process(self.request, getSite())
+
+
+class CSSFileResourceFactory(object):
+
+ def __init__(self, path, checker, name):
+ self.__file = File(path, name)
+ self.__checker = checker
+ self.__name = name
+
+ def __call__(self, request):
+ resource = CSSFileResource(self.__file, request)
+ resource.__Security_checker__ = self.__checker
+ resource.__name__ = self.__name
+ return resource
More information about the Checkins
mailing list