16. Personalizar plantillas existentes

Para profundizar más en los datos real de plone, nosotros ahora miraremos algunas plantillas existentes y las personalizaremos.

El archivo newsitem.pt

Queremos mostrar la fecha de una Noticia se publica. De esta manera la gente puede ver a simple vista que la está mirando es una noticia de actualidad o una noticia antigua.

Para ello vamos a personalizar las plantillas que es utilizanda para representar una Noticia.

Básicamente haremos lo mismo que cuando se utilizó en portal_skins (personalizamos el pie de página), pero ahora vamos a hacerlo todo a mano en nuestro paquete.

  • Cree el directorio browser/template_overrides

  • Agregue el siguiente en el archivo browser/configure.zcml:

<browser:jbot directory="template_overrides" />
  • Para completar, agregue z3c.jbot a las dependencias en el archivo setup.py a la lista install_requires.

  • Buscar el archivo plone/app/contenttypes/browser/templates/newsitem.pt en el directorio omelette (en la instalación Vagrant esto esta en /home/vagrant/omelette).

  • Cópielo dentro de la nueva carpeta, ejecutando el siguiente comando Linux: cp /home/vagrant/omelette/plone/app/contenttypes/browser/templates/newsitem.pt /vagrant/buildout/src/ploneconf.site/ploneconf/site/browser/template_overrides

  • Renombre el nuevo archivo desde newsitem.pt a plone.app.contenttypes.browser.templates.newsitem.pt.

  • Reinicie Plone

Ahora Plone debería usar el nuevo archivo sobrescribiendo el original.

Edite la plantilla plone.app.contenttypes.browser.templates.newsitem.pt e inserte el siguiente código antes el <div id="parent-fieldname-text"...:

<p tal:content="python: context.Date()">
    The current Date
</p>
  • Abra un existente elemento de Noticia en el navegador Web

Esto mostrara algo como esto: 2013-10-02 19:21:15. No es muy amigable. Vamos a ampliar el código y utilizar una de las muchas funciones helpers que ofrece Plone.

<p tal:define="toLocalizedTime nocall:context/@@plone/toLocalizedTime;
               date python:context.Date()"
   tal:content="python:toLocalizedTime(date)">
        The current Date in its local short-format
</p>

Ahora debería verse la fecha en un formato amigable como 17.02.2013.

  • Con nocall: prevenimos que el método toLocalizedTime sea llamado, ya que sólo queremos que esté disponible para su uso.

  • El método toLocalizedTime es proveído por la BrowserView Products.CMFPlone.browser.ploneview.Plone y ejecuta el objeto Date (tipo Fecha) a través del translation_service de Plone y regresa la Fecha en el actual formato de locales, así transformando 2013-02-17 19:21:15 en 17.02.2013.

En antigua versiones de Plone nosotros usamos python:context.toLocalizedTime(context.Date(), longFormat=False). Que llamo al script python toLocalizedTime.py en la Carpeta Products/CMFPlone/skins/plone_scripts/.

Esa carpeta plone_scripts todavía tiene una gran cantidad de scripts útiles que son ampliamente utilizados. Pero todos ellos están obsoletos y honestamente se espera retirar en Plone 5 los cuales sean reemplazados por métodos Python adecuados en BrowserViews.

El archivo summary_view.pt

Utilizamos la vista “Vista de resumen” a la lista de noticias publicadas. También deben tener la fecha. La plantilla asociada con esa vista es summary_view.pt.

Echemos un vistazo a la plantilla folder_summary_view.pt:

plone/app/contenttypes/browser/templates/summary_view.pt

Cópielo al directorio browser/template_overrides/ y renómbrelo a plone.app.contenttypes.browser.templates.summary_view.pt.

Agregue lo siguiente después de la linea 29:

<p tal:condition="python:item_type == 'News Item'"
   tal:content="python:toLocalizedTime(item.Date())">
        News date
</p>

El método toLocalizedTime ya está definido en la plantilla cuya macro usa esta plantillas. ¿Porqué es eso?

El secreto es la linea del archivo summary_view.pt:

<metal:block use-macro="context/standard_view/macros/entries">

use-macro le dice a Plone reusar el macro entries desde la vista standard_view la cual se encuentra en la plantilla plone/app/contenttypes/browser/templates/standard_view.pt.

Las plantillas summary_view.pt y folder_summary_view.pt (las cuales es lo mismo, pero para las carpetas, no para las colecciones) están muy difundidas y también ampliamente personalizadas, para requisitos particulares, por lo que también podría llegar a conocerlo un poco.

Nuestra adiciones hace que la fecha de los objetos respectivo que las iteraciones de plantilla (por lo tanto item en lugar de context desde context sería la colección de la agregación de las noticias).

La fecha solamente es mostrada si la variable item_type (definida en la linea 42 de la vista standard_view.pt) sea News Item.

Hay mucho más en standard_view.pt y summary_view.pt pero vamos a dejar las cosas así.

