以编程方式编辑Sharepoint Wiki内容

Nic*_*erg 7 sharepoint sharepoint-wiki

我想以编程方式编辑我的Sharepoint Wiki内容.其中一个优点是自动向Wiki环境添加索引.

有没有人能够做到这一点?语言并不重要,但寻找脚本解决方案.

kam*_*cus 7

是.我已经推出了自己的Metaweblog API,它以编程方式管理Sharepoint 2010和2007中的Wiki页面.

我的来源:

SP 2010和2007的服务代码几乎完全相同,但有一些注意事项:

  • 在2010年,不必担心管理维基链接标记(例如[[方括号]]).
  • 在2007年,wiki标记会根据您的请求进行转换,因此您必须在发回之前将其重新转换为Wiki标记.在回发时,您不能使用UpdateListItems,您必须使用复制服务.这是因为UpdateListItems将逃避任何wiki标记,有效地使你的努力无用.
  • 在我们的环境中,我们要求在登记前填写RecordType.也许这是标准的?如果您未设置此字段,您的页面将保持签出状态.所以,我有条件为SP2007设置此字段.
  • 在2010年,SP在原始WikiField值中添加了一堆标记,如果它丢失了,它可能会弄乱布局.我只是将它插入WLW发布的值,然后在获取时将其删除.见下文.

我使用第一个链接中的复制服务来创建和更新Wiki页面.在2010年,您可以使用列表服务进行更新,但不能添加.我使用"成像"服务将图像自动上传到图片库.

这是一个将"ms-wikilinks"替换为wiki标记的功能:

注意:如果返回的标记格式不正确,我会使用HTMLAgilityPack.您也可以使用正则表达式来执行此操作.我还使用Microsoft Anti-XSS 4.1库来清理标记.

注意2:我的UrlDecode函数不依赖于System.Web,取自此处.

/// <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;
}
Run Code Online (Sandbox Code Playgroud)

剥离SharePoint的HTML的功能是:

/// <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;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,将所有标记添加回来的函数:

/// <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;
}
Run Code Online (Sandbox Code Playgroud)

这非常有效.

  • 页面仍保留最后修改和正确的用户
  • 页面将保留所有历史记录
  • 页面更易于管理

我正在考虑发布我的API,我认为对我们这些想要更好地管理我们的Sharepoint wiki的人来说,这并不是很多代码.使用WLW,我可以获得自动图像上传,更好的HTML编辑支持,以及对PreCode Snippet等插件的支持.这很棒!


小智 4

SharePoint wiki 只是一种特殊类型的文档库。当我尝试这样做时,遇到了一些奇怪的情况。

SharePoint wiki 页面由模板文件和列表项组成。当您查看页面时,列表项中的字段将插入到模板文件中。因此,要更新 wiki 页面,您只需更新列表项中的正确字段即可。(顺便说一句,这也意味着您无法像获取普通文档库中的文件一样获取原始模板。到目前为止,我发现获取模板本身的唯一方法是通过 SharePoint Designer 下载它。)

此外,当您以编程方式访问列表项时,SharePoint 会自动呈现 wiki 内容。因此,我永远无法获取包含“[[我的链接名称]]”的内容,例如,SharePoint 始终会返回呈现的 HTML,例如:

<A class=ms-wikilink href="/MyWikiLibrary/MyLinkName.aspx">My Link Name</A>
Run Code Online (Sandbox Code Playgroud)

不过,通过一些正则表达式工作,您应该能够将其转换回原始 wiki 内容。

  • 解析 wiki 链接的正则表达式很简单;但反之则不然。如果您 UpdateListItems 并在 WikiField 中保留 [[brackets]] SharePoint 会将其转换为 \\[[brackets]\\] 这完全让我难以置信。我不知道如何避免这种情况;如果我手动转换链接,SharePoint 将从那时起将它们视为链接(而不是原始 wiki 标记)。双输。在 SP2010 中,此问题已修复并且一切正常。我正在尝试让它在 SP2007 中工作。 (2认同)
  • 找到了解决方案。您可以使用复制服务进行插入和更新,只需保持名称相同即可。然后它将标记作为原始 wiki 标记并按预期工作。惊人的! (2认同)