‭(oculto)‬ Herramientas del blog ‭[2]‬

Search


Todas las entradas de este blog son obras bajo una Licencia Creative Commons Atribuci�n-NoComercial 3.0 Unported .

ComunicaTEC

dic. 03
El misterio de los estilos personalizados de la Ribbon que desaparecen

Durante los años en que hemos estado realizando el mantenimiento de la antigua web de la Universidad de Cantabria observamos que los editores, de manera lógica, tenían la necesidad de resaltar partes del contenido de las webs, añadir textos con un aspecto determinado y otras mejoras visuales más allá de lo que permitía la plataforma de gestión de la web. Al no ser posible de manera sencilla para ellos, cada uno lo realizaba del modo que consideraba más fácil. Esto llevó a que al final la web presentase mucha disparidad de criterios visuales al existir miles de páginas gestionadas por cientos de editores, con lo que se dificultaba al usuario el tener una experiencia de navegación agradable.


En la nueva web de la universidad hemos tratado de dar un aspecto visual homogéneo y para ello hemos utilizado la posibilidad que da Sharepoint de extender los estilos predefinidos existentes a la hora de editar una web, añadiendo unos personalizados que responden a nuestras necesidades y que son fáciles de incorporar al contenido para los editores.


Agregar estos estilos personalizados es una tarea sencilla que explicamos en una entrada de blog previa.


Al añadirlos, el resultado en el desplegable de estilos debería ser similar a este:


3.jpg

Hasta aquí todo parecía muy sencillo y ya estábamos cantando victoria cuando nos dimos cuenta de que en Firefox y Chrome los estilos personalizados no aparecían, sin embargo los estilos predefinidos de Sharepoint que aparecen en el mismo listado sí que estaban.



4.jpg

Con Internet Explorer no había problemas y aparecían correctamente.


Así que tocaba investigar, probar y rebuscar en Google a ver si alguien más sufría de este expediente X, y efectivamente, en un tema de la msdn hablaban de este problema.


Si estos estilos se definen en el CSS dentro de un bloque @media, Sharepoint no los reconoce correctamente en todos los casos. En nuestro caso no estaban dentro de uno pero teníamos varias hojas de estilo y la hoja que incluía los estilos personalizados estaba después de otras que si tenían bloques @media. Así que para que se muestren correctamente es necesario que los estilos personalizados sean definidos en los CSS fuera y antes de los bloques @media que regulan las vistas para diferentes dispositivos.


La razón la desconocemos pero cambiando este orden los estilos personalizados comenzaron a mostrarse correctamente en todos los navegadores.

nov. 20
Imágenes de fondo que tiemblan en Internet Explorer

Que conste que no es por manía, pero hay que ser realistas, Internet Explorer hace cosas raras. Es más, en ocasiones es bastante enemigo de la maquetación web.


Uno ve su sitio con Firefox, con Chrome… y está encantado de haberse conocido por lo bien que se ve todo. Pero al abrir Internet Explorer ahí está: ese margen que no es, ese efecto que queda horripilante,  ese descuadre que desluce la web…


También es verdad que la mejora de este explorador ha sido mucha. La versión 11 está muy bien y no da tantos problemas como las anteriores. Y también es cierto que al ser el navegador más extendido durante muchos años, mucha gente tiene versiones antiguas aún instaladas que dificultan el realizar una web moderna que todo el mundo vea correctamente. Sobre todo en la administración pública, donde no siempre se está al día de la última versión de cada navegador que sale.


El caso es que en nuestro nuevo proyecto queríamos seguir la nueva tendencia de utilizar imágenes grandes sobre todo para los fondos de las páginas. Esas imágenes debían quedar fijas de fondo, sin hacer el scroll de la página. Esto mediante CSS es sencillo, y se logra mediante la propiedad:


background-attachment: fixed;


Pero en Internet Explorer 11, aunque esta propiedad hace el efecto deseado, al hacer scroll en la página la foto de fondo tiembla ligeramente. No es que destruya la página o imposibilite su visualización pero es un efecto desagradable y molesto cuando se navega por ella.


Lamentablemente no hemos encontrado una solución que podamos agregar en el HTML o en el CSS ya que es algo del propio Explorador. Para solucionarlo es necesario modificar la configuración de Internet Explorer. Si os pasa esto, id a:


Opciones de internet -> Opciones avanzadas:

opcionesinternet.jpg


Ahí es necesario desmarcar la opción "usar desplazamiento suave":

desplazamientosuave.jpg


De este modo las imágenes de fondo dejarán de temblar.

EDIT - Tras varias pruebas hemos visto que este problema surge en Internet Explorer para Windos 8 en el caso en que se haga scroll con la rueda del ratón. Utilizando las barras de scroll del navegador no pasa.

nov. 17
¡Volvemos!

