2009-01-07 17 views
7

Me gustaría editar programáticamente mi contenido Wiki de Sharepoint. Una de las ventajas sería agregar índices al entorno Wiki automáticamente.Edición programática del contenido Wiki de Sharepoint

¿Alguien ha podido hacer esto? El lenguaje no importa, pero busca una solución de scripting.

Respuesta

3

Una wiki de SharePoint es solo un tipo especial de biblioteca de documentos. Hay algunas rarezas que me he encontrado al intentar hacer esto.

Una página wiki de SharePoint consiste en un archivo de plantilla y un elemento de lista. Cuando ve la página, los campos del elemento de la lista se insertan en el archivo de la plantilla. Entonces, para actualizar una página wiki, solo tiene que actualizar los campos correctos en el elemento de la lista. (Por cierto, eso también significa que no puede acceder a la plantilla original como lo haría con un archivo en una biblioteca de documentos normal. Hasta ahora, la única forma que he encontrado para obtener la plantilla es descargarla a través de SharePoint Designer).

Además, SharePoint representa automáticamente el contenido wiki cuando accede al elemento de la lista mediante programación. Por lo tanto, nunca fue capaz de conseguir el contenido que contenía "[[mi nombre Link]]", por ejemplo - SharePoint siempre devolver el HTML representado en su lugar, como:

<A class=ms-wikilink href="/MyWikiLibrary/MyLinkName.aspx">My Link Name</A> 

Con un poco de trabajo de expresiones regulares que Sin embargo, debería ser capaz de convertir esto al contenido original de la wiki.

+0

¿Alguien ha descubierto cómo obtener la plantilla sin el diseñador de Sharepoint? –

+1

La expresión regular para analizar los enlaces de la wiki fue fácil; pero no funciona al revés. Si UpdateListItems y en WikiField, deje los [[corchetes]] SharePoint lo convierte en \\ [[corchetes] \\], lo que me deja boquiabierto. No puedo entender cómo evitar eso; si convierto manualmente los enlaces, SharePoint los tratará como enlaces a partir de ese momento (en lugar de marcado wiki sin formato). Perder perder. En SP2010, esto es fijo y todo funciona bien. Estoy intentando que funcione en SP2007. – kamranicus

+1

Encontré la solución. Puede usar el servicio de copia para insertar Y actualizar, solo mantenga el nombre igual. Luego toma el marcado como marcado wiki sin procesar y funciona como se esperaba. ¡INCREÍBLE! – kamranicus

7

Sí. He quitado mi propia API de programación MetaWeblog que gestiona las páginas wiki en SharePoint 2010 y 2007.

Mis fuentes:

El servicio el código para SP 2010 y 2007 es prácticamente idéntico, pero hay algunas advertencias:

  • En 2010, no tiene que preocuparse por administrar el marcado de enlaces de wiki (p. [[soportes]]).
  • En 2007, el marcado de wiki se convierte a su pedido, por lo que debe volver a convertirlo en formato Wiki antes de volver a publicarlo. Al publicar de nuevo, usted no puede usar UpdateListItems, debe usar el servicio de Copia. Esto se debe a que UpdateListItems escapará a cualquier marcado de wiki, haciendo que sus esfuerzos sean inútiles.
  • En nuestro entorno, requerimos RecordType para rellenar antes de registrarnos. ¿Tal vez esto es estándar? Si no configura este campo, su página se mantendrá. Entonces, tengo un condicional que establece este campo para SP2007.
  • En 2010, SP agrega un montón de marcado en el valor crudo de WikiField, y si falta, podría estropear los diseños. Solo lo inserto alrededor del valor que WLW está publicando, luego lo quito para obtenerlo. Vea abajo.

Utilizo el servicio de copia como en el primer enlace para crear Y actualizar las páginas de la wiki. En 2010, usted puede utilizar el servicio de Listas para actualizar, pero no para agregar. Uso el servicio de imágenes para subir imágenes automáticamente a una biblioteca de imágenes.

Aquí es una función para reemplazar los "MS-WikiLinks" para el código wiki:

Nota: uso el HTMLAgilityPack en caso de que el margen de beneficio es devuelto con formato incorrecto. Podría usar Regex para hacer esto también. También utilizo la biblioteca Microsoft Anti-XSS 4.1 para sanitizar el marcado.

Nota 2: Mi función UrlDecode no toma una dependencia de System.Web, taken from here.

