Have your views rendered with DTML
1316/08/2008 by Gilles Lenfant
Have your views rendered with DTML
As we’re supposed to kill the CMF skins layer in the Plone components, when tailoring the old style products to components, we put all static data (images, javascripts, stylesheets) in resources directories, python scripts to views and adpters, controller page templates to plone.app.form or plone.app.z3cform schemes, and so on…
But the new style resource directory doesn’t take care about DTML as it does for page templates. And for some kinds of stuffs like dynamic CSS/Javascript, or making a CSV file, DTML is yet the better suited than ZPT.
Yes you can publish DTML based views/pages/viewlets. This is not obvious but not that much complicated. This small example shows how to add a stylesheet using the standard Plone “base_properties” CSS data.
First the ZCML bunch at …/browser/configure.zcml:
<browser:page name="mystytles.css" for="Products.CMFPlone.interfaces.IPloneSiteRoot" class=".stylesheet.MyStylesheet" permission="zope2.Public" />
So we’ll have that sthylesheet published at http://<your-site>/mystyles.css.
Now the …/browser/stylesheet.py module:
... import os from Globals import DTMLFile
from Products.Five.browser import BrowserView ... this_dir = os.path.dirname(os.path.abspath(__file__))
templates_dir = os.path.join(this_dir, 'templates') # Don't add ".dtml" to the file name though the file is "mystyles.css.dtml" mystylesheet_dtml = DTMLFile('mystyles.css', templates_dir)
... class MyStylesheet(BrowserView):
def __call__(self, *args, **kw): """This view is published"""
# Wrap acquisition context to template
template = mystylesheet_dtml.__of__(self.context) # Note that you can provide other named args below you might need in # your template return template(context=context)
And finally our DTML template at …/browser/templates/mystyles.css.dtml
/* <dtml-with "context.base_properties"> (do not remove this :) <dtml-let portal_url="context.absolute_url()"> (do not remove this :) */
.silly { color: &dtml-discreetColor;; } .foo { background: &dtml-portal_url;/some-image.gif; }
/* </dtml-let></dtml-with> (do not remove this :) */
You just need to add “mystyles.css” to the Plone CSS registry but that’s another story. That’s all folks.
Note that you could prefer using z3c.zrtresource if you’re bleeding-edge oriented developer.
Cool !! I’ll used it soon
Thanks Gilles.
I wonder why would one want to add this complexity instead of just putting your stylesheets to the place that is already DTML-enabled – skins/ folder? It’s quite simple – if you don’t need to use DTMl in your stylesheets, use broser/stylesheets if you need DTML put your stylesheets to skins/. While it is possible to use skins/ in case you need DTML why not to use it and save your time? π But this might be the solution when we are not allowed to use skins/ folder indeed. Though I think at that point Plone will have something that would require less manual work π
@spliter:
Sorry to add complexity (I can’t make it more simple) but (a) a view lookup is faster than a CMF skins lookup (well, though we don’t speed up plone by a factor of 10 with this π and (b) the CMF skins will disappear with Plone 4 while this recipe will always work AFAIK.
I’ve been using string.Template (from the python standard library) for some simple user accessible templating. Worth a look for css type templating I’d have thought.
For CSV though I much prefer generating it with the python csv module.
@Gilles Lenfant
Thanks for your response, Gilles. But I wonder do you have numbers that would indicate that “a view lookup is faster than a CMF skins lookup”? I was not able to find any confirmation of this. I think we have discussed this with David Convent and Wichert Akkerman about 5-6 months ago and have agreed that there is no significant speed changes when we are talking about stylesheets. Has anything been changed since then? Would be cool to get updated information
@spliter
A view lookup is nearly as fast as a dict lookup, but I agree with you, there’s nothing significant in the general page publication process. It’s not the Plone performances bottleneck, compared with actions lookup and filtering (among other things…) but I’m running out of topic π
Many thanks for your post Gilles,
I’ve just try it today & it works really fine, i will use it in collective.phantasy since it is the more easy way to reproduce plone stylesheets behavior using browser resources.
Also i’ve tried to work with zrt resources but dtml is more powerful for dynamic skins.
Bye
mc macadames
Still having trouble getting the dtml file to register. Am I missing something special in the cssregistry.xml?
@miguelitosm
Can’t get your case.
What when browsing http:///mystyle.css or http:///@@mystyle.css ?
@miguelitosm
(typo correction due to wordpress ULs mangling)
Canβt get your case.
What when browsing http://www.yoursite.tld/mystyles.css or http://www.yoursite.tld/@@mystyles.css ?
Got it sorted. Thanks, doing as you suggested resulted in:
line 21, in __call__
NameError: global name ‘context’ is not defined
added this line in __call__:
context = context.self
which solved it
Thanks Gilles for the help, this is excellent!
[…] Wed 31-12-2008 Astro-Journalling Retreat, Day Three Saved by pleasantvienna on Thu 25-12-2008 Gilles Lenfant: Have your views rendered with DTML Saved by evifrank on Mon 22-12-2008 Future Teller, renders your future vision! Saved by […]
akkerman forum…
[…]Have your views rendered with DTML « Digital snake and family[…]…