Durante los últimos meses hemos dejado este blog algo abandonado, lo sabemos. Y no porque nos hayamos quedado sin ideas o no nos hayamos encontrado con situaciones dignas de comentar, que de esas ha habido muchas en los últimos tiempos. El motivo ha sido la realización, además del trabajo diario del Área Web De la Universidad de Cantabria, de un nuevo e importante proyecto que veréis muy pronto.


Este nuevo reto, al igual que la web en inglés de la Universidad de Cantabria que presentamos en Noviembre de 2013, ha sido llevado a cabo utilizando Sharepoint 2013 y nos ha planteado innumerables problemas y muchos de esos típicos "pero si esto funcionaba" o  "en mi equipo se ve bien", a los que tanto estamos acostumbrados los que trabajamos en desarrollo.


Estos problemas no se deben a que Sharepoint no sea potente, sea difícil de manejar para tareas comunes o no permita hacer casi nada, sino todo lo contrario. Debido al grado de personalización y funcionalidades que hemos configurado y/o añadido para intentar lograr una herramienta atractiva y que facilite tareas que durante varios años hemos visto que resultaban tediosas para la gente, nos hemos encontrado con cosas que desaparecen, navegadores que hacen lo que les apetece, configuraciones que parecen imposibles de lograr, y complejidades que creíamos más fáciles de resolver.


Tampoco son asuntos exclusivos de Sharepoint 2013. En ocasiones eran los diferentes navegadores (y la diferencia entre versiones de cada uno) los que nos llevaban por el camino de la desesperación preguntándonos por qué no llegarán a un consenso y cumplen los estándares mejor o al menos de igual modo en todos ellos.


Durante una serie de entradas del blog os describiremos algunas de estas cosas y cómo las hemos solucionado. No queremos decir que estas soluciones sean las mejores que vais a ver o que sean las definitivas para esos problemas en todas las situaciones. Son las que nosotros hemos decidido utilizar teniendo en cuenta las particularidades de nuestro proyecto tras realizar pruebas y valorar los pros y contras que se presentaban, pero os pedimos que si encontráis modos más óptimos nos escribáis con ellos para mejorar y aprender cosas nuevas.


Sobre el nuevo proyecto, de momento solo os podemos decir que queda muy poco para que esté disponible y que esperamos que guste tanto como a nosotros nos ha gustado desarrollarlo. Se ha preparado con mucha ilusión, se ha pensado mucho, y se ha dedicado mucho esfuerzo en él ya que la ocasión después de tantos años lo requería. Como decían en el "Un dos tres": ¡hasta aquí podemos leer!

mar. 10
Restauración de aplicaciones de servicio de búsquedas en SharePoint 2013

​En SharePoint 2013, al igual que en SharePoint 2010, se pueden llevar a cabo restauraciones de aplicaciones web y de servicio desde la administración central o desde línea de comandos con PowerShell; esta segunda es la que usaremos para mostrar cómo restaurar una aplicación de servicio de búsquedas de SharePoint 2010 a SharePoint 2013.

En el siguiente enlace de technet tenemos el paso a paso que nos permitirá ejecutar una correcta actualización de nuestras aplicaciones de servicio disponibles en SharePoint 2010 a SharePoint 2013. Personalmente creo que documentarse y documentar antes de hacer nada es fundamental, sobre todo en procesos de migración, y sobra decir que siempre hay que pasar por un entorno de pruebas, donde podamos identificar previa implantación cualquier fallo que pueda producirse por el cambio de versión así como en los desarrollos que llevemos a cabo; por tanto esta guía es de lectura más que recomendada.

A grandes rasgos, los puntos más destacados del proceso de actualización de una aplicación de servicio son:

  • Obtener el backup de la aplicación de servicio
  • Crear en el nuevo servidor de bases de datos la base de datos a través de la restauración del backup
  • Por línea de comandos crear la aplicación de servicio deseada
  • Por línea de comandos crear el proxy de la aplicación de servicio deseada

 

En lo que a las aplicaciones de servicio de búsqueda se refiere, uno de los errores más habituales que podemos encontrarnos a la hora de crear una aplicación del servicio de búsquedas a través del "adjuntado" o "atachado" de una base de datos es que nos indique que la base de datos no es válida ya que no es de administración de búsquedas.

 

 

En nuestro caso este error se produjo porque estábamos utilizando el backup de la aplicación de servicio completa, cuando en realidad sólo hace falta la de administración. Para solucionarlo bastará con realizar un backup de dicha base de datos, repetir el proceso de restauración de la misma en el nuevo servidor de bases de datos de la granja SharePoint 2013 y volver a ejecutar la instrucción en la shell:

 
 

 Y listo, ya podemos continuar con la creación del proxy y poder asociarlo así a nuestra aplicación web en SharePoint 2013.

ene. 28
Teoría de las limitaciones o teoría de las restricciones - Theory of Constraints Parte 1

