Uno de los grandes problemas que nos encontramos a la hora de abordar un proyecto en SharePoint es la forma en la que vamos a desplegar nuestro desarrollo en los distintos entornos posibles (Integración, PRE y PRO). Uno de los aspectos más complicados es cómo vamos a aprovisionar las páginas de nuestro site. Pero dependiendo del tipo de proyecto en el que estemos trabajando, lo realizaremos de una forma u otra. En este post de hoy, vamos a abordar cómo realizar el aprovisionamiento de las páginas de publicación.
Características de la páginas de publicación
La principal diferencia de este tipo de página respecto con una página de colaboración es que, en este caso, a la página le tenemos que asignar un PageLayout basado en un tipo de Contenido. Este PageLayout puede ser implementado por nosotros o estar por defecto en nuestro Site. Dependiendo de este aspecto lo realizaremos de una forma u otra.
Posibilidades de Aprovisionamiento
Disponemos de tres formas de crear las páginas:
- Mediante desarrollo: SharePoint tiene una API muy completa que permite realizar cualquier cosa. La principal desventaja es que es relativamente costoso y engorroso de mantener todo esto en código.
- Mediante Módulos (de forma declarativa).
- Haciendo uso de la interfaz : Esta opción NO debería realizarse bajo ningún concepto.
Mediante desarrollo
No es la función de este post entrar en detalle en cómo realizarlo mediante desarrollo, pero os dejamos un ejemplo de cómo se puede abordar mediante esta solución:
rivate void ProvisionPage( PublishingWeb publishingWeb, string pageLayoutName, string pageTitle, string pageDescription, string pageFileName) { PageLayout[] layouts = publishingWeb.GetAvailablePageLayouts(); // Name Values of Content Types of Publishing Site Dictionary<string, PageLayout> pageLayouts = new Dictionary<string, PageLayout>(); foreach (PageLayout item in layouts) { string cID = item.Title.ToString(); string name = item.Name; pageLayouts.Add(cID, item); } PageLayout layout = pageLayouts[pageLayoutName]; if (!PageExists(publishingWeb, pageFileName)) { PublishingPage newPage2 = publishingWeb.GetPublishingPages().Add(pageFileName, layout); newPage2.Description = pageDescription; newPage2.Title = pageTitle; newPage2.Update(); SPFile pageFile = newPage2.ListItem.File; if (pageFile.CheckOutStatus != SPFile.SPCheckOutStatus.None) { pageFile.CheckIn(“Checked in on feature activation.”); pageFile.Publish(“Published on feature activation.”); } } }
Mediante un Módulo
¿Qué es un módulo? Un módulo es un tipo de artefacto que podemos utilizar dentro de la solución de SharePoint, cuyo funcionamiento es dejar alojados los ficheros que se encuentran dentro de este modulo en una ubicación física de SharePoint. Pero, además de desplegar los ficheros físicos, también es posible añadirle parámetros de configuración.
Un módulo lo utilizaremos para desplegar desde masterpage, pagelayouts, display templates hasta los ficheros css, js, imágenes, etc… que se va a utilizar en nuestro desarrollo.
Ahora bien, ¿cómo aprovisionamos una página de publicación? Tenemos dos casos:
- Hacemos uso de un PageLayout desarrollado por nosotros mismos.
- Hacemos uso de un PageLayout por defecto de SharePoint
Hacemos uso de un PageLayout desarrollado por nosotros
En primer lugar tendremos que tener un Modulo donde indiquemos el despliegue de este PageLayout.
OJO!! Este PageLayout debe desplegarse antes que nuestra página. Lo podemos comprobar observando el orden de despliegue de los artefactos que hay en nuestra solución.
El siguiente paso a realizar es crearnos un Modulo de Páginas, donde tendremos que añadir un XML similar al siguiente dentro del fichero Elements.xml
?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Module Name="Pages" Url="$Resources:cmscore,List_Pages_UrlName;" > <File Path="PageLayouts\NuestroPageLayout.aspx" Url="Home.aspx" Type="GhostableInLibrary" ReplaceContent="TRUE" IgnoreIfAlreadyExists="TRUE"> <Property Name="Title" Value="Página de Inicio"/> <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/NuestroPageLayout.aspx, Página de inicio"/> <Property Name="ContentTypeId" Value="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D4" /> </File> </Module> </Elements>
Aspectos que debemos de conocer de este XML :
- En la etiqueta Module en la URL, tenemos que indicar la url de la biblioteca.
- Dentro de File en el Path, indicamos la ubicación dentro de nuestra solución donde tenemos el fichero aspx. Dentro del módulo no hay ningún fichero.
- Entre el node de File, tendremos que introducir varias propiedades donde se va a establecer la configuración de esta página:
- TÍtulo: Indicaremos el Título de la página.
- PublishingPageLayout: Tendremos que indicar la ruta del PageLayout, seguido del título del mismo.
- ContentTypeID: Indicamos el ID de nuestro tipo de contenido. Si por el contrario no tenemos el ID, también se puede establecer una property «ContentType» donde indicamos el nombre del ContentType.
Hacemos uso de un PageLayout por defecto de SharePoint
Para este caso, en primer lugar tenemos que crearnos un Modulo. Dentro de este módulo insertaremos un fichero .aspx que sólo tiene que tener la siguiente información:
<%@ Page Inherits="Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=15.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %> <%@ Reference VirtualPath="~TemplatePageUrl" %> <%@ Reference VirtualPath="~masterurl/custom.master" %>
El siguiente paso es similar al caso anterior:
Module Name="PagesNoticias" Url="$Resources:cmscore,List_Pages_UrlName;" RootWebOnly="FALSE"> <File Path="PagesNoticias/Home.aspx" Url="Home.aspx" Type="GhostableInLibrary" ReplaceContent="TRUE" IgnoreIfAlreadyExists="TRUE"> <Property Name="Title" Value="Welcome" /> <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/BlankWebPartPage.aspx, Blank Web Part page" /> <Property Name="ContentType" Value="Welcome Page" /> </File> </Module>
NOTA: Si en ambos casos, además de desplegar las páginas queremos añadir los WebParts que van a estar ubicados en la página dentro del nodo «File», creamos una estructura como la siguiente: (en este caso vamos a desplegar un ScriptEditoWebPart)
<AllUsersWebPart WebPartZoneID="MiddleLeftZone" WebPartOrder="1" > <![CDATA[ <webParts> <webPart xmlns="http://schemas.microsoft.com/WebPart/v3"> <metaData> <type name="Microsoft.SharePoint.WebPartPages.ScriptEditorWebPart, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /> <importErrorMessage>Cannot import this Web Part.</importErrorMessage> </metaData> <data> <properties> <property name="ExportMode" type="exportmode">All</property> <property name="HelpUrl" type="string" /> <property name="Hidden" type="bool">False</property> <property name="Description" type="string">Allows authors to insert HTML snippets or scripts.</property> <property name="Content" type="string"><div class="MiAreaPersonal"> <div id="resultsMiAreaPersonal"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sodales tristique magna et molestie. Donec sed lorem eros. Suspendisse facilisis nibh nulla. Maecenas quis velit ipsum. Duis et vehicula dolor. Aenean id tincidunt metus, non tristique magna. Praesent quam mauris, malesuada at eleifend ut, pharetra in ligula. Quisque dapibus tellus et nulla aliquam bibendum. In urna ligula, molestie sed dui eget, sollicitudin venenatis neque. Aliquam diam quam, suscipit at urna auctor, bibendum hendrerit lacus. Praesent eleifend accumsan nisl, et blandit tortor mattis vel. Vivamus at nibh non mauris tempor varius. Nunc tincidunt neque a justo molestie imperdiet. Aenean volutpat tellus lacus, ac pharetra metus hendrerit eget. Aenean posuere egestas sapien a auctor. </p> </div> </div> </property> <property name="CatalogIconImageUrl" type="string" /> <property name="Title" type="string">Script Editor</property> <property name="AllowHide" type="bool">True</property> <property name="AllowMinimize" type="bool">True</property> <property name="AllowZoneChange" type="bool">True</property> <property name="TitleUrl" type="string" /> <property name="ChromeType" type="chrometype">None</property> <property name="AllowConnect" type="bool">True</property> <property name="Width" type="unit" /> <property name="Height" type="unit" /> <property name="HelpMode" type="helpmode">Navigate</property> <property name="AllowEdit" type="bool">True</property> <property name="TitleIconImageUrl" type="string" /> <property name="Direction" type="direction">NotSet</property> <property name="AllowClose" type="bool">True</property> <property name="ChromeState" type="chromestate">Normal</property> </properties> </data> </webPart> </webParts> ]]> </AllUsersWebPart>
Resumen
Algo muy importante dentro del desarrollo de Sofware es saber gestionar correctamente el ciclo de vida de la aplicación (ALM). Muchas veces por desconomiento de la plataforma o por no conocer las posibilidades de realizarlo, optamos por escoger el término medio. ¡Recuerda! Siempre hay una solución eficaz y posible para que el ciclo de vida de nuestra aplicación no sea un sufrimiento sino una diversión.