20. Escribiendo Viewlets¶
Un viewlet para el comportamiento social¶
Un viewlet no es una vista, pero es un fragmento de HTML y la lógica que se puede poner en varios lugares en el sitio. Estos lugares se llaman ViewletManager.
Inspeccione y administre los viewlets existentes yendo a la dirección URL http://localhost:8080/Plone/@@manage-viewlets.
Ya hemos personalizado un viewlet (archivo
collophon.pt). Ahora agregamos un nuevo viewlet.Los viewlets no guardan los datos (los portlets si lo hacen)
Los viewlets no tienen interfaz de usuario (los portlets lo hacen)
Ejercicio 1¶
Registrar una viewlet ‘number_of_talks ” en el pie de página que es visible sólo para los administradores (el permiso que usted busca es cmf.ManagePortal). Utilice sólo una plantilla (sin clase) para mostrar el número de charlas ya enviadas. Sugerencia: Utilice Adquisición para obtener al catálogo (Usted sabe, no debe hacer esto, pero hay un montón de código por ahí que lo hace...)
Solución
Registrar el viewlet en el archivo browser/configure.zcml
<browser:viewlet
name="number_of_talks"
for="*"
manager="plone.app.layout.viewlets.interfaces.IPortalFooter"
layer="zope.interface.Interface"
template="templates/number_of_talks.pt"
permission="cmf.ManagePortal"
/>
Para los parámetros for y layer el * es la abreviatura de zope.interface.Interface y el mismo efecto que la omisión de ellos: El viewlet se mostrará para todos los tipos de páginas y para todos los sitios de Plone en su instancia Zope.
Agregar el archivo de la plantilla browser/templates/number_of_talks.pt:
<div class="number_of_talks"
tal:define="catalog python:context.portal_catalog;
talks python:len(catalog(portal_type='talk'));">
There are <span tal:replace="talks" /> talks.
</div>
python:context.portal_catalog devolverá el catálogo a través de la adquisición. Tenga cuidado si usted desea usar expresiones de rutas: content/portal_catalog llama el catálogo (y devuelve todos los cerebros). Es necesario para evitar esto usando nocall:content/portal_catalog.
Basándose en Adquisición es una mala idea. Sería mucho mejor utilizar la helper view plone_tools desde el módulo plone/app/layout/globals/tools.py para obtener el catálogo.
<div class="number_of_talks"
tal:define="catalog context/@@plone_tools/catalog;
talks python:len(catalog(portal_type='talk'));">
There are <span tal:replace="talks" /> talks.
</div>
context/@@plone_tools/catalog atraviesa a la vista plone_tools y llama a su método catalog. En expresiones Python debería verse así:
<div class="number_of_talks"
tal:define="catalog python:context.restrictedTraverse('plone_tools').catalog();
talks python:len(catalog(portal_type='talk'));">
There are <span tal:replace="talks" /> talks.
</div>
No es una buena práctica consultar el catálogo dentro de una plantilla, ya que incluso la simple lógica como este debería vivir en Python. Pero es muy poderoso si está depurando o necesita una solución rápida y sucia.
Ejercicio 2¶
Registrar una viewlet ‘days_to_conference’ en la cabecera. Utilice una clase y una plantilla para mostrar el número de días hasta la conferencia. Usted consigue muchos puntos de bonificación si se muestra en un formato agradable (pensar “En 2 días” y “Último mes”) utilizando un Javascript existentes o biblioteca Python.
El viewlet social-viewlet¶
Vamos a añadir un enlace al sitio que utiliza la información que hemos recopilado utilizando el comportamiento social.
Registramos el viewlet en el archivo
browser/configure.zcml.Esto registra un viewlet llamado
social. Es visible en todos los contenidos que implementa la interfazISocialde nuestro comportamiento. También es una buena práctica de obligar a la BrowserLayer llamadaIPloneconfSiteLayerde nuestro complemento por lo que sólo se muestra si nuestro complemento se instala en realidad.La clase viewlet
SocialViewletse espera en un archivobrowser/viewlets.py.Esta clase no hace nada excepto hacer que la plantilla asociada (Eso tenemos que escribir aún)
Nota
Si utilizamos
Grokno necesitaríamos registrar los viewlets en el archivoconfigure.zcmlpero si hay que hacerlo en código Python. Nos gustaría añadir un archivo viewlets.py que contiene la clase viewlet.Esto haría lo mismo que el código anterior utilizando el paradigma de Grok de la convención sobre configuración. En las browser views la referencia es llamada view, tenga en cuenta que en las viewlets Grok se llama viewlets (en ese caso
viewlet/lanyrd_link).Vamos a agregar el archivo de la plantilla restante
templates/social_viewlet.pt.Como se puede ver esto no es un documento válido HTML. Eso no es necesario, porque no queremos una visión completa aquí, sólo un fragmento de código HTML.
Hay una sentencia
tal:define, para las consultas view/lanyrd_link. Al igual en la page templates de la plantilla tiene acceso a su clase.Tenemos que ampliar el Viewlet Social ahora para añadir el atributo que le falta:
¿Por qué no acceder directamente contexto?
En este ejemplo,
ISocial(self.context)devuelve el contexto directamente. Todavía es bueno utilizar este idioma por dos razones:Por lo tanto, en este ejemplo, usted puede simplemente escribir
return self.context.lanyrd.Hasta ahora, hemos hecho: