sábado, 18 de febrero de 2012

Sharepoint 2010: Web Parts Injection

con Facundo Franco
Introducción
    Estamos trabajando en AVANADE participando de un proyecto de desarrollo para una importante cadena de supermercados. Estamos realizando un sitio web basado en SharePoint 2010 que utilizaran los empleados como portal interno.
Necesidad
                Necesitamos que las webparts aparezcan cargadas en la página luego de hacer el deploy. Lo primero que intentamos fue reproducir los controls dentro de .aspx pero el problema que tuvimos fue que no podían ser modificados desde el front-end de SharePoint.
Solución
                Para agregar las webpart desde un solo deploy creamos dos features, una para deployar los archivos necesarios, por ejemplo la página de default, y otra que es la que inyectará las webparts a las respectivas paginas.
Abajo explicaremos los pasos a seguir para poder realizar este procedimiento.

Feature 1:
Se encargara de agregar las webparts a nuestro proyecto para poder utilizarlas
1.       Hacemos click derecho en la carpeta donde se contienen las features y hacemos click en Add Feature. El scope de la feature debe ser SITE.
2. Agregamos los controles que queremos que se deployen con esta feature, en nuestro caso las paginas, webparts, controles, etc..

Feature 2:
1.       Creamos una feature para que al activarse se ejecute el código que agrega la webpart. El scope de la feactures es nivel site.

