En un entorno MOSS 2007 ya en producción con un tipo de contenido desplegado y millones de listas referenciándolo (exageración), necesitamos hacer una modificación sobre una de las columnas; concretamente ocultarla de los NewForm y EditForm. Para ello tenemos recursos suficientes y sabemos que es posible alterarla con PowerShell, llegando a SPWeb.Fields, de ahí obtener el SPField y modificar sus propiedades ShowInNewForm y ShowInEditForm.
Pero... ¡ay! Una vez realizada la modificación vemos que en las columnas de cada lista no se ha propagado el cambio. ¿Qué sucede? Vamos a repasar el esquema de propagación:
Columna de sitio –> Referencia a la columna en el tipo de contenido –> Columna de lista
En la columna de sitio hemos conseguido establecer los valores correctos de ShowInNewForm y ShowInEditForm pero si accedemos a la colección de SPField’s del tipo de contenido los valores no han cambiado. Es decir, el esquema de propagación se ha interrumpido a nivel de tipo de contenido.
¿Qué podemos hacer para actualizar esas propiedades sin tener que modificar el SPField lista por lista? Uno diría: si el tipo SPContentType tiene también una colección de SPField’s, podría modificarse desde ahí. Pues no. SharePoint devuelve el siguiente mensaje:
This functionality is unavailable for fields not associated with a list.
Otro observaría: el tipo SPContentType también dispone de la colección de SPFieldLink’s, quizá desde ahí podemos acceder. Pero tampoco; no tienen pública ninguna de las propiedades ShowIn****Form.
Tragedia. Llanto. Desesperación. Y finalmente, el destello de esperanza. Existe una rendija de la API que permite eliminar un SPFieldLink de un tipo de contenido y volverlo a añadir, todo en una misma “transacción” (es decir, eliminar, añadir y actualizar entonces el tipo de contenido). La cosa quedaría así:
// Eliminamos la referencia al campo y no llamamos aún a Update
contentType.FieldLinks.Delete(fieldDisplayName);
// Obtenemos la columna de sitio (configurada ya como queremos)
SPField siteColumn = web.Fields[fieldDisplayName];
// Añadimos la referencia a la columna de sitio
SPFieldLink fieldLink = new SPFieldLink(siteColumn);
contentType.FieldLinks.Add(fieldLink);
// Ahora sí, actualizamos el tipo de contenido (y especificamos que propague cambios)
contentType.Update(true);
Funciona. Los cambios se han propagado hasta nivel de lista. Internamente hemos realizado una modificación sobre el esquema Xml de campos del tipo de contenido, pero de forma un poco tramposa. Sea como sea, objetivo cumplido.
0 comentarios:
Publicar un comentario