jueves, 27 de octubre de 2011

Anidando CDATAs, o cómo no morir personalizando el CoreResultsWebPart

Cada vez que he tenido que hacer una personalización del elemento web de resultados de búsqueda de SharePoint (CoreResultsWebPart) me he encontrado con el mismo problema: el despliegue. La teoría es muy simple, sobre un sitio creado se edita el elemento web, se obtiene el valor del campo XSL, se edita con cualquier editor de XSL, se guarda el webpart con el nuevo valor de la propiedad hasta que obtenemos el resultado deseado y finalmente exportamos el elemento web para insertarlo donde nos convenga en nuestro paquete de despliegue.

¿Pero qué pasa cuando metemos variables en juego? En ocasiones tenemos que introducir valores multilenguaje o urls relativas a la colección de sitios en la que nos encontramos. Por cierto, si habéis llegado hasta aquí y no he despertado vuestro interés, o bien es por que tenéis totalmente resuelto este problema, o bien es porque no os habéis visto en la necesidad de crear algo productizable. Si, como digo, no he despertado vuestra curiosidad a estas alturas, os recomiendo no perder más tiempo en este artículo, ya escribiré cosas mejores Winking smile.

Bien, si seguís leyendo a estas alturas, imagino que estaréis esperando la fórmula mágica para hacer esta tarea un poquito más simple de lo habitual. Primero, dediquemos unas líneas al método tradicional. Una vez obtenido el valor para la propiedad XSL anteriormente mencionada, escapamos el código y lo insertamos en el XML de aprovisionamiento. Si habéis hecho esto en alguna ocasión, estaréis conmigo en que como se te escape algún pequeño error en este punto, depurarlo va a ser poco menos que imposible. Además, la próxima vez que hagas un cambio vas a tener que repetir todo el proceso. No sé a vosotros, pero a mí eso no me gusta nada de nada. Hasta hoy esto era un trance por el que tenía que pasar, pero el frotar se va a acabar…

Una solución, como habréis deducido del título del post, consiste en anidar CDATAs. Pero, ¡si no se puede! ¡si no está permitido según el estándar! Hoy he encontrado una solución muy original de un tal Nat Dunn y que podéis encontrar aquí. La solución consiste en utilizar el siguiente patrón, teniendo en cuenta que el primer CDATA contendría el elemento web y que el CDATA anidado contendría el valor de la propiedad XSL.

<![CDATA[
 
<![CDATA[<!-- Contenido del CDATA anidado -->]]]]><![CDATA[>
      
]]>

De acuerdo pero, ¿cómo queda esto al final? El siguiente listado muestra partes del fichero de aprovisionamiento con el que he hecho las pruebas. He dejado a propósito otra propiedad (SampleData) para demostrar las diferencias entre el modo habitual de tratar este tipo de propiedades y el modo que os estoy proponiendo.

<![CDATA[<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
  <metaData>
    <type name="..." />
  </metaData>
  <data>
    <properties>
      <property name="SampleData" type="string">&lt;All_Results&gt;
        &lt;Result&gt;
          &lt;workid&gt;1&lt;/workid&gt;
          &lt;rank&gt;222&lt;/rank&gt;
          &lt;title&gt;Title of document or web page&lt;/title&gt;
          &lt;author&gt;Author of document or web page&lt;/author&gt;
          &lt;size&gt;1025&lt;/size&gt;
          &lt;sitename&gt;http://www.sample.com&lt;/sitename&gt;
          &lt;url&gt;http://www.sample.com/folder/document.aspx&lt;/url&gt;
          &lt;imageurl&gt;/_layouts/images/aspx16.gif&lt;/imageurl&gt;
          &lt;description&gt;This is the summary of the document or web page. The summary is generated from the original document based on matches with query terms. In some cases, the summary is a description provided by the author.&lt;/description&gt;
          &lt;write&gt;December 26, 2004&lt;/write&gt;
        &lt;/Result&gt;
      &lt;/All_Results&gt;
      </property>
      <property name="Xsl" type="string">
        <![CDATA[
          <?xml version="1.0" encoding="iso-8859-1"?>
          <xsl:stylesheet version="1.0"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:srwrt="http://schemas.microsoft.com/WebParts/v3/searchresults/runtime"
              xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">
            <xsl:output method="xml" indent="no"/>
            <xsl:param name="Keyword" />
            <xsl:param name="ResultsBy" />
            <xsl:param name="ViewByUrl" />
            <xsl:param name="ShowDropDown" />
            
            <!-- Un montón de código aquí -->
            
                </xsl:otherwise>
              </xsl:choose>
            </xsl:template>
 
            <!-- End of Stylesheet -->
          </xsl:stylesheet>          
        ]]]]><![CDATA[>
      </property>
      
      <!-- Un montón de propiedades aquí -->
      
    </properties>
  </data>
</webPart>
webParts>]]>

No se vosotros, pero yo me he llevado una alegría al ver que esto funcionaba. Antes de acabar, un par de puntos:

  1. Esto está funcionando ahora, pero puede tener algún efecto secundario, como siempre. Si detecto alguno, actualizaré el artículo e indemnizaré a todos mis subscriptores con 100€ en la MartosStore
  2. He leído por ahí que nunca deberíamos anidar CDATAs jamás de los jamases. Lo único que os puedo decir es que si por cada vez que lo haces, dios mata a un gatito… lo dejaré de hacer.

1 comentarios:

Servidores en la nube dijo...

Es la primera ves que visito tu blog, pero seguro estoy de que no sera la última, ha sido todo un gusto disfrutar de tan buenos artículos como este tan bien estructurados. Un saludo.