Views II: A Default View for “Talk”

In this part you will:

  • Register a view with a python class
  • Write a template used in the default view for talks

Topics covered:

  • View classes
  • BrowserView and DefaultView
  • displaying data from fields

View Classes

Anteriormente hemos escrito una vista de demostración que también utilizamos para experimentar con las plantillas de página. Vamos a echar un vistazo a la zcml y la plantilla de página de nuevo. Yo he ampliado el código sólo un poco.

browser/configure.zcml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<configure xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    i18n_domain="ploneconf.site">

    <browser:page
       name="demoview"
       for="*"
       layer="zope.interface.Interface"
       class=".views.DemoView"
       template="templates/demoview.pt"
       permission="zope2.View"
       />

</configure>

browser/views.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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()

¿Recuerdas el término MultiAdapter? La browser page es sólo un MultiAdapter. La declaración ZCML browser:page registra un MultiAdapter y agrega cosas adicionales que se necesitan para una vista del navegador.

Un adaptador adapta cosas, un MultiAdapter adapta múltiple cosas.

When you enter a url, Zope tries to find an object for it. At the end, when Zope does not find any more objects but there is still a path item left, or there are no more path items, Zope looks for an adapter that will reply to the request.

El adaptador se adapta la solicitud y el objeto que Zope ha encontrado con la URL. La clase de adaptador se crea instanciada con los objetos que han de adaptarse, entonces se llama.

El código anterior hace la misma cosa que la implementación estándar haría. Hace que el contexto y la solicitud esten disponibles como variables en el objeto.

I have written down these methods because it is important to understand some important concepts.

The init method gets called while Zope is still trying to find a view. At that phase, the security has not been resolved. Your code is not security checked. For historical reasons, many errors that happen in the init method can result in a page not found error instead of an exception.

No hagas mucho a todos en el método init. En su lugar usted tiene la garantía que el método call es llamado antes de cualquier otra cosa (excepto el método init). Tiene los controles de seguridad en su lugar y así sucesivamente.

Desde un punto de vista práctico, considere el método call en su método init, la mayor diferencia es que este método debe retornar el HTML ya. Deje a su clase base manejar la generación de HTML.

The default view

Now we finally add the default view for talks in views.py

browser/configure.zcml

<browser:page
   name="talkview"
   for="*"
   layer="zope.interface.Interface"
   class=".views.TalkView"
   template="templates/talkview.pt"
   permission="zope2.View"
   />

browser/views.py

from plone.dexterity.browser.view import DefaultView

...

class TalkView(DefaultView):
    """ The default view for talks
    """

The DefaultView base class in plone.dexterity only exists for Dextertity Objects and has some very useful properties available to the template:

  • view.w es un diccionario de todos los widgets de pantalla, con clave de nombres de campos. Esto incluye widgets de conjunto de campos alternativos.

  • view.widgets contiene una lista de widgets en esquema para el conjunto de campos predeterminado.

  • view.groups contiene una lista de conjunto de campos con el fin de ordenar conjunto de campo.

  • view.fieldsets contiene un nombre de conjunto de campo mapeado un diccionario a conjunto de campo

  • En un conjunto de campos (grupo), puede acceder a una lista de widgets para obtener los widgets en ese conjunto de campo

Nota

plone.dexterity.browser.view.DefaultView has the same features as the grok equivalent plone.directives.dexterity.DisplayForm.

La plantilla templates/talkview.pt usa el patrón view/w/<fieldname>/render para hacer algunos widgets.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
    lang="en"
    metal:use-macro="context/main_template/macros/master"
    i18n:domain="ploneconf.site">
<body>
    <metal:content-core fill-slot="content-core">
        <p>Suitable for <em tal:replace="structure view/w/audience/render"></em>
        </p>

        <div tal:content="structure view/w/details/render" />

        <div tal:content="context/speaker">
            User
        </div>
    </metal:content-core>
</body>
</html>

After a restart, we can test our view by going to a talk and adding /talkview to the url.

We should tell Plone that the talkview should be used as the default view for talks instead of the built-in view.

Esta es una configuración que puede cambiar en tiempo de ejecución y se almacena en la base de datos, como tal, también es gestionado por perfiles GenericSetup.

abrir profiles/default/types/talk.xml:

1
2
3
4
5
6
7
...
<property name="default_view">talkview</property>
<property name="view_methods">
    <element value="talkview"/>
    <element value="view"/>
</property>
...

We will have to either reinstall our addon or run the GenericSetup import step typeinfo so Plone learns about the change.

Nota

To change it ttw got to the ZMI (http://localhost:8080/Plone/manage), go to portal_types and select the type for which the new view should be selectable (talk). Now add talkview to the list Available view methods. Now the new view is available in the menu Display. To make it the default view enter it in Default view method.

Mejoremos la vista talkview para mostrar toda la información que queremos.

templates/talkview.pt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
      metal:use-macro="context/main_template/macros/master"
      i18n:domain="ploneconf.site">
<body>
    <metal:content-core fill-slot="content-core">

        <p>
            <span tal:content="context/type_of_talk">
                Talk
            </span>
            suitable for
            <span tal:replace="structure view/w/audience/render">
                Audience
            </span>
        </p>

        <div tal:content="structure view/w/details/render">
            Details
        </div>

        <div class="newsImageContainer">
            <img tal:condition="python:getattr(context, 'image', None)"
                 tal:attributes="src string:${context/absolute_url}/@@images/image/thumb" />
        </div>

        <div>
            <a class="email-link" tal:attributes="href string:mailto:${context/email}">
                <strong tal:content="context/speaker">
                    Jane Doe
                </strong>
            </a>
            <div tal:content="structure view/w/speaker_biography/render">
                Biography
            </div>
        </div>

    </metal:content-core>
</body>
</html>

Exercise

Add the new choice field “room” to the Talk type (TTW) and display it below Audience in the browser view, it should contain the following data:

  • Title: Room
  • Possible values: Room 101, Room 102, Auditorium

Solution

<p>
    <span tal:replace="structure view/w/room/render">
        Room
    </span>
</p>