2009-01-07 80 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這樣的插件。這很棒!