Nota

En defecto de Plone sin plone.app.contenttypes esto sería folder_summary_view.pt, una plantilla skin de Archetypes se puede encontrar en la carpeta Products/CMFPlone/skins/plone_content/. La plantilla personalizada sería Products.CMFPlone.skins.plone_content.folder_summary_view.pt.

La plantilla Archetypes de Noticia es newsitems_view.pt de la misma carpeta. La plantilla personalizada tendría que ser nombrada Products.CMFPlone.skins.plone_content.folder_summary_view.pt.

¡Tenga en cuenta que no sólo los nombres han cambiado, sino también el contenido!

Buscando la correcta plantilla

Hemos cambiado la pantalla de la lista de elementos de noticias en http://localhost:8080/Plone/news. Pero, ¿cómo sabemos que plantilla para personalizar?

Si usted no sabe con qué plantilla utiliza la página que estás viendo, usted puede hacer una conjetura, iniciar una sesión de depuración o use el paquete plone.app.debugtoolbar para obtener una vista que ofrece información de depuración del actual contexto.

  1. Pudimos comprobar el HTML con la herramienta Firebug y buscar una estructura en el área de contenido que parece único. También podríamos buscar la clase CSS del cuerpo

    <body class="template-summary_view portaltype-collection site-Plone section-news subsection-aggregator icons-on userrole-anonymous" dir="ltr">
    

    La clase template-summary_view nos dice que el nombre de la vista (pero no necesariamente el nombre de la plantilla) el cual es summary_view. Así que podríamos buscar en todos los archivos *.zcml la cadena name="summary_view" o buscar todas las plantillas llama summary_view.pt y probablemente encontrar la vista y también la plantilla correspondiente. Pero probablemente sólo porque esa no nos diría si ya está siendo sobrescrita la plantilla.

  2. El método es más seguro está usando el paquete plone.app.debugtoolbar. Ya lo tenemos en nuestra configuración buildout definidos y sólo hay que instalarlo. Ese agregue un menú desplegable “Debug” en la parte superior de la página. La sección “Publicado” muestra la ruta completa a la plantilla que se utiliza para representar la página que estás viendo.

  3. La sesión de depuración para encontrar la plantilla es un poco más complicado. Entonces tenemos el producto Products.PDBDebugMode en nuestra configuración buildout podemos llamar /pdb desde nuestra página.

    El objeto que las URL apunta por defecto self.context. Pero el primer problema es que la dirección URL que estamos viendo no es la dirección URL de la colección en la que queremos modificar ya que la colección es la página por defecto de la carpeta news.

    >>> (Pdb) self.context
    <Folder at /Plone/news>
    >>> (Pdb) obj = self.context.aggregator
    >>> (Pdb) obj
    <Collection at /Plone/news/aggregator>
    >>> (Pdb) context_state = obj.restrictedTraverse('@@plone_context_state')
    >>> (Pdb) template_id = context_state.view_template_id()
    >>> (Pdb) template_id
    'summary_view'
    >>> (Pdb) view = obj.restrictedTraverse('summary_view')
    >>> (Pdb) view
    <Products.Five.metaclass.SimpleViewClass from /Users/philip/.cache/buildout/eggs/plone.app.contenttypes-1.1b2-py2.7.egg/plone/app/contenttypes/browser/templates/summary_view.pt object at 0x10b00cd90>
    >>> view.index.filename
    u'/Users/philip/workspace/training_without_vagrant/src/ploneconf.site/ploneconf/site/browser/template_overrides/plone.app.contenttypes.browser.templates.summary_view.pt'
    

    Ahora puede ver que nosotros personalizamos la plantilla.

Plantillas skins

¿Por qué no siempre sólo utilizamos plantillas? Porque lo que se quiere hacer es algo más complicado que obtener un atributo de formulario en el contexto y hacer su valor en alguna etiqueta HTML.

Es una tecnología obsoleta llamada ‘skin-templates’ que le permite añadir simplemente alguna página en la plantilla (por ejemplo, ‘old_style_template.pt’) a una carpeta determinada en el ZMI o su paquete egg) y se puede acceder a ella en el navegador mediante la dirección URL como esta http://localhost:8080/Plone/old_style_template y se mostrara. Pero nosotros no lo usamos y usted también no hay que a pesar de que estos de las skin-templates siguen siendo todo Plone.

Desde que usamos el paquete plone.app.contenttypes no encontramos nunca más muchas plantillas skin cuando se trata de contenidos. Pero más a menudo que usted no tendrás que personalizar un sitio antiguo que aún utiliza la plantillas skin.

Las plantillas Skins y los script Python están ubicados en la herramienta portal_skin están descontinuados porque:

  • ellos son Python restringido

  • no tienen buena manera de adjuntar código Python a ellos

  • ellos son siempre invocable para todo el mundo (ellos no pueden ser fácilmente unidos a una interfaz)