Eliyahu M. Goldratt, en su libro “La meta: un proceso de mejora continua”, comienza definiendo el termino de productividad como “la realización del trabajo de acuerdo a una meta”. Pero ¿Cuál es la meta de una empresa?, aplicando la lógica más aplastante “la meta de una empresa es ganar dinero”. Yo creía que ya no había gente que no pensara esto, pero efectivamente tal y como nos cuenta Goldratt, aún existe mucha gente que se piensa que la meta es alguna de las siguientes:

  • Aumentar los rendimientos de producción
  • Elaborar productos de calidad
  • Alcanzar una tasa determinada de mercado
  • Conseguir comprar barato
  • Invertir en I+D+i
  • Aumentar el número de ventas

No se dan cuenta de que esto son realmente medios para alcanzar dicha meta, pero que cada uno de ellos por sí solos no van a conseguir que la empresa gane dinero, sino que incluso pueden hacer que la empresa quiebre.

Goldratt nos lleva hacía el camino de parametrizar la empresa y no utilizar únicamente el ROI (retorno de inversión) y el beneficio neto como parámetros, ya que empresas que arrojan beneficios y poseen un ROI positivo han llegado a quebrar por falta de liquidez.

Los parámetros propuestos en TOC son tres:

  • Throughput o ingresos, es la capacidad de la empresa para ganar dinero, esto es, los ingresos por las ventas menos el coste productivo de materias primas.
  • Inventario, es el material inmovilizado en alguna de las fases de la cadena de producción, es el dinero que se encuentra dentro del sistema (es el dinero empleado o invertido en adquirir la materia prima para venderlo y ya la tenemos ensamblada o procesada)
  • Gastos de operación, que son los costes que empleamos en convertir el inventario en ingresos netos

Y lo que propone TOC es la necesidad de mejorar los tres parámetros al tiempo.

Para ellos nos hemos de fijar en la empresa como un TODO, como una cadena que hay que mejorar. Hemos de empezar a pensar que si los óptimos locales no influyen en la productividad global, lo único que  nos están generando es exceso de inventario (recordemos que consideramos inventario al material inmovilizado y que es dinero perdido que no está entrando en la empresa y que se va devaluando con el tiempo).

Pongamos un ejemplo:

En la cadena de producción más sencilla dos procesos A y B se ejecutan para desarrollar un producto X

A --> B = X

Si la productividad máxima de A (PA) son 20 piezas/hora y la productividad máxima de B (PB) también son 20 piezas/hora. ¿Qué le ocurre al sistema si aumentamos la productividad de A en un 20 % al invertir en la mejora de dicho proceso?

PA --> pasa a ser 24 p/h

PB --> 20 p/h

El proceso

A --> B --> X

Nos genera 20 p/h independientemente del aumento de productividad de A. EL problema añadido al aumento de productividad local es que los inventarios de material sin procesar entre A y B va aumentando a 4 p/h, con lo que tarde o temprano ese “aumento” de productividad local nos llevará a tener que parar el proceso A para poder eliminar ese inventario precedente a B (un desastre en la gestión de recursos).

Lo que nos ha ocurrido es que los costes por unidad de A han bajado al aumentar su productividad, pero los gastos de operación han aumentado debido al material inmovilizado.

Otro ejemplo es si A aumenta su productividad un 50% y B aumenta su productividad un 30 % el aumento real de la productividad es de un 30 % ya que B es lo que definiremos como una limitación del sistema o cuello de botella y es quien marcará el ritmo de producción de nuestro proceso de fabricación.

Resumiendo:

Vamos a tener tres parámetros dinero ingresado (Throughput), dinero retenido dentro (inventario) y dinero que sale (gastos de operación) y un cuarto parámetro que es la necesidad de mercado, que nos determina el valor de nuestros productos y el que marcará el objetivo al que hemos de fabricar (no se puede mejorar nuestra cadena de producción si con ello generamos una cantidad de producto superior a la demanda ya que se nos convertiría en inventario).
 

oct. 08
Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (5)

En esta última entrada de la serie de posts sobre el desarrollo de una solución tipo SandBox para personalizar nuestro archivo de entradas de blog en SharePoint 2010, veremos los últimos métodos que nos ayudarán a completar la lógica de la solución. Además, daremos las pautas para el despliegue y uso de la webpart creada.

La serie completa consta de un total de cinco entradas:

 

Siguiendo con la anterior entrada, el método seleccionaMeses se encarga de crear la estructura HTML para el año pasado si en éste existen meses con entradas publicadas. Como ya comentamos anteriormente, este método recibe un control HTML, el valor de año sobre el que queremos extraer los meses con entradas, y un valor booleano que indicará que si es el primer año a añadir al control, sus meses aparecerán "desplegados". La cabecera del método es la siguiente:

 
private void seleccionaMeses(HtmlGenericControl archivo, string year, bool isFirst)
 

