Pregunta

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

¿Alguien ha podido hacer esto? El idioma no importa, pero busca una solución de secuencias de comandos.

¿Fue útil?

Solución

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

Una página wiki de SharePoint consta de 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 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 obtener 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 en sí 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 pude obtener el contenido que contenía " [[My Link Name]], " por ejemplo: SharePoint siempre devolvería el HTML representado, como:

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

Sin embargo, con un poco de trabajo de expresiones regulares, debería poder volver a convertir esto al contenido wiki original.

Otros consejos

Sí He creado mi propia API Metaweblog que gestiona mediante programación las páginas wiki en Sharepoint 2010 y 2007.

Mis fuentes:

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

  • En 2010, no necesita preocuparse por administrar el marcado de enlaces wiki (por ejemplo, [[paréntesis]]).
  • En 2007, el marcado wiki se convierte en su solicitud, por lo que debe volver a convertirlo al marcado Wiki antes de volver a publicarlo. Al volver a publicar, no puede usar UpdateListItems, debe usar el servicio Copiar. Esto se debe a que UpdateListItems escapará a cualquier marcado wiki, haciendo que sus esfuerzos sean inútiles.
  • En nuestro entorno, requerimos que se complete RecordType antes de registrarse. ¿Tal vez esto es estándar? Si no configura este campo, su página permanecerá desprotegida. Entonces, tengo un condicional que establece este campo para SP2007.
  • En 2010, SP agrega un montón de marcas en el valor sin procesar de WikiField, y si falta, podría estropear los diseños. Simplemente lo inserto alrededor del valor que WLW está publicando, luego lo elimino al obtenerlo. Ver abajo.

Utilizo el servicio Copiar como en el primer enlace para crear Y actualizar las páginas wiki. En 2010, puede usar 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í hay una función para reemplazar el " ms-wikilinks " al marcado de wiki:

Nota: utilizo el HTMLAgilityPack en caso de que el marcado devuelto tenga un formato incorrecto. Podrías usar Regex para hacer esto también. También uso la biblioteca Microsoft Anti-XSS 4.1 para desinfectar el marcado.

Nota 2: Mi función UrlDecode no depende de System.Web, tomado de aquí .

/// <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 para eliminar el 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 finalmente, la función que agrega ese 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.

  • Las páginas aún conservan el último usuario modificado y correcto
  • Las páginas conservarán todo su historial
  • Las páginas son más fáciles de administrar

Estoy pensando en publicar mi API, no es mucho código, creo que es muy útil para aquellos de nosotros que queremos gestionar mejor nuestros wikis de 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 increíble!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top