Zope Resource Templates
Project description
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 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, 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, 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 ``/*
... */``.
Here is the general syntax::
<COMMAND-BEGIN> <ZRT-COMMAND>: <COMMAND-ARGUMENTS> <COMMAND-END>
Here is an example for CSS:
/* zrt-replace: ".." "@@" */
Detailed Dcoumentation
~~~~~~~~~~~~~~~~~~~~~~
===================
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 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, 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, 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 ``/*
... */``.
Here is the general syntax::
<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('''\
... /* zrt-replace: "../img1" "++resource++/img" */
... h1 {
... color: red;
... background: url('../img1/mybackground.gif');
... }
...
... h2 {
... color: red;
... background: url('../img2/mybackground.gif');
... }
... /* zrt-replace: "../img2" "++resource++/img" */
... ''')
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 ZRT resource from the resource factory ...
>>> 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;
background: url('++resource++/img/mybackground.gif');
}
<BLANKLINE>
h2 {
color: red;
background: url('../img2/mybackground.gif');
}
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::
<zrt-resource
name="site.css"
path="css/site.css"
/>
Replacing Strings
=================
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.zrtresource import processor, replace
>>> def process(text):
... p = processor.ZRTProcessor(
... text, commands={'replace': replace.Replace})
... return p.process(None, None)
>>> print process('''\
... /* zrt-replace: "foo" "bar" */
... foo''')
bar
>>> print process('''\
... /* zrt-replace: "foo" "bar" */
... foo''')
bar
>>> print process('''\
... /* zrt-replace: "foo" "bar" */
... foo''')
bar
But the following does not work:
>>> print process('''\
... /* zrt-replace : "foo" "bar" */
... foo''')
/* zrt-replace : "foo" "bar" */
foo
>>> print process('''\
... /* zrt -replace : "foo" "bar" */
... foo''')
/* 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
==========================
``zrt-resource`` Directive
==========================
This package provides a new directive to use the special resource
directive. Let's register it first:
>>> from zope.configuration import xmlconfig
>>> context = xmlconfig.string('''
... <configure i18n_domain="zope">
... <include package="z3c.zrtresource" file="meta.zcml" />
... </configure>
... ''')
Now we can register a resource:
>>> import tempfile
>>> fn = tempfile.mktemp('.css')
>>> open(fn, 'w').write('''\
... /* zrt-replace: "../img1" "++resource++/img" */
... h1 {
... color: red;
... background: url('../img1/mybackground.gif');
... }
... ''')
>>> context = xmlconfig.string('''
... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope">
... <zrt-resource
... name="test.css"
... file="%s" />
... </configure>
... ''' %fn, context=context)
Now let's see whether the adapter has been registered:
>>> import zope.component
>>> import zope.interface
>>> from zope.publisher.browser import TestRequest
>>> resource = zope.component.getAdapter(
... TestRequest(), zope.interface.Interface, name='test.css')
Now run it:
>>> print resource.GET()
h1 {
color: red;
background: url('++resource++/img/mybackground.gif');
}
=======
CHANGES
=======
1.0.0 (2007-10-30)
------------------
- Initial release.
template, CSS and Javascript files, which just work (with some additional
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, 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, 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 ``/*
... */``.
Here is the general syntax::
<COMMAND-BEGIN> <ZRT-COMMAND>: <COMMAND-ARGUMENTS> <COMMAND-END>
Here is an example for CSS:
/* zrt-replace: ".." "@@" */
Detailed Dcoumentation
~~~~~~~~~~~~~~~~~~~~~~
===================
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 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, 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, 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 ``/*
... */``.
Here is the general syntax::
<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('''\
... /* zrt-replace: "../img1" "++resource++/img" */
... h1 {
... color: red;
... background: url('../img1/mybackground.gif');
... }
...
... h2 {
... color: red;
... background: url('../img2/mybackground.gif');
... }
... /* zrt-replace: "../img2" "++resource++/img" */
... ''')
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 ZRT resource from the resource factory ...
>>> 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;
background: url('++resource++/img/mybackground.gif');
}
<BLANKLINE>
h2 {
color: red;
background: url('../img2/mybackground.gif');
}
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::
<zrt-resource
name="site.css"
path="css/site.css"
/>
Replacing Strings
=================
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.zrtresource import processor, replace
>>> def process(text):
... p = processor.ZRTProcessor(
... text, commands={'replace': replace.Replace})
... return p.process(None, None)
>>> print process('''\
... /* zrt-replace: "foo" "bar" */
... foo''')
bar
>>> print process('''\
... /* zrt-replace: "foo" "bar" */
... foo''')
bar
>>> print process('''\
... /* zrt-replace: "foo" "bar" */
... foo''')
bar
But the following does not work:
>>> print process('''\
... /* zrt-replace : "foo" "bar" */
... foo''')
/* zrt-replace : "foo" "bar" */
foo
>>> print process('''\
... /* zrt -replace : "foo" "bar" */
... foo''')
/* 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
==========================
``zrt-resource`` Directive
==========================
This package provides a new directive to use the special resource
directive. Let's register it first:
>>> from zope.configuration import xmlconfig
>>> context = xmlconfig.string('''
... <configure i18n_domain="zope">
... <include package="z3c.zrtresource" file="meta.zcml" />
... </configure>
... ''')
Now we can register a resource:
>>> import tempfile
>>> fn = tempfile.mktemp('.css')
>>> open(fn, 'w').write('''\
... /* zrt-replace: "../img1" "++resource++/img" */
... h1 {
... color: red;
... background: url('../img1/mybackground.gif');
... }
... ''')
>>> context = xmlconfig.string('''
... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope">
... <zrt-resource
... name="test.css"
... file="%s" />
... </configure>
... ''' %fn, context=context)
Now let's see whether the adapter has been registered:
>>> import zope.component
>>> import zope.interface
>>> from zope.publisher.browser import TestRequest
>>> resource = zope.component.getAdapter(
... TestRequest(), zope.interface.Interface, name='test.css')
Now run it:
>>> print resource.GET()
h1 {
color: red;
background: url('++resource++/img/mybackground.gif');
}
=======
CHANGES
=======
1.0.0 (2007-10-30)
------------------
- Initial release.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
z3c.zrtresource-1.0.0.tar.gz
(10.9 kB
view hashes)