Lo primero que haremos en el cuerpo del método es definir los controles HTML que utilizaremos para ir dándole la estructura que queramos. El primero de ellos será la cabecera, que contendrá el año con un enlace que tendrá asociado en el evento "onclick" la llamada a un función JavaScript que hemos creado y añadido a la cabecera de la página después de la carga del código de la webpart, es decir, en el método RenderContents; esta sencilla función lo que hace es trabajar sobre el DOM para cambiar por estilos el valor de la propiedad "display" del control que contiene la lista de meses.

A continuación, lo que haremos será entrar en un bucle en el que crearemos una consulta dinámica de modo que obtengamos el número de entradas publicadas en el mes y año pasados; si la cuenta es mayor a cero procedemos a crear un control HTML cuyo contenido será el nombre del mes enlazado a la página por defecto "Date.aspx", que lista todas las entradas comprendidas en un período de tiempo pasado.
 
//Archivo para el año year
for (int i = 1; i <= 12; i++){
     //Crea la consulta para filtrar las entradas publicadas en el mes que estamos mirando y cuyo año coincidan con el pasado
     SPQuery condicion = new SPQuery();
     condicion.Query = @"<Where><And><Eq><FieldRef Name='numMes'/><Value Type='Text'>" + i.ToString() +     "</Value></Eq><Eq><FieldRef Name='year'/><Value Type='Text'>" + year + "</Value></Eq></And></Where>";
 
     //Si se obtienen correspondencias, es que hay entradas publicadas en el mes que estamos mirando
     var cuenta = entradas.GetItems(condicion).Count;
     if (cuenta > 0){
 
         DateTime dt = new DateTime(1900, i, 1);
 
         /*
          * Establece las fechas límite para el enlace (startDate y endDate) y su título
          */
          var startDate="";
          var endDate = "";
          var titulo = "";
 
          //Si mes actual = 1 -> mes anterior es 12 y año -> año - 1
          if (i == 1) {
              startDate = ultimoDia("12", (int.Parse(year) -1 ).ToString());
          }
          //Para el resto de meses, el mes a pasar será el anterior del mismo año: i-1
          else {
              startDate = ultimoDia((i-1).ToString(), year);
          }
 
          endDate = ultimoDia(i.ToString(), year); // último día del mes actual (con entradas publicadas)
          titulo = dt.ToString("MMMM", blog.Locale) + ", " + year;
 
         /*
          * Crea el control HTML en el que se pinta el nombre del mes enlazado a la página Date.aspx
          * de la forma “Date.aspx?StartDateTime=" + startDate +  "&EndDateTime=" + endDate + "&LMY=" + titulo”
          * y lo añade al control donde agrupamos todos los meses
          */
      }
}
 
Las fechas para formar este rango se pasan en formato ISO8601. Cabe recordar que la fecha de inicio debe ser el último día del mes anterior y la de fin el último día del mes del que queremos el listado. Por ello hemos creado un método que nos devuelve una cadena de texto con la fecha en ISO8601 del último día del mes y año pasados, y al que llamaremos para obtener ambas fechas. La lógica para obtener el último día de un mes es trivial, así que omitiremos aquí el código de la función.
 
Finalmente, además de registrar la función JavaScript que se encarga de mostrar u ocultar los meses de un año, también registraremos en el RenderContents el fichero CSS que el usuario haya indicado en las propiedades personalizadas de la webpart; comprobando antes que la URL pasada sea relativa y se aloje en la biblioteca de nuestro blog.
 
 

Desplegando la solución SandBox

 
Con esto damos por completado el desarrollo de nuestra solución, ahora, después de haber depurado el código y probado que funciona como es de esperar, empaquetaremos nuestra solución para obtener el fichero .wsp, que cargaremos en la galería de soluciones de nuestro sitio de blog.
 
 Solución cargada en la galería de soluciones
 
Cargar solución SandBox en la galería de soluciones del sitio
 
 
 
O, si hemos utilizado Visual Studio 2012 para desarrollarla (como es el caso), podemos publicarla directamente en el sitio.
 
Despliegue de solución sandbox desde Visual Studio 2012 
Despliegue de la webpart SandBox desde Visual Studio 2012
 
 
Al pinchar en el botón "Publish" nos pedirá las credenciales para autenticarnos en el sitio, como es lógico, y tras ello y una vez cargada, se nos redireccionará a la galería de soluciones. Lo último necesario para poder añadirla en nuestras páginas es activar la solución. Después bastará con editar las páginas y buscarla bajo la categoría que hayamos definido en el fichero Elements.xml (sino será la categoría por defecto).
 
 Webpart personalizada para el archivo de entradas de blog
 
