Pergunta

Eu gostaria de editar meu conteúdo Sharepoint Wiki programaticamente. Uma das vantagens seria adicionar índices para o ambiente Wiki automaticamente.

Alguém já foi capaz de fazer isso? Língua não importa, mas à procura de solução de scripting.

Foi útil?

Solução

A SharePoint wiki é apenas um tipo especial de biblioteca de documentos. Há apenas algumas esquisitices eu correr em quando se tenta fazer isso.

página A SharePoint wiki consiste em um arquivo de modelo e um item da lista. Quando você visualizar a página, campos do item da lista são inseridos no arquivo de modelo. Então, para atualizar uma página de wiki, você só tem que atualizar os campos corretos no item da lista. (Aliás, isso também significa que você não pode chegar ao modelo original como você poderia um arquivo em uma biblioteca de documentos normal. Até agora, a única maneira que eu encontrei para obter o modelo em si é para baixá-lo através do SharePoint Designer.)

Além disso, o SharePoint torna automaticamente o conteúdo wiki quando você acessar o item da lista de programação. Então, eu nunca fui capaz de obter o conteúdo que continha "[[Meu Nome do Link]]", por exemplo - SharePoint seria sempre retornar o HTML processado em vez disso, como:

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

Com um pouco de trabalho regex você deve ser capaz de converter esta de volta para o conteúdo wiki original, apesar de tudo.

Outras dicas

Sim. Tenho rolou minha própria API MetaWeblog que programaticamente gere páginas wiki no SharePoint 2010 e 2007.

As minhas fontes:

O código de serviço tanto para SP 2010 e 2007 é praticamente idêntica, mas há algumas ressalvas:

  • Em 2010, não precisa se preocupar com a gestão ligação wiki markup (por exemplo [[colchetes]]).
  • Em 2007, wiki markup é convertido em seu pedido, então você tem que re convertido-lo para Wiki antes de postagem de volta. Na postagem de volta, você não pode Usar UpdateListItems, você deve usar o serviço de cópia. Isso ocorre porque UpdateListItems vai escapar de qualquer wiki markup, efetivamente tornando seus esforços inúteis.
  • Em nosso ambiente, que exigem RecordType deve ser preenchido antes de check-in. Talvez esta é padrão? Se você não definir esse campo, sua página ficará reservado para si. Então, eu tenho uma condicional que define este campo para SP2007.
  • Em 2010, SP adiciona um monte de marcação no valor WikiField cru, e se estiver faltando isso poderia atrapalhar layouts. Eu só inseri-lo em torno do valor WLW é postagem, em seguida, tira-lo para fora em começar. Veja abaixo.

Eu uso o serviço de cópia como no primeiro link para criar e atualizar as páginas wiki. Em 2010, você pode usar o serviço de listas de atualização, mas não adicionar. Eu uso o serviço de imagem para carregar imagens automaticamente para uma biblioteca de imagens.

Aqui está uma função para substituir o "MS-wikilinks" para wiki marcação:

Nota: Eu uso o HtmlAgilityPack no caso da marcação retornado é mal formado. Você poderia usar Regex para fazer isso também. Eu também uso Microsoft Anti-XSS 4.1 biblioteca para sanear marcação.

Nota 2: função My UrlDecode não toma uma dependência em System.Web, tomada a partir daqui .

/// <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;
}

A função para tirar HTML do SharePoint é:

/// <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;
    }
}

E, finalmente, a função que acrescenta que markup tudo de volta:

/// <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;
}

Isso funciona muito bem.

  • Páginas ainda mantêm modificada pela última vez e usuário correto
  • Páginas manterá toda a sua história
  • As páginas são mais fáceis de gerir

Estou pensando em publicar meu API, não é um monte de código eu acho que é super útil para aqueles de nós que querem gerenciar melhor o nosso Sharepoint wikis. Com WLW eu recebo carregamento auto-imagem, melhor suporte a HTML edição e suporte para plugins como cigo prio trechos. É impressionante!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top