Add web part from Xml node by client object model

31/01/2014 13:23

Following XElement nodes are considered as xWebpart 

<Webpart Src="Webparts\CEWP.dwp" PageUrl ="/SitePages/MyPage.aspx" Zone="LeftColumn" PartOrder="4">
          <Replace What="tbTitleToken" With="My Webpart Title"></Replace>
        </Webpart>
        <Webpart Src="Webparts\ListViewWebPart.webpart" PageUrl ="/SitePages/MyPage.aspx" Zone="RightColumn" PartOrder="5">
          <Replace What="tbListUrlToken" With="mylinks"></Replace>
          <Replace What="tbListNameToken" With="My favorite links"></Replace>
        </Webpart>

First one is Content Editor web part and next XsltListViewWebPart. Src files are exported and some properties replaced with tokens.
Code finds these tokens and replaces them by attribute 'With'. We can use then e. g. ListViewWebPart.webpart file for several lists and don't need special file.

In case you don't need any replacement, just don't add them to xml.

Web part codes are at the end of this post.

 

  public static void ImportWebPartFromXElement(string webUrl, XElement xWebpart, string rootWebpartDirectory)
        {
            //Read attributes from XElement 'Webpart'
            string webpartFilePath = rootWebpartDirectory + "\\" + xWebpart.Attribute("Src").Value;
            string pageUrl = xWebpart.Attribute("PageUrl").Value;
            string zoneName = xWebpart.Attribute("Zone").Value;
            int order = Convert.ToInt32(xWebpart.Attribute("PartOrder").Value);

            //Read all strings to replace
            Dictionary<string, string> replacements = new Dictionary<string, string>();
            IEnumerable<XElement> xReplacements = xWebpart.Elements("Replace");
            if (xReplacements != null)
            {
                foreach (XElement xReplacement in xReplacements)
                {
                    replacements.Add(xReplacement.Attribute("What").Value, xReplacement.Attribute("With").Value);
                }
            }

            ImportWebPartWithReplacements(webUrl, pageUrl, webpartFilePath, zoneName, order, replacements);

        }

        public static void ImportWebPartWithReplacements(string webUrl, string pageUrl, string webpartFilePath, string zoneName, int order, Dictionary<string, string> replacements)
        {
            ClientContext context = new ClientContext(webUrl);

            Web web = context.Web;
            context.Load(web, w => w.ServerRelativeUrl);
            context.ExecuteQuery();
            string pageRelativeUrl = web.ServerRelativeUrl + pageUrl;

            Microsoft.SharePoint.Client.File page = context.Web.GetFileByServerRelativeUrl(pageRelativeUrl);
            LimitedWebPartManager manager = page.GetLimitedWebPartManager(PersonalizationScope.Shared);

            XmlTextReader xtr = new XmlTextReader(webpartFilePath);
            StringBuilder sb = new StringBuilder();

            while (xtr.Read())
            {
                var tmpObj = sb.AppendLine(xtr.ReadOuterXml());
            }
            string newXml = sb.ToString();

            //Replace all strings in file (key with value)
            foreach (var replacement in replacements)
            {
                newXml = Regex.Replace(newXml, replacement.Key, replacement.Value);
            }

            if (xtr != null)
            {
                xtr.Close();
            }

            WebPartDefinition webpart = manager.ImportWebPart(newXml);
            manager.AddWebPart(webpart.WebPart, zoneName, order);
            context.ExecuteQuery();
        }

Content Editor web part

<?xml version="1.0" encoding="utf-8"?>
<WebPart xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://schemas.microsoft.com/WebPart/v2">
  <Title>tbTitleToken</Title>
  <FrameType>Default</FrameType>
  <Description>Umožňuje autorom zadať text vo formáte RTF.</Description>
  <IsIncluded>true</IsIncluded>
  <ZoneID>wpz</ZoneID>
  <PartOrder>0</PartOrder>
  <FrameState>Normal</FrameState>
  <Height />
  <Width />
  <AllowRemove>true</AllowRemove>
  <AllowZoneChange>true</AllowZoneChange>
  <AllowMinimize>true</AllowMinimize>
  <AllowConnect>true</AllowConnect>
  <AllowEdit>true</AllowEdit>
  <AllowHide>true</AllowHide>
  <IsVisible>true</IsVisible>
  <DetailLink />
  <HelpLink />
  <HelpMode>Modeless</HelpMode>
  <Dir>Default</Dir>
  <PartImageSmall />
  <MissingAssembly>Táto webová časť sa nedá importovať.</MissingAssembly>
  <PartImageLarge>/_layouts/15/images/mscontl.gif</PartImageLarge>
  <IsIncludedFilter />
  <Assembly>Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
  <TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>
  <ContentLink xmlns="https://schemas.microsoft.com/WebPart/v2/ContentEditor" />
  <Content xmlns="https://schemas.microsoft.com/WebPart/v2/ContentEditor"><![CDATA[]]></Content>
  <PartStorage xmlns="https://schemas.microsoft.com/WebPart/v2/ContentEditor" />
