jueves, 7 de octubre de 2010

David Martos, también en Geeks.ms

Queridos lectores, tengo que informaros de la reciente inauguración de mi nuevo blog en Geeks.ms. Coincidiendo con mi reciente nombramiento como Microsoft MVP SharePoint Server he querido dar un saltito y crear este nuevo blog que llevaba tiempo rondándome por la cabeza. Esto no significa en ningún caso que dejaré de mantener este blog. De hecho, allí sólo publicaré contenido relacionado con SharePoint 2010 mientras que seguiré publicando el resto de cosas aquí.

¿Que el 99% de lo que publico acualmente está relacionado con SharePoint 2010? correcto, pero no alarmarse que seguiré publicando esa información aquí mediante crossposting.

Poco a poco iré personalizando el otro blog para darle una forma y un estilo más apropiados, pero es que si no lo inauguro ya irá pasando el tiempo y nunca acabaré de ponerme. Ahora tengo que ponerme sí o sí.

En fin, nada más. Os dejo la url para aquellos de vososotros que prefiráis leerme en Geeks.ms pero, como ya he dicho, este blog se mantendrá como siempre.

http://geeks.ms/blogs/davidmartos/

¡He sido MVP-tizado!

Hoy es un día muy especial para éste, mi humilde blog: tengo el placer de anunciaros mi nombramiento como Microsoft MVP de SharePoint Server, y de ese nombramiento, tiene gran parte de culpa este espacio que leéis. Como muchos sabréis, este título o galardón se otorga a aquellos profesionales que más o mejor colaboran con la comunidad, ya sea posteando, participando en los grupos de usuario, creando contenido multimedia o incluso participando en eventos presenciales. Aunque intento participar en tantas áreas como sea posible, tengo que reconocer que el blog es el que se acaba llevando más cuota de tiempo. Además, cualquier colaboración que realizo fuera de este blog acaba teniendo aquí su reseña a modo de referencia.

Cuando comencé a escribir este blog y a colaborar más activamente en la comunidad, mi objetivo era claro: mis principales fuentes de inspiración han sido siempre los foros y los blogs de expertos de las tecnologías con las que trabajo a diario, gracias a los cuáles he aprendido muchísimo y me he ahorrado una gran cantidad de tiempo a la hora de resolver problemas. Creando este sitio quería poder devolver una pequeña parte de todo lo que la comunidad me ha dado siempre y, si alguna vez algo de lo que escribo puede ahorrarle unos minutos a alguien, el trabajo habrá merecido la pena. El caso es que el reconocimiento como MVP no es otra cosa que una confirmación de que por lo menos estoy en el buen camino para conseguir ese objetivo, y eso es lo más importante al fin y al cabo.

La verdad es que todo se ha producido muy rápido y de manera muy inesperada para mí, ya que me enteré durante el “bautizo” de otros MVPs en el pasado MVP Open Day & TTT del 01/10/2010 en Fuengirola. No os hablaré del evento en este post, pero si buscáis TTT2010 por las principales redes sociales encontraréis información interesante a  raudales. Cuando vi aparecer al amigo Juan Carlos indicándome que me tocaba a mí pensaba que en realidad se trataba de una broma. De hecho, cuando vi como se desarrollaron los acontecimientos seguía pensando que muy normal no era… pero  bueno, espero acostumbrarme a esto porque significará que sigo muchos años metido en el ajo.

Sin más, comentar únicamente que, como ya se han encargado de decirme: un gran poder conlleva una gran responsabilidad, así que espero poder mantener (o a ser posible mejorar) el nivel de este blog para que esté a la altura de las circunstancias. Y no quiero finalizar este post sin dar las gracias a todas las personasque  han participado de una u otra manera en mi proceso de nominación. Espero devolverles la confianza que han depositado en mí.

martes, 5 de octubre de 2010

Blogs en SharePoint 2010 y rating

Permitir a tus usuarios valorar los posts de un blog de SharePoint 2010 y mostrar estas valoraciones por pantalla es un requerimiento bastante habitual que, por defecto, no está soportado. Existen muchas maneras de poner esto en marcha, y se pueden encontrar algunas soluciones que te ofrecen esta y otras muchas funcionalidades (por ejemplo, CKS). No obstante, si sólo queremos habilitar el rating y no queremos complicarnos la vida, tenemos una manera muy simple de hacerlo.

Para empezar, accedemos a la gestión de la lista de posts de nuestro blog y, una vez ahi, seleccionamos configuración de la lista.

image

En la configuración de la lista veremos una opción para establecer la configuración de las valoraciones o ratings.

image 

Una vez ahí podremos confirmar que permitimos valorar los elementos de esta lista y guardar la configuración.

image

En estos momentos nuestra lista está preparada para recibir valoraciones y, utilizando las vistas de la lista y editando las propiedades de los posts podríamos valorarlos y ver las valoraciones medias. Si queremos hacer esto de una manera más elegante, necesitamos permitir realizar las valoraciones desde la propia página del post y ver las valoraciones medias desde la lista. Para hacer eso, podemos utilizar SharePoint Designer.

