2009-01-07 76 views
7

我想以编程方式编辑我的Sharepoint Wiki内容。其中一个好处是可以自动向Wiki环境添加索引。以编程方式编辑Sharepoint Wiki内容

有没有人能够做到这一点?语言无所谓,但寻找脚本解决方案。

回答

3

SharePoint维基只是一种特殊类型的文档库。试图这样做时,我遇到了一些古怪的事情。

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

此外,当您以编程方式访问列表项目时,SharePoint会自动呈现wiki内容。所以,我从来没有能够得到包含“[我的链接名称],”例如内容 - SharePoint功能将始终返回呈现的HTML代替,如:

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

一点点的正则表达式的工作,你应该能够将其转换回原始的wiki内容。

+0

有没有人想过如何在没有Sharepoint设计器的情况下获取模板? – 2009-09-21 13:42:22

7

是的。我已经推出以编程方式管理在2010年的SharePoint维基页面和2007年

我的消息来源我自己的MetaWeblog API:

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

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

我在第一个链接中使用复制服务来创建和更新wiki页面。在2010年,你可以使用列表服务来更新,但不添加。 我使用映像服务将图像自动上传到图片库。

这里是取代“MS-wikilinks”功能,以维基标记:

注:我用HTMLAgilityPack的情况下,返回的标记的格式不正确。你也可以使用Regex来做到这一点。我还使用Microsoft Anti-XSS 4.1库来清理标记。

注2:我的UrlDecode函数不依赖于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; 
} 

剥离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; 
    } 
} 

最后,这增加了该标记全部恢复功能:

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

这个伟大的工程。

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

我想发表我的API,它不是一个很大的我认为对于那些想更好地管理我们的Sharepoint维基的人来说,这个代码非常有用。借助WLW,我可以获得自动图片上传,更好的HTML编辑支持,并支持像PreCode Snippet这样的插件。这很棒!