</WebPart>


XsltListViewWebPart

<webParts>
  <webPart xmlns="https://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <importErrorMessage>Táto webová časť sa nedá importovať.</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="ShowWithSampleData" type="bool">False</property>
        <property name="Default" type="string" />
        <property name="NoDefaultStyle" type="string" null="true" />
        <property name="CacheXslStorage" type="bool">True</property>
        <property name="ViewContentTypeId" type="string">0x</property>
        <property name="XmlDefinitionLink" type="string" />
        <property name="ManualRefresh" type="bool">False</property>
        <property name="ListUrl" type="string" >tbListUrlToken</property>
        <property name="EnableOriginalValue" type="bool">False</property>
        <property name="Direction" type="direction">NotSet</property>
        <property name="ServerRender" type="bool">False</property>
        <property name="ViewFlags" type="Microsoft.SharePoint.SPViewFlags, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">Html, TabularView, Hidden, Mobile</property>
        <property name="AllowConnect" type="bool">True</property>
        <property name="ListName" type="string">tbListNameToken</property>
        <property name="AllowZoneChange" type="bool">True</property>
        <property name="ChromeState" type="chromestate">Normal</property>
        <property name="DisableSaveAsNewViewButton" type="bool">False</property>
        <property name="ViewFlag" type="string" />
        <property name="DataSourceID" type="string" />
        <property name="ExportMode" type="exportmode">All</property>
        <property name="AutoRefresh" type="bool">False</property>
        <property name="FireInitialRow" type="bool">True</property>
        <property name="AllowEdit" type="bool">True</property>
        <property name="Description" type="string" />
        <property name="HelpMode" type="helpmode">Modeless</property>
        <property name="BaseXsltHashKey" type="string" null="true" />
        <property name="AllowMinimize" type="bool">True</property>
        <property name="CacheXslTimeOut" type="int">86400</property>
        <property name="ChromeType" type="chrometype">TitleOnly</property>
        <property name="Xsl" type="string" null="true" />
        <property name="JSLink" type="string" null="true" />
        <property name="CatalogIconImageUrl" type="string">/_layouts/15/images/itann.png?rev=23</property>
        <property name="SampleData" type="string" null="true" />
        <property name="UseSQLDataSourcePaging" type="bool">True</property>
        <property name="TitleIconImageUrl" type="string" />
        <property name="PageSize" type="int">-1</property>
        <property name="ShowTimelineIfAvailable" type="bool">True</property>
        <property name="Width" type="string" />
        <property name="DataFields" type="string" />
        <property name="Hidden" type="bool">False</property>
        <property name="Title" type="string"></property>
        <property name="PageType" type="Microsoft.SharePoint.PAGETYPE, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">PAGE_NORMALVIEW</property>
        <property name="DataSourcesString" type="string" />
        <property name="AllowClose" type="bool">True</property>
        <property name="InplaceSearchEnabled" type="bool">False</property>
        <property name="WebId" type="System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">00000000-0000-0000-0000-000000000000</property>
        <property name="Height" type="string" />
        <property name="GhostedXslLink" type="string">main.xsl</property>
        <property name="DisableViewSelectorMenu" type="bool">False</property>
        <property name="DisplayName" type="string" />
        <property name="IsClientRender" type="bool">False</property>
        <!--<property name="XmlDefinition" type="string">&lt;View Name="{7F235CCC-A9AE-4C76-941B-3528E39A8FF6}" MobileView="TRUE" Type="HTML" Hidden="TRUE" DisplayName="" Url="/sites/sitecollection/SitePages/Home.aspx" Level="1" BaseViewID="1" ContentTypeID="0x" ImageUrl="/_layouts/15/images/announce.png?rev=23" &gt;&lt;Query&gt;&lt;OrderBy&gt;&lt;FieldRef Name="Modified" Ascending="FALSE"/&gt;&lt;/OrderBy&gt;&lt;Where&gt;&lt;And&gt;&lt;Leq&gt;&lt;FieldRef Name="StartDate"/&gt;&lt;Value Type="DateTime"&gt;&lt;Today/&gt;&lt;/Value&gt;&lt;/Leq&gt;&lt;Leq&gt;&lt;FieldRef Name="Expires"/&gt;&lt;Value Type="DateTime"&gt;&lt;Today/&gt;&lt;/Value&gt;&lt;/Leq&gt;&lt;/And&gt;&lt;/Where&gt;&lt;/Query&gt;&lt;ViewFields&gt;&lt;FieldRef Name="Body"/&gt;&lt;/ViewFields&gt;&lt;RowLimit&gt;1&lt;/RowLimit&gt;&lt;Aggregations Value="Off"/&gt;&lt;ViewStyle ID="15"/&gt;&lt;JSLink&gt;clienttemplates.js&lt;/JSLink&gt;&lt;XslLink Default="TRUE"&gt;main.xsl&lt;/XslLink&gt;&lt;Toolbar Type="None"/&gt;&lt;/View&gt;</property>-->
        <property name="XmlDefinition" type="string">&lt;View Name="{7F235CCC-A9AE-4C76-941B-3528E39A8FF6}" MobileView="TRUE" Type="HTML" Hidden="TRUE" DisplayName="" Url="tbPageRelativeUrl" Level="1" BaseViewID="1" ContentTypeID="0x" ImageUrl="/_layouts/15/images/announce.png?rev=23" &gt;&lt;Query&gt;&lt;OrderBy&gt;&lt;FieldRef Name="Modified" Ascending="FALSE"/&gt;&lt;/OrderBy&gt;&lt;Where&gt;&lt;And&gt;&lt;Leq&gt;&lt;FieldRef Name="StartDate"/&gt;&lt;Value Type="DateTime"&gt;&lt;Today/&gt;&lt;/Value&gt;&lt;/Leq&gt;&lt;Leq&gt;&lt;FieldRef Name="Expires"/&gt;&lt;Value Type="DateTime"&gt;&lt;Today/&gt;&lt;/Value&gt;&lt;/Leq&gt;&lt;/And&gt;&lt;/Where&gt;&lt;/Query&gt;&lt;ViewFields&gt;&lt;FieldRef Name="Body"/&gt;&lt;/ViewFields&gt;&lt;RowLimit&gt;1&lt;/RowLimit&gt;&lt;Aggregations Value="Off"/&gt;&lt;ViewStyle ID="15"/&gt;&lt;JSLink&gt;clienttemplates.js&lt;/JSLink&gt;&lt;XslLink Default="TRUE"&gt;main.xsl&lt;/XslLink&gt;&lt;Toolbar Type="None"/&gt;&lt;/View&gt;</property>
        <property name="InitialAsyncDataFetch" type="bool">False</property>
        <property name="AllowHide" type="bool">True</property>
        <property name="ParameterBindings" type="string">
          &lt;ParameterBinding Name="dvt_sortdir" Location="Postback;Connection" /&gt;
          &lt;ParameterBinding Name="dvt_sortfield" Location="Postback;Connection" /&gt;
          &lt;ParameterBinding Name="dvt_startposition" Location="Postback" DefaultValue="" /&gt;
          &lt;ParameterBinding Name="dvt_firstrow" Location="Postback;Connection" /&gt;
          &lt;ParameterBinding Name="OpenMenuKeyAccessible" Location="Resource(wss,OpenMenuKeyAccessible)" /&gt;
          &lt;ParameterBinding Name="open_menu" Location="Resource(wss,open_menu)" /&gt;
          &lt;ParameterBinding Name="select_deselect_all" Location="Resource(wss,select_deselect_all)" /&gt;
          &lt;ParameterBinding Name="idPresEnabled" Location="Resource(wss,idPresEnabled)" /&gt;
          &lt;ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" /&gt;
          &lt;ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" /&gt;
        </property>
        <property name="DataSourceMode" type="Microsoft.SharePoint.WebControls.SPDataSourceMode, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">List</property>
        <property name="AutoRefreshInterval" type="int">60</property>
        <property name="AsyncRefresh" type="bool">False</property>
        <property name="HelpUrl" type="string" />
        <property name="MissingAssembly" type="string">Táto webová časť sa nedá importovať.</property>
        <property name="XslLink" type="string" null="true" />
        <property name="SelectParameters" type="string" />
      </properties>
    </data>
  </webPart>
</webParts>