Accedemos a All Files –> Lists –> Posts –> Post.aspx y editamos el fichero en modo avanzado

image

Una vez ahí necesitamos, primero, registrar el control de valoraciones al inicio de la página, insertando el siguiente código:

<%@ Register Tagprefix="SharePointPortalControls" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Después, en algún lugar de la página (yo he decidido ponerlo dentro del DIV con ID BlogRSSNav pero podéis decidir vosotros mismos) necesitáis añadir el control AverageRatingFieldControl.

<div id="BlogRSSNav">
    <SharePointPortalControls:AverageRatingFieldControl id="PageRatingControl" FieldName="Rating (0-5)" runat="server" />
</div>

Una vez hecho esto ya tendréis la posibilidad de enviar valoraciones desde la propia página del post, tal y como muestra la figura:

image

Poner esta información en el listado de la página inicial es algo más complejo y va a requerir que tengáis conocimientos de XSLT. Para hacerlo deberíais editar la página default.aspx de la raíz del sitio con SharePoint Designer, localizar el XsltListViewWebPart que muestra la lista de posts (es el segundo) y modificar la definición del XML.

Primero, en la lista de ViewFields tendréis que añadir el siguiente campo:

<FieldRef Name="AverageRating"/>

Para finalizar, puedes mostrar el campo allá donde más te convenga, dentro del nodo xsl, utilizando el siguiente código:

<xsl:value-of select="$thisNode/@AverageRating"/>

Evidentemente esto es únicamente parte de la solución porque aunque tengas todo perfectamente configurado únicamente verás el valor numérico. A partir de aquí, con algunos conocimientos de XSLT podrás montar automáticamente una lista de estrellas o cualquier otro elemento que quieras utilizar para mostrar las valoraciones. Si, además de todo esto, necesitas disponer del control interactivo para valorar posts desde el propio listado os recomiendo que editéis con SharePoint Designer alguna de las vistas que contengan el campo AverageRating como, por ejemplo, AllPosts.aspx.

Editado el 06/10/2010

Para aclarar algunas dudas, añado el código xsl que sería necesario para mostrar la valoración media justo delante del título del post en la página de inicio del blog. Editáis la página con SharePoint Designer 2010 y buscáis el siguiente código:

</XmlDefinition>
<DataFields>
</DataFields>
 
</WebPartPages:XsltListViewWebPart>

Y justo después del cierre del nodo DataFields introducís el siguiente código:

