Rendering a view - About performance

THE PLOT

If you want to render a piece of html code in your template, and it is going to be needed at different templates you can use macros attached to a view, but if this piece of html needs to have some logic and you are using view methods or attributes in it, then you have to assure that the variable view is defined and has access to those method a/o attributes, there are different solutions for this but the offered by Plone (or Zope, I don't know who implemented it) is the use of viewlets and viewlets managers. Now appears Plone 5 using Diazo and another way of rendering views, and I was asking about:
Which one is the better way?


THE CASES

Next I'm going to list all the cases that I explained before and the steps needed to make them work

Rendering a macro without logic in it

Traversing

  1. Define your macro within a template
  2. Register a view with your template attached
  3. Call it: tal:content="context/@@my_view/macros/my_macro"

Quite simple and seems ok.

Rendering a macro with logic in it

Viewlets

  1. Write the template
  2. Write the class
  3. Register them as a viewlet
  4. Register a viewlet manager
  5. Attach your viewlet to your viewlets manager
  6. Render your viewlet manager tal:replace="structure provider:plone.httpheaders"

The way plone does it, never tried it by my self, seems a pain in the ass.

Attaching view definitions

  1. Write the template
  2. Write the class
  3. Register them as a view
  4. Provide to view what it needs
    a. Through template: tal:define="view python:context.restrictedTraverse('@@my_view')", or maybe, I'm not sure right now if it would work: tal:define="view nocall:context/@@my_view"
    b. Through inheritance, making the class of the view (for example @@front_page) where you want to render the view we defined here (@@my_view) a subclass of the @@my_view class, so it has all the definitions.
  5. Render the macro.

I don't like any of this solutions.

Diazo way

  1. Write the template
  2. Write the class
  3. Register them as a view
  4. Go to rules and access to it like: <replace css:theme="#content" css:content="#my-view-content" href="@@my_view"/>

It looks good, but detaches rendering flow from main_template, and seems like its creating different threads to chameleon making it render first the main_template and then every view attached to a href, so I'm not sure about using it.


Which is the best way to handle this situation?

1 Like

And there is rapido for TTW customizations. Did you take a look at that already?

Do you have an actual use case or are you just elaborating performance merits of various approaches? Often the best approach can differ between different cases, depending on actual requirements.

If you are serious about perfomance, you should prepare a measurable test case to determine the best alternative - but unless you have a really demanding use case behind your question, your time is probably better spent on other things than this kind of optimization, anyway.

2 Likes

I'm just curious about which one is the "correct" way to do it. And know if there some of this way are a very heavy hit to performance.

There is no "correct" way, given you are not giving a more specific use case. I'd suggest starting with a regular view, and if you have special performance requirements for your HTML page produced by the view, just make sure to put as much of your logic into the view as you can, rather than the template.

1 Like

as @petri says: there is no "correct" way; in the past I made some performance measures in tests, maybe you can take some ideas for your case:

Once in the past I tried to use macros in Plone 4, but I always got bitten by some bug.

Now when the need for reusable HTML arises I always manage to use views instead. It's more powerful and clean, because you have a class behind, and just feels more right.

A tip for performance: when the need for speed is too high you can manage to squeeze some milliseconds out by not using ZPT and make the HTML construction in your view class. Even better if you avoid string concatenation by doing things like '\n'.join(html_tags) or StringIO.

I don't have anything against macros, they can feel a bit tricky at the first but they are a powerful way of defining base templates which are highly reusable, and most of times a class is avoidable.
Anyway, which is the method you use to render your views inside your other views?

<div tal:content="structure context/@@my-view">Render view content here</div>

We heavily use macros at work and those combined with plone.app.contentlisting (we don't use it actually, but got inspired by it) means that our templates and macros are:

  • super clean
  • highly reusable
  • extremely consistent

No matter what object we are rendering, we will certainly have the same listitem/foo as in all other templates.

I see that nobody mentioned it before, but there's yet another solution (pioneered by castle.cms actually): use plone.app.mosaic site and page layouts. And actually that's the more future proof thing you could do if you don't want to port away from portlets and viewlets in a plone 6/7/8

1 Like