2.       Una vez creada la feature debemos agregar un event received y sobre escribir el método FeatureActivated. Este medo recibe como parámetro un SPFeatureReceiverProperties. Con este parámetro nosotros podemos obtener el spSite al que pertenece y con este último saber finalmente a que spWeb nos referimos. Asignandole la propiedad AllowUnsafeUpdates a la web permitimos agregar la webpart.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    if (properties.Feature.Parent is SPSite)
    {
        // This is a site collection
        SPSite siteCollection = properties.Feature.Parent as SPSite;
        // This is the top level site in the site collection
        SPWeb rootWeb = siteCollection.RootWeb;
        rootWeb.AllowUnsafeUpdates = true;
3.       Con el SPWeb obteneos el SPFile y con el podemos finalmente llegar al SPLimitedWebPartManager el cual contiene los métodos que utilizaremos para agregar las webpart a la pagina.
        SPFile file = rootWeb.GetFile(@"PAges\Home.aspx");
        if (file.CheckOutType == SPFile.SPCheckOutType.None) file.CheckOut();
        SPLimitedWebPartManager manager =
                  file.GetLimitedWebPartManager(PersonalizationScope.Shared);
4.       Por otro lado solo nos queda crear la webpart que queremos agregar, para esto tenemos dos opciones. Utilizar las webparts OOB o exportando una webpart desde el sharepoint.
5.       Si vamos a utilizar una webpart out of the box o una custom webpart solo debemos instanciar el objeto, dale valor a las propiedades y luego agregarla con el manager creado en el punto 3.
            ContentByQueryWebPart myWebPart = new ContentByQueryWebPart();
            myWebPart.Title = "Links";
            myWebPart.ListName = "Links";
            manager.AddWebPart(myWebPart, "LeftColumn", 3);
            manager.SaveChanges(myWebPart);

6.       Si queremos utilizar una webpart de una página ya existente podemos exportarla haciendo click en export…

7.       Para utilizar esta webpart exportada debemos primero leer el archivo con un XmlTextReader para luego castearlo a webpart.
            string url = string.Empty;
            XmlTextReader reader = null;
            // Add the Announcements Web Part
            url = rootWeb.Url + "/_catalogs/wp/announcement.webpart";
            reader = new XmlTextReader(new StringReader(rootWeb.GetFileAsString(url)));
            Microsoft.SharePoint.WebPartPages.WebPart announcementsWebPart =
                  (Microsoft.SharePoint.WebPartPages.WebPart)manager.ImportWebPart(reader,
                  out announcementsWebPartError);
            manager.AddWebPart(announcementsWebPart, announcementsWebPartZoneID, 0);
            manager.SaveChanges(announcementsWebPart);
8.       Una vez realizado esto volvemos la property AllowUnsafeUpdates a false.
 web.AllowUnsafeUpdates = false;
Por último para quitar las webparts desde el código.
9.       En la misma feature sobre escribimos el metodo FeatureDeactivating. Y volvemos a realizar todo el proceso para obtener el SPLimitedWebPartManager. Después debemos poner la propiedad AllowUnsafeUpdates con el valor true.
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    SPSite siteCollection = properties.Feature.Parent as SPSite;
    SPWeb rootWeb = siteCollection.RootWeb;
    SPLimitedWebPartManager webPartManager = rootWeb.GetLimitedWebPartManager(rootWeb.Url + @"\Pages\Home.aspx", PersonalizationScope.Shared);
    rootWeb.AllowUnsafeUpdates = true;
10.   Luego recorremos con un for las webparts de la web y desactivamos la que nosotros queremos.
for (int i = webPartManager.WebParts.Count - 1; i > -1; i--)
{
    if (webPartManager.WebParts[i].Title == webPartTitle)
    {
        webPartManager.DeleteWebPart(webPartManager.WebParts[i]);
        // don't break because there could be more than one.
    }
}
11.   Al finalizar todo el proceso debemos modificar la propiedad AllowUnsafeUpdates nuevamente.
web.AllowUnsafeUpdates = false;

jueves, 9 de febrero de 2012

Powershell Fundamentals

con Dario Mouzo.

Estamos trabajando en AVANADE participando de un proyecto de desarrollo para una importante cadena de supermercados. Estamos realizando un sitio web basado en SharePoint 2010 que utilizaran los empleados como portal interno.

Durante nuestro proyecto tuvimos la necesidad de automatizar algunas de las operaciones como la creación de web application, sites y deploy para lo cual utilizamos scripts de SharePoint.

En esta tabla vamos a comentar los comandos (desde ahora Cmdlets), dar una descripción de cada uno, y comentar la utilidad y beneficios que trae usarlos.


Cmdlets
Descripción
Utilidad que se le dio
Add-PsSnapin
Agrega complementos registrados de Windows PowerShell
Se le agrega “Microsoft.SharePoint.PowerShell” para utilizar Cmdlets en SharePoint.
new-spwebapplication -name <Name> -ApplicationPool <ApplicationPool> -ApplicatioinPoolAccount <ApplicationPoolAccount> -port <port> - URL <url>
Crea un WebApplication con los parámetros seleccionados.
Permite crear WebApplication en menos tiempo.
SPWebApplication –identity http://sitename-Confirm
Borra Web Application seleccionado según los parámetros dados.
New-SPSite -Url "<URL for the new site collection>" -OwnerAlias "<domain\user>" - Template “<template>”
Crea un Site Collection con los parámetros seleccionados.
Permite crear Site Collection de un tipo determinado al ingresar código del Template.
Remove-SPSite -Identity "<URL>" -Confirm -DeleteIISSite -RemoveContentDatabases
Borra un Site Collection determinado por los parámetros ingresados.
Borra el Site Collection seleccionado, con este comando se borran AppPool del IIS y Content Databases creados.
Set-SPSite -Identity "<SiteCollection>" -OwnerAlias "<DOMAIN\User>"-SecondaryOwnerAlias "<DOMAIN\User>"
Setea Administradores de SiteCollection.
Permite cambiar/asignar rápidamente a los Administrators del sitio.
New-SPManagedPath [-RelativeURL] "</RelativeURL>" -WebApplication <WebApplication>
Agrega Managed Path(1) a un WebApplication designado.
Remove-SPManagedPath [-Identity] <ManagedPathName> -WebApplication <WebApplication>
Borra Managed Path(1) seleccionado, en WebApplication designado.

(1)    Managed Path: Al definir rutas de acceso administradas, puede especificar qué rutas del espacio de nombres de direcciones URL de una aplicación web se usan para colecciones de sitios. Puede indicar que existe una o más colecciones de sitios en la ruta de acceso especificada. Este podría ser el método más conveniente para consolidar varios accesos a sitios para los usuarios de diversos departamentos  (http://technet.microsoft.com/es-ar/library/cc288905.aspx)

Tenemos Cmdlets que sirven para crear, borrar, y modificar nuestros sitios. Pero también tenemos Cmdlets para conseguir datos importantes, que pueden ayudarnos a crear Líneas de comando mucho más personalizables.

get-command
Devuelve todos los comandos de Windows PowerShell

Existen filtros muy útiles que se pueden aplicar a comandos generales o que devuelven gran cantidad de comandos, por ejemplo:
                -noun “filter” (solo filtra por sustantivos)
                -verb “filter” (solo filtra por verbos)
De esta forma filtraría todos los comandos que contengan los datos incluidos en el espacio “filter”


En esta captura se puede ver que no se puede leer, por una limitación de la aplicación, toda la definición de los Cmdlets devueltos por nuestro comando. Lo que se puede hacer es agregar al final un comando que te devuelve los mismos datos, pero en un archivo de texto .TXT

También podemos escribir la sentencia  “ | format-list” para darle un formato más detallado de cada ítem o comando devuelto.


Podemos traer Services, Features, Web Application, Site Collections, Web Sites, Templates, etc,

Services:

Get-spserviceinstance
Recupera una lista de todos los servicios de la granja de servidores junto con sus GUID
Start-SPServiceInstance -Identity <GUID>
Inicia Servicio, es necesario el GUID. Referencia: http://technet.microsoft.com/es-es/library/ff607965.aspx
Stop-SPServiceInstance -Identity <GUID del servicio>
Detiene el servicio

Features:

get-spfeature
Obtiene Features de toda la farm
get-spfeature –<Scope> <URL>
Obtiene Features de un Scope determinado, en una URL especifica.

Templates:

Get-SPWebTemplate
Devuelve todos los templates instalados y listos para utilizar

Recuerden que con cada Cmdlet, se pueden aplicar los filtros para hacer más rápida y precisa la búsqueda.

sábado, 4 de febrero de 2012

Sharepoint 2010: How to add RSS Viewer Web Part

1.       Open and edit a page


2.       Select the section where you want to add the new webpart and click on “Add a Web Part”



3.       Select “Content Rollup”, choice “RSS Viewer” and click on “Add” button.




a.       If the web part doesn’t exit, you need to activate a Site Collection Feature for this go to “Site Actions”, “Site Settings” and “Site Collection Feature” into the “Site Collection Administration” group, find and active the following feature:


4.       After to add the control, click in “Open the tool pane”.


5.       Now, you need to configure a RSS for this you can use for example this URL http://rss.cnn.com/rss/cnn_us.rss

6.       And this the final result.

jueves, 2 de febrero de 2012

Infopath avanzado con Sharepoint 2010 BPOS 365

con Gonzalo Alcaraz

Introducción

Estamos trabajando en AVANADE participando de un proyecto de desarrollo para una de las más importantes empresas cerveceras. Estamos utilizando un portal en SharePoint Online conocido como Office 365 o BPOS. Hemos implementado un formulario que nos permite realizar encuestas y guardar los resultados en una lista de SharePoint. Éste approach no funciona dentro de Office 365, ya que éste no permite la ejecución de código de InfoPath.
Necesidad
                Necesitamos crear un formulario que funcione como una encuesta, tomando varias preguntas de una lista de SharePoint, dependiendo de si están habilitadas y la periodicidad, y guardando los datos que cargue el usuario en otra lista de SharePoint.
Solución
InfoPath es una aplicación incluida en el paquete Office.  Esta vez crearemos un formulario desde cero.
1.       En la pantalla de creación de nuevo formulario, seleccionamos un “Formulario en Blanco”.
2.       Luego pasaremos a crear las conexiones de datos necesarias. Primero crearemos una conexión para recibir datos desde la lista de SharePoint de donde queremos obtener los elementos a mostrar para que el usuario complete el formulario (para crear este tipo de conexión, ver el primer News Letter de InfoPath aquí.).
3.       El paso siguiente es agregar una tabla extensible para mostrar la información que obtendremos de la lista. Para hacer esto necesitamos mostrar los campos de las conexiones de datos. Nos aseguramos de que el Ribbon este desplegando el menú de “Datos”, y luego clickearemos en “Mostrar Campos”.
4.       Se despliega la barra de Campos. En ella, seleccionamos nuestra conexión de datos recientemente creada en el DropDown debajo de “Campos:”, y seleccionamos “d:SharepointListItem_RW” luego de desplegar “dataFields”, como se indica en la imagen. Arrastramos la selección al área de trabajo y seleccionamos “Tabla Extensible” cuando nos lo pida.
5.       El resultado será similar al de la imagen. Se pueden eliminar columnas de no ser necesario mostrarlas (click derecho en la columna -> Eliminar -> Columnas).
6.       Ahora crearemos “Reglas” para filtrar las preguntas a mostrarse en la tabla extensible. Seleccionamos la tabla extensible, y desplegamos el Ribbon de “Herramientas de Controles”, para mostrar el botón de “Administrar Reglas”. Al clickearlo se abre la ventana de reglas del control.
 
7.       Clickeamos en “Nuevo->Formato” para crear una nueva regla de tipo Formato. Tildamos la opción “Ocultar este control”, ya que ésta será la primera condición por la cual se ocultarán los elementos a mostrar. Clickeamos donde dice “Ninguno” debajo de “Condición” para agregar la condición. En este caso, queremos que se oculten los elementos cuando “Enable” sea igual a falso, las opciones de la condición nos permiten hacer esto. Clickeamos “Aceptar” y cambiamos el nombre de la regla.
8.       Agregaremos un botón que nos permita enviar los datos una vez que hayamos agregado el código pertinente. Para hacerlo, en el Ribbon de “Inicio”, desplegamos los controles de entrada y seleccionamos un “Botón”.

9.       Click derecho sobre el mismo, “Propiedades de Botón”. En la ventana que se abre, debajo de “Acción”, seleccionar “Reglas y código personalizado”. Esto generará un Id para el botón y habilitará una opción para “Editar código del formulario”. Hacer click en esta opción.

10.   Se abrirá el Visual Studio Tools for Applications, donde podremos agregar el código que necesitamos al botón. Primero deberemos agregar dos referencias, “Microsoft.Sharepoint” y “Microsoft.Sharepoint.Security”. Habrá también que agregar estas dos librerías con el comando ‘using’.

11.   Luego, dentro del método al que llama el botón, se deberá insertar un código como el que sigue a continuación.

//Esta sección del código crea un iterador de nodo xml señalando todos //los campos de los items de la lista de donde estamos sacando las //preguntas para la encuesta, luego iteraremos dentro de éste para //acceder a cada una de las preguntas

XPathNodeIterator questions = DataSources["KPI Question"].CreateNavigator().Select("/dfs:myFields/dfs:dataFields/d:SharePointListItem_RW", NamespaceManager);


//Necesitamos correr esta próxima parte con mayores privilegios

SPSecurity.RunWithElevatedPrivileges(delegate()
{
string url = //Url del sitio
      using (SPSite rootsite = new SPSite(url))
      {
string webSite = //Rootweb
using (SPWeb rootweb = rootsite.OpenWeb(webSite))
            {
string listName = //Nombre de la lista
                  SPList list = rootweb.Lists[listName];
                  SPListItem item;
                    
//Esta sección la corremos con cada una de las preguntas
                  while (questions.MoveNext())
                  {

//Creamos un navegador xml para iterar a través de las preguntas
XPathNavigator question = questions.Current.CreateNavigator();

//Agregamos el item vacío en la lista Database
                        item = list.Items.Add();

//A cada atributo de la pregunta lo metemos en el //item recién guardado en Database
item["Pillar"] = question.SelectSingleNode("d:Pillar", NamespaceManager).Value;
                                               
item["Measure"] = question.SelectSingleNode("d:Measure", NamespaceManager).Value;
                                               
item["Frequency"] = question.SelectSingleNode("d:Frequency", NamespaceManager).Value;
                                               
item["Source"] = question.SelectSingleNode("d:Source", NamespaceManager).Value;
                                               
item["Method of Calculation"] = question.SelectSingleNode("d:Method_x0020_of_x0020_Calculatio", NamespaceManager).Value;
                       
item["KPI"] = question.SelectSingleNode("d:KPI", NamespaceManager).Value;
                       
item["Actual"] = question.SelectSingleNode("d:Actual", NamespaceManager).Value;

item["Value"] = question.SelectSingleNode("d:Value", NamespaceManager).Value;
                                          
                           //Y finalmente hacemos el update al item    
item.Update();
}
}
}
});
12.   El resultado final puede apreciarse en la foto. Agregamos un par de filtros más de acuerdo al valor en el campo Frequencies y campos propios de mes y zona. Ahora resta publicarlo al sitio de SharePoint para permitir el uso a los usuarios.

13.   Clickeamos en “Archivo->Publicar->Sharepoint Server”.

14.   En la primera pantalla escribimos el sitio de SharePoint donde queremos publicar. Luego clickeamos “Siguiente” y en la próxima pantalla tildamos la opción “Habilitar este formulario para rellenarlo utilizando un explorador” y seleccionamos la opción “Biblioteca  de Formularios”.

15.   La siguiente ventana nos da la opción de crear una biblioteca de formularios nueva o elegir una existente. Luego nos dará el sumario del formulario y nos dará la opción de publicar. Una vez que hayamos clickeado ahí el formulario estará publicado en la ubicación seleccionada.

Conclusión

InfoPath es una herramienta poderosa, más aún si agregamos código a la ecuación. Sin embargo, este tipo de soluciones funcionan sólo si se hace un deploy dentro de nuestro dominio, limitando su utilidad. En nuestro caso, implementamos esta solución para hacer un deploy en Office 365, ambiente que restringe este tipo de soluciones con código, por lo que se tuvo que tomar la decisión de desarrollar una WebPart que implementara la funcionalidad que aquí logramos con InfoPath.