SharePoint – Destripando el Wiki (4)

En está última parte de Destripando el Wiki, veremos como crear un campo personalizado para cambiar el comportamiento por defecto del SPFieldMultiLineText el usado por WikiField, de modo que podremos cambiar el comportamiento a la hora de visualizar los enlaces a entradas que no están definidas para que estas sean redirigidas a nuestra página CustomCreatePage.aspx.


Como comentaba en anteriores posts, hemos visto que el wiki es una biblioteca de documentos que almacena páginas basadas en un tipo de contenido llamado Página Wiki que hereda de documento. Cuando se crea una nueva página la plantilla llamada wkpstd.aspx se copia en la biblioteca de documentos. Vimos que podemos crear nuestra propia página CreateCustomPage.aspx, para recrear el mismo comportamiento, utilizando nuestras propias plantillas y que esto funcionaba correctamente. Pero el problema llega cuando el campo WikiField se renderiza, ya que mantiene un enlace a CreateWebPage.aspx.


Antes de continuar, creo que es evidente que los errores de diseño en la solución Wiki de Sharepoint son más que notables. Para empezar, han limitado la plantilla incrustando el nombre de la misma en el código de CreateWebPage.aspx, limitando los usos del Wiki. Por otro lado, el campo WikiField, es el campo SPFieldMultiLine, al cual han añadido el método ProcessWikiLinks para realizar la conversión de los enlaces, cuando este debía ser una clase heredada del mismo. Por último, el control a través del cual se renderiza WikiField, es RichTextField, el cual hereda de NoteField, y que debía haber sido también una clase heredada con el fin de que cada una se dedicara a lo suyo y no mezclar distintas funcionalidades aunque sean parecidas en la misma clase, lo cual nos permitiría a los desarrolladores una comprensión mejor del funcionamiento sin tener que buscar donde han ido haciendo los trucos, y nos facilitaría la tarea a la hora de extender SharePoint. Como si no fuera lo suficientemente grande el SDK, como para añadir unas cuantas clases más.


En primer lugar tendremos que crear nuestro propio campo personalizado, yo lo he llamado Wiki que a su vez hereda de SPFieldMultiLineText,  y he sobreescrito GetFieldValueAsHtml, para reemplazar la página por defecto por la nuestra.


 



   1:  public class Wiki : SPFieldMultiLineText
   2:      {
   3:          #region SPField Constructors
   4:   
   5:          public Wiki(SPFieldCollection fields, string fieldName)
   6:              : base(fields, fieldName)
   7:          {           
   8:          }
   9:   
  10:          public Wiki(SPFieldCollection fields, string typeName, string displayName)
  11:              : base(fields, typeName, displayName)
  12:          {        
  13:          }
  14:   
  15:          #endregion
  16:   
  17:          public new string GetFieldValueAsHtml(object value, SPListItem item)
  18:          {            
  19:              string html = base.GetFieldValueAsHtml(value, item);
  20:              return html.Replace(«CreateWebPage», «CreateCustomPage»);
  21:          }
  22:        
  23:          public override BaseFieldControl FieldRenderingControl
  24:          {
  25:              get
  26:              {
  27:                  BaseFieldControl fieldControl = new WikiField();
  28:                  fieldControl.FieldName = InternalName;
  29:                  return fieldControl;
  30:              }
  31:          }
  32:      }

 


Para subsanar el segundo problema, necesitamos crear también un control que llame a nuestro GetFieldValueAsHtml, para lo cual he heredado de NoteField, y sobrescrito el método de RenderFieldForDisplay


 



   1:   public class WikiField : NoteField
   2:      {
   3:   
   4:          protected override void RenderFieldForDisplay(HtmlTextWriter output)
   5:          {
   6:              Wiki field = (Wiki) Field;
   7:              if (field != null)
   8:              {
   9:                  if (field.WikiLinking)
  10:                  {
  11:                      output.Write(«<div class=»ms-wikicontent»>»);
  12:                      output.Write(field.GetFieldValueAsHtml(ItemFieldValue, ListItem));
  13:                      output.Write(«<p></p></div>»);
  14:                      return;
  15:                  }
  16:              }
  17:              else
  18:              {
  19:                  return;
  20:              }
  21:              base.RenderFieldForDisplay(output);
  22:          }
  23:   
  24:      }

 


Y la definición del nuevo campo Wiki


 



   1:   <FieldType>
   2:          <Field Name=»TypeName»>Wiki</Field>
   3:          <Field Name=»ParentType»>Note</Field>        
   4:          <Field Name=»TypeDisplayName»>
   5:              WikiField 
   6:          </Field>
   7:          <Field Name=»TypeShortDescription»>
   8:              WikiField supports custom page
   9:          </Field>
  10:          <Field Name=»UserCreatable»>FALSE</Field>
  11:          <Field Name=»ShowInListCreate»>FALSE</Field>
  12:          <Field Name=»ShowInSurveyCreate»>FALSE</Field>
  13:          <Field Name=»ShowInDocumentLibraryCreate»>FALSE</Field>
  14:          <Field Name=»ShowInColumnTemplateCreate»>FALSE</Field>
  15:          <Field Name=»Sortable»>FALSE</Field>
  16:          <Field Name=»Filterable»>FALSE</Field>
  17:          <Field Name=»FieldTypeClass»>IdeSeg.SharePoint.CustomFields.Wiki.Wiki,
