Here's the final function I ended up using to add the web part:
function addWebPart(webUrl, pageUrl,webPartXml,zoneId,zoneIndex, Success,Error){
var context = new SP.ClientContext(webUrl);
var web = context.get_web();
var file = web.getFileByServerRelativeUrl(webUrl + pageUrl);
var webPartMngr = file.getLimitedWebPartManager(SP.WebParts.PersonalizationScope.shared);
var webPartDef = webPartMngr.importWebPart(webPartXml);
var webPart = webPartDef.get_webPart();
webPartMngr.addWebPart(webPart, zoneId, zoneIndex);
context.load(webPart);
context.executeQueryAsync(
function() {
Success(webPart);
},
Error
);
}
I also ended up creating two other functions to actually build the XML used in the web parts:
function buildTimeLine(list,web){
listID=list.get_id();
fullUrl=web.get_url();
relUrl=web.get_serverRelativeUrl();
partTitle=web.get_title()+ ' '+ list.get_title();
partXml='<webParts>'+
'<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">'+
'<metaData>'+
'<type name="Microsoft.SharePoint.WebPartPages.SPTimelineWebPart, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />'+
'<importErrorMessage>Cannot import this Web Part.</importErrorMessage>'+
'</metaData>'+
' <data>'+
'<properties>'+
'<property name="HelpUrl" type="string" />'+
'<property name="ChromeType" type="chrometype">Default</property>'+
'<property name="TitleUrl" type="string" />'+
'<property name="Width" type="string" />'+
'<property name="Hidden" type="bool">False</property>'+
'<property name="SourceSelection" type="string">'+
listID +
'</property>'+
'<property name="AllowClose" type="bool">True</property>'+
'<property name="ExportMode" type="exportmode">All</property>'+
'<property name="AllowMinimize" type="bool">True</property>'+
'<property name="TypeSelection" type="string">TaskListTimeline</property>'+
'<property name="Direction" type="direction">NotSet</property>'+
'<property name="AllowConnect" type="bool">True</property>'+
'<property name="MissingAssembly" type="string">Cannot import this Web Part.</property>'+
'<property name="CurrentTaskListWebAddress" type="string">'+
fullUrl +
'</property>'+
'<property name="PageAddress" type="string">'+
relUrl+
'</property>'+
'<property name="Description" type="string"></property>'+
'<property name="TitleIconImageUrl" type="string" />'+
'<property name="CatalogIconImageUrl" type="string" />'+
'<property name="ListId" type="string">'+
listID+
'</property>'+
'<property name="AllowZoneChange" type="bool">True</property>'+
'<property name="Height" type="string" />'+
'<property name="ViewName" type="string">Timeline</property>'+
'<property name="HelpMode" type="helpmode">Modeless</property>'+
'<property name="Title" type="string">'+
partTitle +
'</property>'+
'<property name="ChromeState" type="chromestate">Normal</property>'+
'<property name="AllowHide" type="bool">True</property>'+
'<property name="TimelineType" type="string">TaskListTimeline</property>'+
'<property name="AllowEdit" type="bool">True</property>'+
'</properties>'+
'</data>'+
'</webPart>'+
'</webParts>';
return partXml;
};
function buildHeader(web,zone,index){
projTitle=web.get_title();
projDesc=web.get_description();
projUrl=web.get_serverRelativeUrl();
partXml='<?xml version="1.0" encoding="utf-8"?>'+
'<WebPart xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/WebPart/v2">'+
'<Title>Content Editor'+
projTitle +
'</Title>'+
' <FrameType>None</FrameType>'+
'<Description>Allows authors to enter rich text content.</Description>'+
'<IsIncluded>true</IsIncluded>' +
'<ZoneID>' +
zone +
'</ZoneID>' +
'<PartOrder>'+
index+
'</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>Cannot import this Web Part.</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="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />'+
'<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"><![CDATA[<h1><a href="' +
projUrl +
'">' +
projTitle +
'</a></h1><p>' +
projDesc+
'</p><hr/>]]></Content>'+
'<PartStorage xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />'+
'</WebPart>';
return partXml;
};
These two functions are used within callback functions called from more generic functions that pull in the targeted lists/webs:
function getWebList(subsiteUrl,listName,success,fail){
ctx=new SP.ClientContext(subsiteUrl);
web=ctx.get_web();
list=web.get_lists().getByTitle(listName);
ctx.load(web);
ctx.load(list);
ctx.executeQueryAsync(Function.createDelegate(this,success),Function.createDelegate(this,fail));
}
function getWeb(subsiteUrl,success,fail){
ctx=new SP.ClientContext(subsiteUrl);
web=ctx.get_web();
ctx.load(web);
ctx.executeQueryAsync(Function.createDelegate(this,success),Function.createDelegate(this,fail));
};
Examples of usage follows:
getWeb("sites/topLevelSite/subsite",
function(sender,args){
headerXml=buildHeader(web,"FullPage",0);
},
function(sender, args){
alert(args.get_message();)
})
getWebList("sites/topLevelSite/subsite", "Tasks List",
function(sender,args){
timelineXml=buildTimeline(web,list);
},
function(sender, args){
alert(args.get_message();)
})
Now that the XML has been built, the original addWebPart function can be executed.