How to render PageTemplateFile

from Products.Five.browser import BrowserView
from Products.PageTemplates.PageTemplateFile import PageTemplateFile

class ReportView(BrowserView):
def render_template(self):
return PageTemplateFile('templates/template1.zpt', globals()).render(self)

...

...

This fails with:
Traceback (innermost last):

Module ZPublisher.Publish, line 138, in publish
Module ZPublisher.mapply, line 77, in mapply
Module ZPublisher.Publish, line 48, in call_object
Module Products.Five.browser.metaconfigure, line 485, in __call__
Module Products.Five.browser.pagetemplatefile, line 125, in __call__
Module Products.Five.browser.pagetemplatefile, line 59, in __call__
Module zope.pagetemplate.pagetemplate, line 132, in pt_render
Module five.pt.engine, line 98, in __call__
Module z3c.pt.pagetemplate, line 163, in render
Module chameleon.zpt.template, line 261, in render
Module chameleon.template, line 191, in render
Module chameleon.template, line 171, in render
Module d0eb32ecfe0341044c60310130931e05.py, line 208, in render
Module de31ce41c2769f819da4315975276b9f.py, line 1223, in render_master
Module de31ce41c2769f819da4315975276b9f.py, line 420, in render_content
Module d0eb32ecfe0341044c60310130931e05.py, line 160, in __fill_content_core
Module five.pt.expressions, line 161, in __call__
Module MyAddon.browser.views, line 27, in render_template

TypeError: cannot concatenate 'str' and 'int' objects

From the Training Docs

from Products.Five.browser import BrowserView

class DemoView(BrowserView):
    """ This does nothing so far
    """

    def __init__(self, context, request):
        self.context = context
        self.request = request

    def __call__(self):
        # Implement your own actions

        # This renders the template that was registered in zcml like this:
        #   template="templates/demoview.pt"
        return super(DemoView, self).__call__()
        # If you don't register a template in zcml the Superclass of
        # DemoView will have no __call__-method!
        # In that case you have to call the template like this:
        # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
        # class DemoView(BrowserView):
        # template = ViewPageTemplateFile('templates/demoview.pt')
        # def __call__(self):
        #    return self.template()

I need to insert specific template/more templates by request (template-xxx) into view. The ReportView has separate template. The following code doesn't work https://docs.plone.org/develop/plone/views/browserviews.html#several-templates-per-view.

can you use a if/else statement?


class DemoView(BrowserView):
  
  def __init__(self, context, request):
    self.context = context
    self.request = request

  def __call__(self):
    if  'demo2' in self.request.form:
      template = ViewPageTemplateFile('templates/demoview2.pt')
    else:
      template = ViewPageTemplateFile('templates/demoview1.pt')
    
    return self.template()

No. I have a common view ReportView. I need insert into this view a template(s) depending on request parameters.
ReportView:

<metal:block fill-slot="content-core" tal:define="report view/get_report; template view/get_template">
 .............
                    <div tal:replace="structure view/render_task" />
 .............
</metal:block>

I would not do it like that (someone: please correct me if I am wrong).

I would make a view template, and define that template in ZCML ( or you can do it the BrowserView if you prefer that)

Then, in the browser view, I would use for example TAL, something like this:

 <div tal:replace='structure view/render_something' />

and in the view class (DemoView) you define something like

def render_something(self, request):
     a lot of logic here
     return '<p>some <b>thing</b></p>'

If that is not enough, you can define many render_something, put them in different fill slots etc.

... or you can return another browser view, or maybe inject things with pat-inject (?)