IdeSeg.SharePoint.CustomFields,Version=1.0.0.0,
Culture=neutral, PublicKeyToken=…</Field>
  18:  </FieldType>    


 


Bien, por último solo nos quedaría crear nuestro propio tipo de contenido para poder adjuntarlo a la biblioteca de documentos, como es lógico podríamos crear una definición de lista con el tipo de contenido, pero por abreviar, yo solo he creado el tipo de contenido que después podemos añadir a una biblioteca de documentos.


 


feature.xml



   1:  <Feature Id=»1d9a8ea3-0b7d-42cf-8c64-78df773b7e41″ 
   2:      Title=»IdeSeg Wiki» 
   3:      Description=»Wiki with custom templates» 
   4:      Version=»1.0.0.0″ 
   5:      Scope=»Site» 
   6:      xmlns=»http://schemas.microsoft.com/sharepoint/»>
   7:    <ElementManifests>
   8:      <ElementManifest Location=»fields.xml» />
   9:      <ElementManifest Location=»ctypes.xml» />    
  10:    </ElementManifests>
  11:  </Feature>


 


fields.xml



   1:  <?xml version=»1.0″ encoding=»utf-8″?>
   2:  <!–
   3:  –>
   4:  <Elements xmlns=»http://schemas.microsoft.com/sharepoint/»>
   5:    <Field ID=»{f1d10620-1f85-460b-8132-7c57cd6eABCD}» 
   6:       Name=»WikiFld»
   7:       DisplayName=»Contenido»
   8:       StaticName=»WikiField»
   9:       Group=»_IdeSeg»
  10:       Hidden=»TRUE»
  11:       Type=»Wiki»
  12:       RichText=»TRUE»
  13:       RichTextMode=»FullHtml»
  14:       IsolateStyles=»TRUE»
  15:       RestrictedMode=»FALSE»
  16:       NumLines=»30″
  17:       DisplaySize=»110″
  18:       UnlimitedLengthInDocumentLibrary=»TRUE»
  19:       WikiLinking=»TRUE»
  20:       Sortable=»FALSE»
  21:       Sealed=»TRUE»
  22:       AllowDeletion=»TRUE»>
  23:      </Field>
  24:  </Elements>


 


ctypes.xml



   1:  <?xml version=»1.0″ encoding=»utf-8″?>
   2:  <Elements xmlns=»http://schemas.microsoft.com/sharepoint/»>
   3:    <ContentType ID=»0x0101005ADDEAA7312EE967BFC3076B9699C3D4″
   4:      Name=»IdeSeg Wiki» 
   5:      Group=»_IdeSeg» 
   6:      Description=»IdeSeg Wiki with custom templates»     
   7:      Version=»1″>
   8:      <FieldRefs>
   9:        <RemoveFieldRef ID=»{fa564e0f-0c70-4ab9-b863-0177e6ddd247}» Name=»Title» />
  10:        <FieldRef ID=»{f1d10620-1f85-460b-8132-7c57cd6eABCD}» Name=»WikiField» />
  11:      </FieldRefs>
  12:      <XmlDocuments>
  13:              <XmlDocument NamespaceURI=»http://schemas.microsoft.com/sharepoint/v3/contenttype/forms»>
  14:                  <FormTemplates xmlns=»http://schemas.microsoft.com/sharepoint/v3/contenttype/forms»>
  15:                      <Display>DocumentLibraryForm</Display>
  16:                      <Edit>WikiEditForm</Edit>
  17:                      <New>WikiEditForm</New>
  18:                  </FormTemplates>
  19:              </XmlDocument>
  20:          </XmlDocuments>
  21:          <DocumentTemplate TargetName=»/_layouts/CreateCustomPage.aspx» />
  22:    </ContentType>
  23:  </Elements>
 


He recibido algunos comentarios acerca de el nombre del post «Destripando«, puede que se deba al carácter latino, pero no. En un principio pensé en llamarle Anatomía del Wiki, que sonaba más científico, al igual que Disección del Wiki; Funcionamiento interno del Wiki, sonaba muy clásico y Autopsia del Wiki es para los cadáveres  y moss todavía esta calentito. Destripando el wiki, tiene un sabor más de carnicero, por que lo que estamos haciendo con el wiki, ya que su diseño es de casquería,  Destripando el Wiki, era el título correcto.


 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *