<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns="http://purl.org/rss/1.0/">




    



<channel rdf:about="http://www.plone-es.org/noticias/aggregator/RSS">
  <title>Noticias y articulos</title>
  <link>http://www.plone-es.org</link>

  <description>
    
      
    
  </description>

  

  
            <syn:updatePeriod>daily</syn:updatePeriod>
            <syn:updateFrequency>1</syn:updateFrequency>
            <syn:updateBase>2011-12-23T08:56:25Z</syn:updateBase>
        

  <image rdf:resource="http://www.plone-es.org/logo.png"/>

  <items>
    <rdf:Seq>
      
        <rdf:li rdf:resource="http://www.plone-es.org/articulos/plone-4-e-ie9"/>
      
      
        <rdf:li rdf:resource="http://www.plone-es.org/articulos/implementacion-de-la-libreria-jquery-tools-i-plone-para-el-efecto-scrollable"/>
      
      
        <rdf:li rdf:resource="http://www.plone-es.org/articulos/validador-de-titulos-duplicados-para-plone-4.x"/>
      
      
        <rdf:li rdf:resource="http://www.plone-es.org/articulos/importar-datos-csv-en-plone"/>
      
      
        <rdf:li rdf:resource="http://www.plone-es.org/articulos/subscripcion-de-usuarios-a-objetos-plone-con-envio-de-notificaciones"/>
      
    </rdf:Seq>
  </items>

</channel>


  <item rdf:about="http://www.plone-es.org/articulos/plone-4-e-ie9">
    <title>Plone 4 + IE9</title>
    <link>http://www.plone-es.org/articulos/plone-4-e-ie9</link>
    <description>La incompatibilidad de Plone con Internet Explorer 9</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Actualmente Plone e IE9 no son totalmente compatibles. El editor que utiliza por defecto en su versión 4 (TinyMCE) tiene problemas graves de incompatibilidad con esta versión del navegador, imposibilitando al completo la edición de contenidos.</p>
<p>Al intentar editar el contenido en el editor no funcionan ninguna de las opciones para dar formato, insertar enlaces, imágenes, etc. Se puede introducir texto pero al guardar el formulario éste se pierde.</p>
<p>Ocurren 2 errores de javascript, uno al cargar la página:</p>
<pre>SCRIPT438: El objeto no acepta la propiedad o el método 'recalc' 
tiny_mce.js, Línea 3 Carácter 20015</pre>
<p>Y un segundo al hacer click sobre el editor:</p>
<pre>SCRIPT438: El objeto no acepta la propiedad o el método 'parentElement' 
tiny_mce.js, Línea 3 Carácter 64632</pre>
<p>Al parecer el bug persiste en la versión actual de Plone (4.1.4), que utiliza la versión 1.2.10 de TinyMCE.</p>
<p> </p>
<p>Mientras esperamos una solución oficial, el arreglo temporal que nos plantean en el siguiente <a class="external-link" href="https://dev.plone.org/ticket/11690" target="_blank">enlace</a> es el de forzar el DOCTYPE para que se pueda visualizar como si se tratara de IE8:</p>
<p> </p>
<ol>
<li>1. Customizamos la main_template</li>
<li>2. Remplazamos la línea:</li>
<li>
<pre>&lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&gt;</pre>
<p>con:</p>
<pre>&lt;meta http-equiv="X-UA-Compatible" content="IE=8" /&gt;</pre>
</li>
<li>
<p>3. Dado que se modifica la main_template, se forzará en toda la web, así que podemos condicionarlo para que solo se muestre en la plantilla de edición (atct_edit), quedando así nuestro código:</p>
<pre><div><meta content="IE=8" http-equiv="X-UA-Compatible" /></div><div id="_mcePaste" style="width: 1px; height: 1px;"></div><div id="_mcePaste" style="width: 1px; height: 1px;">&lt;div tal:omit-tag="" tal:condition="python: template.id != 'atct_edit'"&gt;&lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&gt;&lt;/div&gt;</div>
&lt;div tal:omit-tag="" tal:condition="python: template.id == 'atct_edit'"&gt;&lt;meta http-equiv="X-UA-Compatible" content="IE=8" /&gt;&lt;/div&gt;</pre>
</li>
</ol>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Javier Díaz</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2012-05-15T15:54:48Z</dc:date>
    <dc:type>Noticia</dc:type>
  </item>


  <item rdf:about="http://www.plone-es.org/articulos/implementacion-de-la-libreria-jquery-tools-i-plone-para-el-efecto-scrollable">
    <title>Implementación de la librería Jquery Tools y Plone para el efecto scrollable.</title>
    <link>http://www.plone-es.org/articulos/implementacion-de-la-libreria-jquery-tools-i-plone-para-el-efecto-scrollable</link>
    <description>El objetivo es lograr que nuestro código genere una serie de banners agrupados para que el Jquery los desplace en grupos del número deseado. Se trata de controlar el número de banners y los grupos a realizar. El código controla si el banner dispone de enlace interno, externo o ninguno de ellos.</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Según la documentación de la pagina oficial:</p>