Webpart disponible para utilizar en modo edición
 
 
Pues ya está, editamos las propiedades según el tipo de archivo que queramos y si queremos aplicarle algún estilo creado y listo, ¡a otra cosa!
 
 
oct. 02
Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (4)

​Después de la última entrada 'Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (3)' de la serie de post que venimos realizando, continuaremos con el desarrollo de nuestra webpart y comenzaremos a crear los métodos que nos van a permitir crear el archivo de las entradas.

La serie completa consta de un total de cinco entradas:

 

De nuevo, recordemos que tenemos que conseguir saber si un mes-año tiene entradas publicadas. Como ya adelantamos en la entrada anterior, para esto necesitaremos extraer el mes y el año del valor de la fecha de publicación de cada elemento de la lista "Entradas de blog". Por ello crearemos dos nuevas columnas calculadas en la lista, que se inicializarán automáticamente con el valor que les corresponda, y finalmente podremos usar dichas columnas para crear las queries que nos permitan obtener los post publicados en un determinado mes y año.
 
Para realizar consultas en SharePoint utilizaremos objetos de tipo SPQuery, a los que debemos pasarle la condición que los elementos resultado deben cumplir en CAML (Collaborative Application Markup Language).

En dicha condición es donde utilizaremos las dos nuevas columnas comentadas antes. Por defecto estas columnas no existen y por tanto las crearemos desde nuestra solución: las columnas serán calculadas a partir de una fórmula que utilizará las funciones de fechas MONTH() y YEAR(); que como sus nombres indican nos permiten obtener el mes y el año de una fecha pasada, en nuestro caso ésta será, como ya dijimos, la de fecha de publicación.

Vamos por tanto a definir en nuestro .ascx.cs los dos métodos que se encargan de crear estas columnas personalizadas sobre la lista de entradas de nuestro blog:

#region modificacionesEnElSitioDeBlog
   /// <summary>
   /// Crea en la lista pasada una columna calculada que se llamará numMes y cuyo 
   /// valor es la representación numérica del mes de publicación. 
   /// En la fórmula deberemos utilizar el display name con que aparece en nuestro sitio  
   /// la columna de fecha de publicación.
   /// </summary>
   /// <param name="entradas">Instancia de la lista de entradas de blog</param>
   /// <param name="publicada">Display name de la columna de fecha de publicación</param>
   private void creaNumMesEntrada(SPList entradas, string publicada)
   {
      //creamos una la nueva columna con la fórmula para su cálculo según lo especificado
      string colName = entradas.Fields.Add("numMes", SPFieldType.Calculated, false);
      SPFieldCalculated col = (SPFieldCalculated)entradas.Fields[colName];
      col.Formula = "=CONCATENATE(MONTH("+publicada+"))";
      col.Update();
   }

   /// <summary>
   /// Crea en la lista pasada una columna calculada que se llamará year y cuyo 
   /// valor es la representación numérica del año de publicación. 
   /// En la fórmula deberemos utilizar el display name con que aparece en nuestro sitio 
   /// la columna de fecha de publicación.
   /// </summary>
   /// <param name="entradas">Instancia de la lista de entradas de blog</param>
   /// <param name="publicada">Display name de la columna de fecha de publicación</param>
   private void creaYearEntrada(SPList entradas, string publicada)
   {
      //creamos una la nueva columna con la fórmula para su cálculo según lo especificado
      string colName = entradas.Fields.Add("year", SPFieldType.Calculated, false);
      SPFieldCalculated col = (SPFieldCalculated)entradas.Fields[colName];
      col.Formula = "=CONCATENATE(YEAR(" + publicada + "))";
      col.Update();
   }
#endregion

Desde el Page_Load, además de comprobar que el usuario nos haya pasado la información de las propiedades personalizadas de forma correcta y de instanciar las variables de clase privadas del sitio de blog y la lista de entradas, llamaremos a las funciones anteriores si es necesario:

protected void Page_Load(object sender, EventArgs e)
{
   try
   {
      //Instancia el sitio de blog actual
      blog = SPContext.Current.Web;
 
      //Obtiene la lista de entradas de blog
      entradas = blog.Lists.TryGetList(EntradasDeBlog);
 
      //Se asegura de que la lista de entradas se ha podido obtener
      if (entradas == null) {
         throw new Exception("Compruebe si existe la lista de entradas en el sitio de blog");
      }
 
      //Comprueba que el año pasado en la WP es un valor numérico y de longitud 4, o vacío
      int a;
      if (((YearArchivo.Length == 4 && int.TryParse(YearArchivo, out a) == true)
      || YearArchivo.Length == 0) == false) {
         throw new Exception("Compruebe que el año para obtener el archivo de entradas es de 4 cifras o vacío");
      }
      //Obtiene la columna con nombre interno PublishedDate
      SPField publishedDate = entradas.Fields.GetFieldByInternalName("PublishedDate");
 
      //Si no existe la columna calculada 'numMes' {=CONCATENATE(MONTH(Publicada))}, la añade
      if (entradas.Fields.TryGetFieldByStaticName("numMes") == null) {
         blog.AllowUnsafeUpdates = true;
         creaNumMesEntrada(entradas, publishedDate.Title);
         blog.AllowUnsafeUpdates = false;
      }
 
      //Si no existe la columna calculada 'year' {=CONCATENATE(YEAR(Publicada))}, la añade
      if (entradas.Fields.TryGetFieldByStaticName("year") == null) {
         blog.AllowUnsafeUpdates = true;
         creaYearEntrada(entradas, publishedDate.Title);
         blog.AllowUnsafeUpdates = false;
      }
 
      //Crea y muestra el código HTML con los datos obtenidos
      pintaArchivo();
   }
   catch (Exception ex) { System.Diagnostics.Debug.WriteLine("ERROR: "+ ex.Message); }
}

