Have your views rendered with DTML

13

16/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.

13 thoughts on “Have your views rendered with DTML

  1. yboussard says:

    Cool !! I’ll used it soon
    Thanks Gilles.

  2. spliter says:

    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 πŸ˜‰

  3. Gilles Lenfant says:

    @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.

  4. laurencerowe says:

    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.

  5. spliter says:

    @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

  6. Gilles Lenfant says:

    @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 πŸ˜‰

  7. macadames says:

    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

  8. miguelitosm says:

    Still having trouble getting the dtml file to register. Am I missing something special in the cssregistry.xml?

  9. Gilles Lenfant says:

    @miguelitosm
    Can’t get your case.
    What when browsing http:///mystyle.css or http:///@@mystyle.css ?

  10. Gilles Lenfant says:

    @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 ?

  11. miguelitosm says:

    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!

  12. […] 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 […]

  13. akkerman forum…

    […]Have your views rendered with DTML « Digital snake and family[…]…

Leave a reply to spliter Cancel reply

Archives