<Xsl>
    <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal" xmlns:o="urn:schemas-microsoft-com:office:office"> 
        <xsl:include href="/_layouts/xsl/blog.xsl"/> 
        <xsl:include href="/_layouts/xsl/internal.xsl"/> 
        <xsl:param name="AllRows" select="/dsQueryResponse/Rows/Row[$EntityName = '' or (position() &gt;= $FirstRow and position() &lt;= $LastRow)]"/>
        <xsl:param name="dvt_apos">&apos;</xsl:param>
        <xsl:template mode="Item" match="Row[../../@TemplateType='301' and (../../@BaseViewID='0' or ../../@BaseViewID='7' or ../../@BaseViewID='8' or ../../@BaseViewID='9')]" ddwrt:ghost="">
        <xsl:param name="Fields" select="."/>
        <xsl:param name="Collapse" select="."/>
        <xsl:param name="Position" select="1"/>
        <xsl:param name="Last" select="1"/>
        <xsl:variable name="ShowBody"><xsl:if test="../../@BaseViewID='0' or ../../@BaseViewID='7'">1</xsl:if></xsl:variable>
        <xsl:variable name="ShowTopDate"><xsl:if test="../../@BaseViewID='0' or ../../@BaseViewID='7'">1</xsl:if></xsl:variable>
        <xsl:variable name="ShowDrafts"><xsl:if test="../../@BaseViewID='7'">1</xsl:if></xsl:variable>
        <xsl:variable name="thisNode" select="."/>
        <xsl:if test="$ShowDrafts=1 or $thisNode/@_ModerationStatus. = 0">
            <table>
              <tr class="ms-blogpostdatecol" valign="top">
                  <td class= "ms-leftblogdate">
                    <div id="PostDateTopBox{generate-id()}" class="ms-postcalendardateboxtop">
                    </div>
                    <xsl:if test="$MasterVersion = 4">
                        <div id="PostDateBottomBox{generate-id()}" class="ms-postcalendardateboxbottom" style="overflow-x:hidden">
                            <div>
                                <xsl:value-of select="$thisNode/@PublishedDate.MonthDayOnly" disable-output-escaping="yes" />
                            </div>
                        </div>
                    </xsl:if>
                    <xsl:if test="$MasterVersion != 4">
                        <div id="PostDateBottomBox" class="ms-postcalendardateboxbottom" style="overflow-x:hidden;font-size:0.8em">
                            <div>
                            <xsl:value-of select="$thisNode/@PublishedDate.MonthDayOnly" disable-output-escaping="yes" />
                            </div>
                        </div>
                    </xsl:if>      
                  </td>
                  <td class = "ms-rightblogpost">
                    <table dir="None" cellspacing="0" cellpadding="0" width="100%" border="0">
                      <tbody>
                        <tr>
                          <td class="ms-PostTitle">
                                                          
                            <xsl:value-of select="$thisNode/@AverageRating"/>
                            
                            <xsl:value-of select="$Fields[@Name='AverageRating']" disable-output-escaping="yes" />
                            <a href="{$HttpVDir}/{$thisNode/../@resource.wss.lists_Folder}/{$thisNode/../@resource.wss.blogpost_Folder}/Post.aspx?ID={$thisNode/@ID}">
                              <xsl:apply-templates select="$Fields[@Name='Title']" mode="PrintField">
                                <xsl:with-param name="thisNode" select="$thisNode"/>
                                <xsl:with-param name="Position" select="$Position"/>
                              </xsl:apply-templates>
                            </a>
                          </td>
                              <xsl:if test="../../@BaseViewID='7'">
                                <xsl:if test="($thisNode/../@value.listpermission.EditListItems = '1' and (($thisNode/../@value.listpermission.ManageLists  = '1') or ($XmlDefinition/List/@WriteSecurity = '2' and $thisNode/@Author.id = $Userid) or ($XmlDefinition/List/@WriteSecurity != '2')))">
                                  <td align="right" class="ms-blogedit">
                                    <a href="javascript:" onclick="javascript:ShowPopupDialog('{$HttpVDir}/{$thisNode/../@resource.wss.lists_Folder}/{$thisNode/../@resource.wss.blogpost_Folder}/EditPost.aspx?ID={$thisNode/@ID}&amp;Source={$HttpVDir}%2Fdefault.aspx');">
                                      <xsl:value-of select="'Edit'" />
                                    </a>
                                  </td>
                                </xsl:if>
                              </xsl:if>
                        </tr>
                      </tbody>
                    </table>
                    <div class="ms-PostFooter">
                      <xsl:for-each select="$Fields">            
                        <xsl:if test="@Name!='Title' and @Type!='Note' and not(@Name='PostCategory' and $thisNode/@PostCategory='')">
                              <xsl:choose>
                                <xsl:when test="@Name='Author'"><span class="ms-postfootercolor"><xsl:value-of select="'by '"/></span><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$thisNode/@Author.span" disable-output-escaping="yes" /></xsl:when>
                                <xsl:when test="@Name='PublishedDate'"><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;&amp;nbsp;</xsl:text><span class="ms-postfootercolor"><xsl:value-of select="'on'"/><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$thisNode/@PublishedDate" /></span></xsl:when>                
                              </xsl:choose>
                        </xsl:if>
                      </xsl:for-each>
                    <div>
                        <xsl:for-each select="$Fields">            
                  <xsl:if test="@Name='PostCategory' and not ($thisNode/@PostCategory='')">
            <xsl:value-of select="'Category'" />:<xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text><xsl:apply-templates select="$Fields[@Name='CategoryWithLink']" mode="Computed_body"><xsl:with-param name="thisNode" select="$thisNode"/></xsl:apply-templates>
            </xsl:if>
        </xsl:for-each>
        </div>
      </div>
        <xsl:if test="$ShowBody=1">
          <div class="ms-PostBody">
            <div>
              <xsl:apply-templates select="$Fields[@Name='Body']" mode="PrintField">
                <xsl:with-param name="thisNode" select="$thisNode"/>
                <xsl:with-param name="Position" select="$Position"/>
              </xsl:apply-templates>
            </div>
          </div>
        </xsl:if>
        <div class="ms-PostFooter">
              <xsl:for-each select="$Fields">            
                <xsl:if test="@Name ='Permalink' or @Name ='EmailPostLink' or @Name ='NumCommentsWithLink'">
                    <xsl:choose>
                          <xsl:when test="@Name='Permalink' or @Name='EmailPostLink' or @Name='NumCommentsWithLink'"><xsl:apply-templates select="." mode="PrintFieldWithDisplayFormLink"><xsl:with-param name="thisNode" select="$thisNode"/><xsl:with-param name="Position" select="$Position"/></xsl:apply-templates><xsl:if test="@Name='Permalink' or @Name='EmailPostLink'"><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;|&amp;nbsp;</xsl:text></xsl:if></xsl:when>
                          <xsl:when test="$thisNode/@*[name()=current()/@Name]!=''"><xsl:apply-templates select="." mode="PrintFieldWithDisplayFormLink"><xsl:with-param name="thisNode" select="$thisNode"/><xsl:with-param name="Position" select="$Position"/></xsl:apply-templates><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;|&amp;nbsp;</xsl:text></xsl:when>
                    </xsl:choose>
            </xsl:if>
          </xsl:for-each>
        </div>
          </td>
    </tr>
    </table>
    </xsl:if>
  </xsl:template></xsl:stylesheet>
</Xsl>