Una vez que tenemos creadas las columnas, seguiremos trabajando para completar nuestra lógica de modo que vayamos construyendo el HTML resultante con el que mostraremos el listado de archivo de nuestro blog. Diferenciaremos principalmente dos situaciones, a saber:

  • Se desea el archivo completo, es decir, no se ha especificado un año concreto en las propiedades personalizadas de la webpart
  • Se desea únicamente el archivo de entradas de un año determinado que recibimos en las propiedades personalizadas de la webpart
 
La condición en la que nos basaremos para determinar estos dos posibles caminos se basa en el valor del año leído de las propiedades personalizadas; y es la siguiente:

//Histórico completo
if (YearArchivo.Length == 0) {
   //Obtiene todos los años en los que se han publicado entradas en el blog
   SPQuery condicion = new SPQuery();
   condicion.Query = @"<OrderBy><FieldRef Name='year' Ascending='FALSE' /></OrderBy><FieldRef Name='year' />";
   DataTable table = entradas.GetItems(condicion).GetDataTable();
   table = new DataView(table).ToTable(true, "year");
   bool isFirst = true;
   foreach (DataRow r in table.Rows) {
      //Pasa el control HTML donde se añadirá el archivo de entradas del año year
      seleccionaMeses(archivo, r["year"].ToString(), isFirst);
      isFirst = false;
   }
}
//Histórico del año pasado
else {
   seleccionaMeses(archivo, YearArchivo, true);
}

Si se quiere obtener el archivo completo de entradas de blog, crearemos una primera consulta sobre la lista de entradas de blog de modo que obtengamos todos los años en los que se han publicado posts en orden descendente; también podríamos haber decidido hacerlo en orden ascendente, o incluso convertirlo en una propiedad personalizada más para que sea el usuario quien realmente decida en qué orden quiere el archivo.
 
Como el método GetItems nos devuelve una colección de elementos de lista, la transformaremos en una tabla de filas únicas, de modo que sea más sencillo recorrer todos los valores. Para cada año leído, llamaremos al método seleccionaMeses, que recibe el control "archivo", que hemos definido, inicializado y añadido previamente al control creado desde la vista de diseño de la webpart en un principio. Pasaremos además como parámetros el año, del que queremos extraer el histórico de meses, y un booleano, que utilizaremos para saber si hay que mostrar los meses que obtengamos del año pasado (en caso de que sea el primero) o no.
 
Por el contrario, si sólo queremos pintar el archivo de entradas de un año específico, simplemente llamaremos al método seleccionaMeses; pasándole el control "archivo", el año leído de las propiedades personalizadas de la webpart, y el valor booleano true.

En la próxima entrada comentaremos qué hace exactamente el método seleccionaMeses y daremos las últimas indicaciones para ir completando nuestra solución.

sep. 18
Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (3)

​En esta tercera entrada de la serie de posts que venimos siguiendo con la finalidad de crear una solución tipo SandBox para crear un nuevo archivo de entradas de un blog en SharePoint 2010, comenzaremos a desarrollar nuestra solución. En la segunda entrada 'Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (2)' analizamos algunos aspectos con los que trabaja SharePoint, como el formato de las fechas, y la forma en la que conseguiremos todos los datos que necesitamos para construir la lógica.

 
Para comenzar, recordemos que el primer requisito era saber si existen o no entradas publicadas para cada mes-año. La forma más sencilla de resolver esto es crear en la lista de entradas de nuestro blog dos nuevas columnas que contendrán automáticamente los valores numéricos del mes y el año de la fecha de publicación de cada entrada. Con ello ya seremos capaces de obtener el número de elementos en los que su mes y año coincide con unos criterios pasados y de este modo no pintar en el archivo los meses en los que no se hayan publicado entradas.
 