<p><a href="http://jquerytools.org/demos/scrollable/index.html">http://jquerytools.org/demos/scrollable/index.html</a></p>
<p>No disponemos a desarrollar este efecto en Plone 4.</p>
<p>Para ello dispondremos de los siguientes recursos.</p>
<ul>
<li>Librería del Jquery Tools </li>
</ul>
<pre>&lt;script src="http://cdn.jquerytools.org/1.2.7/full/jquery.tools.min.js"&gt;&lt;/script&gt;
</pre>
<p> </p>
<ul>
<li>El código de Jquery que llama a la función Scrollable. Ej:</li>
</ul>
<pre>&lt;script type="text/javascript"&gt;<br />     $(function() {<br />         $(".scrollable").scrollable({ circular: true }).autoscroll(/*{ autoplay: true, interval: 7000 }*/);<br />     });<br />&lt;/script&gt;</pre>
<p> </p>
<ul>
<li>El script de Python que realizará las consultas y operaciones  pertinentes</li>
</ul>
<p> </p>
<ul>
<li>Finalmente el código html que generara la estructura de código deseada para realizar el efecto de scroll en grupo.</li>
</ul>
<p> </p>
<p>El objetivo es lograr que nuestro código genere una serie de banners agrupados para que el Jquery los desplace en grupos del número deseado. Se trata de controlar el número de banners y los grupos a realizar. El código controla si el banner dispone de enlace interno, externo o ninguno de ellos.</p>
<p>La manera en que opera el script python:</p>
<p>En este caso concreto por las necesidades del site le enviamos al script un par de parámetros. El primero designa la ruta en donde queremos que haga la consulta de elementos tipo banner y el segundo parámetro designa el número de elementos por grupo que queremos mostrar.</p>
<p>Una vez en el código python vemos que este realiza una primera consulta para saber cuántos elementos entran en juego. Con este dato y jugando con el valor de elementos por grupo, resolvemos el número de grupos que necesitamos, mediante las funciones <b>int(math.ceil(num/elements)) </b>.Finalmente con este dato realizamos una batería de consultas, aumentado el rango en cada una de las vueltas del bucle. Todas estas consultas las vamos almacenando en una matriz, para después ser tratados con el código tal/metal .</p>
<pre>request = container.REQUEST<br />import math<br />idiomactual = context.REQUEST.other['LANGUAGE']<br />from Products.CMFCore.utils import getToolByName<br />urltool = getToolByName(context, 'portal_url')<br /><br />llista = []<br />pathSeccio = urltool.getPortalPath()+ '/'+idiomactual+'/'+posicio<br /><br />if elements == None:<br /> elements = 4<br /><br />result1 = context.portal_catalog({'meta_type':{'query':['Noubanner']},<br />                                  'sort_on':'getObjPositionInParent',<br />                                  'sort_order':'ascending',<br />                                  #'review_state':'published',<br />                                  'path':{'query':pathSeccio,'level':0,'depth':1},<br />                                 })<br /><br />inici = 0<br />final = inici + elements<br />num = float(len(result1))<br />voltes = int(math.ceil(num/elements))<br />index = 1<br /><br />for volta in range(voltes):<br />    result = context.portal_catalog({'meta_type':{'query':['Noubanner']},<br />                                     'sort_on':'getObjPositionInParent',<br />                                     'sort_order':'ascending',<br />                                     #'review_state':'published',<br />                                     'path':{'query':pathSeccio,'level':0,'depth':1},<br />                                    })[inici:final]<br /><br />    llista.append(result)<br />    inici = index * elements    <br />    final = inici + elements<br />    index = index + 1   <br /> <br />return llista<br /><br /></pre>
<p> </p>
<p>Finalmente para lograr generar el código html deseado:</p>
<p>Hacemos un doble bucle con la array obtenida en el paso anterior, mediante los tal:repeat anidados. Con el primer bucle obtenemos los divs que agruparan los banners y con el bucle anidado, los diferentes banners, que nos llegan de cada una de las consultas.</p>
<p> </p>
<pre>&lt;div class="banersRelacionat" tal:define="grups python:here.showBannersGrup('banersportada',6)"&gt;<br /> &lt;a class="left browse prev"&gt;&lt;/a&gt;<br /> &lt;div class="scrollable"&gt;<br /> &lt;div class="items"&gt;<br /> &lt;div tal:repeat="grup grups" class="grup"&gt;<br /> &lt;div tal:omit-tag="" tal:repeat="section grup"&gt;<br /> &lt;div  tal:omit-tag="" tal:define="objecte section/getObject" &gt;<br /> &lt;div tal:omit-tag="" tal:condition="not:objecte/exclude_from_nav" tal:define="extern objecte/getEnllacExtern;intern objecte/getEnllacIntern"&gt;<br /> &lt;div tal:omit-tag="" tal:condition="objecte/getEnllacExtern" class="baner"&gt;<br /> &lt;a tal:attributes="href objecte/getEnllacExtern;title section/Title;" tal:define="dir section/getURL;" target="_blank"&gt;<br /> &lt;img tal:attributes="src string:$dir/image;alt section/Title;"/&gt;<br /> &lt;/a&gt;<br /> &lt;/div&gt;<br /> &lt;div tal:omit-tag="" tal:condition="objecte/getEnllacIntern" class="baner"&gt;<br /> &lt;div tal:omit-tag="" tal:define="intLink objecte/getEnllacIntern;"&gt;<br /> &lt;a tal:attributes="href intLink/absolute_url|nothing;title section/Title;" tal:define="dir section/getURL;"&gt;<br /> &lt;img tal:attributes="src string:$dir/image;alt section/Title;"/&gt;<br /> &lt;/a&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;div tal:omit-tag="" tal:condition="not:intern"&gt;<br /> &lt;div tal:condition="not:extern" class="baner" tal:define="dir section/getURL;" tal:omit-tag=""&gt;<br /> &lt;div tal:omit-tag="" tal:define="intLink objecte/getEnllacIntern;"&gt;<br /><br /> &lt;img tal:attributes="src string:$dir/image;alt section/Title;"/&gt;<br /><br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;/div&gt;<br /> &lt;a class="right browse next"&gt;&lt;/a&gt;<br /> &lt;div class="separador"&gt;&lt;/div&gt;<br />&lt;/div&gt;</pre>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>aormazabal</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2012-04-27T13:10:00Z</dc:date>
    <dc:type>Noticia</dc:type>
  </item>


  <item rdf:about="http://www.plone-es.org/articulos/validador-de-titulos-duplicados-para-plone-4.x">
    <title>Validador de titulos duplicados para Plone 4.x</title>
    <link>http://www.plone-es.org/articulos/validador-de-titulos-duplicados-para-plone-4.x</link>
    <description></description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Un validador para Plone 4.x que permite avisar al usuario si ha introducido un elemento con un titulo duplicado. El funcionamiento por defecto del gestor es crear igualmente un elemento modificando el valor del id añadiendo un número, y así podemos tener elementos que comparten el campo Title.</p>
<p>Con este validador, que se puede añadir a cualquier tipo de contenido, podemos avisar al usuario y evitar que entre contenidos duplicados.</p>
<p><a href="https://gist.github.com/1724336">https://gist.github.com/1724336</a></p>
<pre>from zope.component import adapts
from Products.Archetypes.interfaces import IObjectPostValidation
from Products.PythonScripts.standard import html_quote
from Products.CMFCore.utils import getToolByName
from Products.statusmessages.interfaces import IStatusMessage
from aeau.contenttypes import contenttypesMessageFactory as _
from aeau.contenttypes.interfaces import ISoci

from Acquisition import aq_inner
from Acquisition import aq_parent

class ValidateUniqueTitle(object):
    """
    Checks if there's an object with the same title inside the folder where the new item it's being created.
    In this example i'm using my own content type: aeau.contenttypes.soci
    """

    implements(IObjectPostValidation)
    adapts(ISoci)

    # Name of the field in which the validator will be applied
    field_name = 'title'

    def __init__(self, context):
        self.context = context

    def __call__(self, request):
        value = request.form.get(self.field_name, request.get(self.field_name, None))

        if value is not None:
            messages = IStatusMessage(request)
            catalog = getToolByName(self.context, "portal_catalog")
            plone_utils = getToolByName(self.context, 'plone_utils', None)

            parent = aq_parent(aq_inner(self.context))

            # Get the object metatype that we are going to create
            object_type = self.context.Type()

            # Actual folder where the object is going to be created, ignoring the portal_factory check
            object_folder = str('/'.join(parent.getPhysicalPath()))
            object_folder = object_folder.replace('/portal_factory/'+object_type,'')

            results = self.context.portal_catalog.searchResults(portal_type=object_type,
                                                                path={'query':object_folder,'level':0,'depth':1},
                                                                Title=value)

            for result in results:
                if self.context.UID() == result.getObject().UID():
                    return None

            if results:
                messages.addStatusMessage(_(u'There is an object in this folder with the same type and title'), type="error")
                return { self.field_name: '' }

        # Returning None means no error
        return None
</pre>
<p>via: <a class="external-link" href="http://marcpampols.com/post/16931637851/validador-de-titulos-duplicados-para-plone-4-x">http://marcpampols.com/post/16931637851/validador-de-titulos-duplicados-para-plone-4-x</a></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Marc Pampols</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2012-04-02T14:05:00Z</dc:date>
    <dc:type>Noticia</dc:type>
  </item>


  <item rdf:about="http://www.plone-es.org/articulos/importar-datos-csv-en-plone">
    <title>Importar datos CSV en Plone</title>
    <link>http://www.plone-es.org/articulos/importar-datos-csv-en-plone</link>
    <description></description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>He subido un pequeño script en Python en el Github Gist, que pertenece a una vista de un producto de Plone, y que puede utilizarse como base para importar datos de un fichero CSV en tipos de contenido.</p>
<p>Muy sencillo para tener una idea de cómo hacerlo, y fácilmente adaptable a la necesidad de cada uno.</p>
<p>Import CSV data to Plone content type: <br /> <a href="https://gist.github.com/2256740">https://gist.github.com/2256740</a></p>
<pre># -*- coding: utf-8 -*-
import datetime
import urllib

from Acquisition import aq_inner

from zope import interface
from zope import schema

from zope.app.pagetemplate import viewpagetemplatefile
from zope.app.component.hooks import getSite

from Products.CMFCore.utils import getToolByName
from Products.Five import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from Products.statusmessages.interfaces import IStatusMessage

# Control BadRequest errors (duplicate id's found)
try: from zExceptions import BadRequest
except ImportError: BadRequest = 'BadRequest'

# Control errors caused by WebDAV open objects in Plone durint import
from Products.CMFDefault.exceptions import ResourceLockedError

import StringIO
import csv

class Import(BrowserView):

    # Template where we show the import results
    template = viewpagetemplatefile.ViewPageTemplateFile('import.pt')

    # Import function
    def render(self):
        plone_utils = getToolByName(self.context, 'plone_utils')
        workflowTool = getToolByName(self.context, "portal_workflow")

        # Read the CSV file
        csv_contents = str(self.context)
        f = StringIO.StringIO(csv_contents)
        file = f.read()
        csv_reader = csv.reader(file.splitlines(), delimiter=';')

        # Counting successful and failed register imports
        stats_ok = 0
        stats_failed = 0

        # Set the name of the content type to create
        content_type = "Name of the Content Type"

        headers = 0
        for field in csv_reader:
            if (headers == 1):
               
                # Set the csv values to new python variables and do the proper processing for each register
                obj_id          = plone_utils.normalizeString(unicode(field[0]))
                obj_title       = str(field[1])
                obj_descripcion = str(field[2])
                
                # Try to create the object in Plone
                try:
                    subfolder_item[1].invokeFactory(content_type, obj_id)
                    obj_newObject = getattr(self, obj_id)
                    obj_newObject.setTitle(obj_title)
                    obj_newObject.setDescription(obj_description)
                    obj_newObject.reindexObject()
                    stats_ok += 1

                    except BadRequest:
                        print "Can't create object."
                        stats_failed += 1

                    except ResourceLockedError:
                        print "Can't create object, locked entry by WebDAV."
                        stats_failed += 1

            if (headers == 0):
                headers = 1

        return str("Import process results: CREATED: " + str(stats_ok) + " FAILED: " + str(stats_failed))

    def __call__(self):
        return self.render()
</pre>
<p>via: <a class="external-link" href="http://marcpampols.com/post/20191828115/importar-datos-csv-en-plone">http://marcpampols.com/post/20191828115/importar-datos-csv-en-plone</a></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Marc Pampols</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2012-04-02T13:55:00Z</dc:date>
    <dc:type>Noticia</dc:type>
  </item>


  <item rdf:about="http://www.plone-es.org/articulos/subscripcion-de-usuarios-a-objetos-plone-con-envio-de-notificaciones">
    <title>Subscripción de usuarios a objetos Plone con envío de notificaciones.</title>
    <link>http://www.plone-es.org/articulos/subscripcion-de-usuarios-a-objetos-plone-con-envio-de-notificaciones</link>
    <description></description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>He añadido un Gist público en Github con 3 funciones que pueden ser útiles si estás creando un sistema de suscripción a objetos de Plone, con envío de notificaciones por correo y opción de darse de baja a través de un enlace con un hash personalizado.</p>
<p>La idea es crear un tipo de contenido de Plone con un campo para guardar los suscriptores. Primero, una función add_subscriber() para añadirlos, que puede ser llamada desde cualquier acción en la web. Luego está la función sendEmail() que envía la notificación de, por ejemplo, actualización, a todos los suscriptores del objeto.</p>
<p>El correo enviado contiene un enlace con el objeto al que el usuario se ha suscrito, y un string secreto que nos permite comprobar que sólo el receptor del correo podrá darse de baja.</p>
<p>La función do_unsubscribe nos sirve para comprobar dicho string cuando el usuario hace click en el enlace, y darle de baja eliminando su cuenta de correo de dicho objeto Plone.</p>
<p>Add / Remove Plone object subscribers and send a notification email on state change:<br /> <a href="https://gist.github.com/2265553">https://gist.github.com/2265553</a></p>
<p>Via: <a class="external-link" href="http://marcpampols.com/post/20226818731/subscripcion-de-usuarios-a-objetos-plone-con-envio-de">http://marcpampols.com/post/20226818731/subscripcion-de-usuarios-a-objetos-plone-con-envio-de</a></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Marc Pampols</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2012-04-02T13:55:00Z</dc:date>
    <dc:type>Noticia</dc:type>
  </item>





</rdf:RDF>