/// <summary> 
/// Sharepoint 2007 is mean and converts [[wiki links]] once the page is saved in the Sharepoint editor. 
/// Luckily, each link is decorated with class="ms-wikilink" and follows some conventions. 
/// </summary> 
/// <param name="html"></param> 
/// <returns></returns> 
private static string ConvertAnchorsToWikiLinks(this string html) 
{ 
    HtmlDocument htmlDoc = new HtmlDocument(); 

    htmlDoc.LoadHtml(html); 

    var anchorTags = (from d in htmlDoc.DocumentNode.Descendants() 
         where d.Attributes.Contains("class") && d.Attributes["class"].Value == "ms-wikilink" 
         select d).ToList(); 

    foreach (var anchor in anchorTags) 
    { 
     // Two kinds of links 
     // [[Direct Link]] 
     // [[Wiki Page Name|Display Name]] 
     var wikiPageFromLink = UrlDecode(anchor.Attributes["href"].Value.Split('/').LastOrDefault().Replace(".aspx", "")); 
     var wikiPageFromText = anchor.InnerText; 

     HtmlNode textNode = null; 

     if (wikiPageFromLink == wikiPageFromText) 
     { 
      // Simple link 
      textNode = HtmlTextNode.CreateNode("[[" + wikiPageFromText + "]]"); 
     } 
     else 
     { 
      // Substituted link 
      textNode = HtmlTextNode.CreateNode(String.Format("[[{0}|{1}]]", wikiPageFromLink, wikiPageFromText)); 
     } 

     if (textNode != null) 
     { 
      anchor.ParentNode.ReplaceChild(textNode, anchor); 
     } 
    } 

    return htmlDoc.DocumentNode.InnerHtml; 
} 

La función de despojar HTML de SharePoint es:

/// <summary> 
/// Gets editable HTML for a wiki page from a SharePoint HTML fragment. 
/// </summary> 
/// <param name="html"></param> 
/// <returns></returns> 
public static string GetHtmlEditableContent(string html) 
{ 
    HtmlDocument htmlDoc = new HtmlDocument(); 

    htmlDoc.LoadHtml(html); 

    HtmlNode divNode = (from d in htmlDoc.DocumentNode.Descendants() 
         where d.Attributes.Contains("class") && d.Attributes["class"].Value == "ms-rte-layoutszone-inner" 
         select d).FirstOrDefault(); 
    HtmlNode divNode2 = (from d in htmlDoc.DocumentNode.Descendants() 
         where d.Attributes.Contains("class") && d.Attributes["class"].Value.StartsWith("ExternalClass") 
         select d).FirstOrDefault(); 

    if (divNode != null) 
    { 
     // SP 2010 
     return divNode.InnerHtml; 
    } 
    else if (divNode2 != null) 
    { 
     // SP 2007 or something else 
     return divNode2.InnerHtml.ConvertAnchorsToWikiLinks(); 
    } 
    else 
    { 
     return null; 
    } 
} 

Y, por último, la función que añade que el marcado todo de vuelta:

/// <summary> 
/// Inserts SharePoint's wrapping HTML around wiki page content. Stupid! 
/// </summary> 
/// <param name="html"></param> 
/// <returns></returns> 
public static string InsertSharepointHtmlWrapper(string html, SharePointVersion spVersion) 
{ 
    // No weird wrapper HTML for 2007 
    if (spVersion == SharePointVersion.SP2007) 
     return Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment(html); 

    HtmlDocument htmlDoc = new HtmlDocument(); 

    htmlDoc.LoadHtml(@"<table id='layoutsTable' style='width:100%'> 
          <tbody> 
           <tr> 
            <td> 
             <div class='ms-rte-layoutszone-outer' style='width:99.9%'> 
              <div class='ms-rte-layoutszone-inner' style='min-height:60px;word-wrap:break-word'> 
              </div> 
             </div> 
            </td> 
           </tr> 
          </tbody> 
         </table> 
         <span id='layoutsData' style='display:none'>false,false,1</span>"); 

    HtmlNode divNode = (from d in htmlDoc.DocumentNode.Descendants() 
         where d.Attributes.Contains("class") && d.Attributes["class"].Value == "ms-rte-layoutszone-inner" 
         select d).FirstOrDefault(); 

    divNode.InnerHtml = Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment(html); 

    return htmlDoc.DocumentNode.InnerHtml; 
} 

Esto funciona muy bien.

  • Páginas aún conservan último usuario modificado y correcta
  • Páginas conservará toda su historia
  • Las páginas son más fáciles de manejar

Estoy pensando en la publicación de mi API, no es una gran cantidad de Creo que el código es muy útil para aquellos de nosotros que queremos administrar mejor nuestros wikis Sharepoint. Con WLW obtengo carga automática de imágenes, mejor soporte de edición de HTML y soporte para complementos como PreCode Snippet. ¡Es impresionante!

Cuestiones relacionadas