Por tanto, necesitaremos hacer modificaciones de forma programática sobre la lista de Entradas de blog:
  • Añadir una columna calculada, numMes, que será el mes obtenido a partir de la fecha de publicación de la entrada de blog.
  •  
  • Añadir una columna calculada, year, que será el año obtenido a partir de la fecha de publicación de la entrada de blog.
 
Antes de comenzar a desarrollar nuestra solución es importante destacar que hay cierta información que recogeremos del usuario, pues de un modo u otro afectarán al resultado final; para esto debemos definir propiedades personalizadas a nuestra webpart. Añadiremos las siguientes:
  • El título o nombre que se muestra de la lista de entradas de blog
  •  
  • El título que queremos que aparezca a modo de cabecera en nuestra webpart
  •  
  • El año del que queremos sacar el histórico de entradas por mes; tal vez queramos el histórico de un único año en vez del total
  •  
  • URL del fichero CSS donde hemos definido los estilos personalizados para esta webpart en nuestro blog, de la forma: /Style Library/BlogCSS/archivo.css
 
Con todo esto en mente procederemos a crear nuestra solución.
 

Comenzando a desarrollar la solución

 
En Visual Studio (2012 en nuestro caso) creamos un nuevo proyecto vacío de SharePoint y a continuación añadimos un nuevo elemento de tipo Visual Web Part, al que llamamos igual que al proyecto, archivoBlogWP:
 
crear proyecto vacío con visual webpart 
Añadimos al proyecto vacío un nuevo elemento de tipo "Visual Web Part"
 
 
explorador de soluciones con la visual web part 
 
 En el explorador de soluciones vemos todos los ficheros creados tras añadir el elemento
 

En primer lugar nos iremos a nuestra página de diseño de la webpart (.ascx) y escribiremos en ella un par de etiquetas HTML que nos permitan servir de marco para el archivo que iremos pintando en ellas, algo así:

<div class="ArchivesWP">
    <div ID="listadoArchivo" runat="server"></div>
</div>
 
Lo siguiente que haremos (antes de que se nos olvide) será crear, dentro de nuestro fichero .webpart, las propiedades personalizadas que permitiremos que edite el usuario para pasarnos datos adicionales, como ya comentamos antes. Entre las etiquetas <data> </data> definiremos las propiedades de la siguiente forma:
 
<properties>
    <property name="Title" type="string">WebPart de archivos personalizada</property>
    <property name="Description" type="string">Archivo personalizado</property>
    <property name="EntradasDeBlog" type="string">Entradas de blog</property>
    <property name="TituloArchivo" type="string">Archivos</property>
    <property name="YearArchivo" type="string">2012</property>
    <property name="URLCSS" type="string">URL del fichero CSS</property>
</properties>
 
Una vez definidas las propiedades que se podrán pasar, deberemos instanciarlas desde el code-behind, que contiene la lógica de la webpart, de modo que podamos trabajar con ellas. Esto lo haremos dentro del fichero .ascx.cs:
 
       /*Display name de la lista de entradas de blog*/
     [WebBrowsable(true),
     WebDisplayName("Entradas de blog"),
     WebDescription("Introducir el display name (título) de la lista de entradas de blog"),
     Personalizable(PersonalizationScope.Shared),
     Category("Datos para obtener el archivo")]
     public string EntradasDeBlog { get; set; }

     /*Título del archivo que se quiera utilizar*/
     [WebBrowsable(true),
     WebDisplayName("Título del archivo"),
     WebDescription("Introducir el título de Archivos que se quiera utilizar"),
     Personalizable(PersonalizationScope.Shared),
     Category("Datos para obtener el archivo")]
     public string TituloArchivo { get; set; }

     /*Año del que queremos el archivo de entradas de blog*/
     [WebBrowsable(true),
     WebDisplayName("Año de archivo de entradas"),
     WebDescription("Introducir el año concreto del que queremos el archivo de entradas de blog"),
     Personalizable(PersonalizationScope.Shared),
     Category("Datos para obtener el archivo")]
     public string YearArchivo { get; set; }

     /*URL del fichero css que se quiera utilizar para aplicar estilos*/
     [WebBrowsable(true),
     WebDisplayName("URL de fichero CSS"),
     WebDescription("Introducir la URL del fichero CSS que se quiera utilizar"),
     Personalizable(PersonalizationScope.Shared),
     Category("Datos para obtener el archivo")]
     public string URLCSS { get; set; }
 
Estas propiedades personalizadas, que hemos definido para poder interactuar con el usuario, aparecerán cuando estemos editando dicha webpart desde nuestras páginas de blog, bajo el grupo de propiedades que hemos denominado "Datos para obtener el archivo":
 
propiedades personalizadas de la webpart desde la edición de una página 
Vista de las propiedades personalizadas durante la edición

 

Hasta aquí esta entrada en la que hemos comenzado a crear nuestra solución. En próximas entradas continuaremos con el desarrollo y seguiremos comentando los aspectos más importantes de la misma.

ago. 26
Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (2)

Esta entrada es la segunda de una serie de post en los que iremos viendo y planteádonos los diferentes aspectos para crear una solución tipo SandBox que sustituya la web part de archivo de entradas, que se nos da por defecto en los sitios de blog de SharePoint 2010. En la primera entrada 'Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (1)' vimos el escenario que justifica el desarrollo que haremos.

La serie completa consta de un total de cinco entradas:

 

Analizando la webpart de archivo de entradas original

Tras la creación de un sitio de blog en SharePoint 2010 veremos que aparece un archivo de entradas. Mediante una webpart se listan los últimos meses, a partir del actual, y se enlazan a una página de detalle llamada "Date.aspx", pasándole a través de la URL el rango de fechas que delimitan el mes del que se sacará el histórico y el título de la página. Con esta información, SharePoint consigue las entradas publicadas en ese rango de fechas, escribe el título de la página que ha recibido a través de la URL y muestra cada elemento con un diseño (que puede haber sido personalizado con XSL), apareciendo de forma similar a la imagen:

 
 

Página con vista personalizada de entradas publicadas en un mes determinado
 
 
SharePoint trabaja internamente con el formato de fechas ISO 8601, que es de la forma [yyyy-mm-ddThh:mm:ssZ], y que podemos ver cómo usa en el rango de fechas pasadas por parámetros en la URL: 
 
 
Paso de parámetros en la URL
 

 También podemos ver que la fecha de inicio será el último día del mes anterior y la de fin el último día del mes del que queremos el listado.  

Para cumplir el primero de los requisitos, es decir, que no aparezca en el listado del archivo un mes que no contenga entradas publicadas, necesitaremos saber si existen o no entradas publicadas para cada mes-año.
 
Para el segundo y el tercer requisitos, que aparezcan desplegados y accesibles todos los meses con entradas publicadas en el año y conseguir una navegación directa por todos los años y meses en los que hayamos publicado posts, trabajaremos con la información de la lista de entradas para extraer y agrupar los datos según nuestras necesidades.
 
Es decir, lo que necesitamos hacer principalmente son consultas sobre nuestra lista de entradas de blog de modo que obtengamos la cuenta de elementos publicados para cada mes-año, decidiendo así si mostrar dicho mes en el listado de archivo, y podamos agrupar los elementos en una jerarquía de modo que tengamos cada año con su lista de meses en los que hubo publicaciones.
 
En próximas entradas veremos cómo comenzar a desarrolar la solución y veremos los aspectos clave para su consecución final.
 
ago. 13
Crear una solución SandBox para el archivo de entradas de un blog en SharePoint 2010 (1)

​Con esta nueva entrada vamos a seguir los pasos para dar solución a un escenario planteado comúnmente en los sitios de blog creados en SharePoint 2010: mejorar la funcionalidad del archivo de entradas.

La serie completa consta de un total de cinco entradas:
 

Comenzando: escenario propuesto

El escenario que se nos plantea es el siguiente:

Tenemos un sitio de blog en SharePoint 2010 en el que el funcionamiento de la webpart del archivo de entradas de blog (mensual) no cumple nuestras expectativas por los siguientes motivos:
 
Cuando en un mes no se han publicado entradas, la página de detalle aparece vacía, y lo ideal sería que, simplemente, este mes sin entradas no apareciera en el listado de meses del año.
 
Listado de mes sin entradas publicadas 
Listado de un mes sin entradas publicadas
 
En un vistazo sólo aparecen accesibles los históricos de entradas publicadas en los últimos cuatro meses. En cambio, nos gustaría que aparecieran desplegados y accesibles todos los meses con entradas publicadas en lo que va de año.
Archivo de entradas original 
Archivo de entradas original
Del mismo modo, sólo se visualiza el histórico reciente del año actual, y para acceder a entradas de otros años debemos pinchar en un enlace que nos lleva a otra página con el histórico desplegado por años y meses. Sin embargo, para evitar esta redirección, queremos poder explorar todos los meses con entradas publicadas a lo largo de la vida de nuestro blog, es decir, una navegación directa por todos los años y meses en los que hayamos publicado posts.
Histórico completo desplegado 
 Histórico completo original 
 
 
Debido a la naturaleza del caso y de forma que podamos reaprovecharla para otros sitios de blog, crearemos una solución de tipo SandBox, en la que crearemos la webpart que pinte el histórico de archivos siguiendo los requisitos expuestos.

En próximas entradas iremos describiendo los pasos que hemos llevado a cabo para dar respuesta al problema, de modo que el resultado final quede como en la siguiente imagen:

 
 Archivo de entradas creado con solución SandBox
 

 Archivo de entradas final, creado con la solución SandBox

 
1 - 10Siguiente

 ‭(oculto)‬ Herramientas del blog ‭[1]‬