Overview
The EPiServer administration tools are pretty good, but every now and then I find that I want a bit more functionality. In this case, I wanted to duplicate new properties across multiple page types, create new properties based on a template and also change existing properties to have unique values for each language. This would have been tedious by hand, but the EPiServer API has everything I needed.
Basic preparation
You don't need to do anything special to access the EPiServer APIs. The easiest option is to create new, standard ASP.NET pages in the admin folder, so that an administrative login is required. Of course, a plug-in could be created instead.
APIs
Everything necessary to manipulate Page Types are in the following classes:
- EPiServer.DataAbstraction.PageType (an individual Page Type)
- EPiServer.DataAbstraction.PageTypeCollection (a collection of PageTypes)
- EPiServer.DataAbstraction.PageDefinition (an individual property of a Page Type)
- EPiServer.DataAbstraction.PageDefinitionCollection (a collection of PageDefinitions)
The following are important static methods:
- PageType.List() retrieves all defined PageTypes as a PageTypeCollection
- PageType.Load(int) retrieves a PageType given its ID
- PageType.Load(string) retrieves a PageType given its name
- PageDefinition.Load(int) retrieves a PageDefinition given its ID
The following instance members are also important:
- PageType.Definitions retrieves a PageType's PageDefinitionCollection
- PageType.Save() saves changes to a PageType
- PageDefinition.Save() saves changes to a PageDefinition
Examples
Three examples follow in C#. These are as follows:
- DuplicatePageTypeProperties.aspx allows for copying properties between PageTypes
- LocalizePageTypeProperties.aspx allows for bulk changing of the "Unique Value Per Language" property setting
- RepeatingPageTypeProperties.aspx provides a quick method for creating new properties based on an existing one
DuplicatePageTypeProperties.aspx
DuplicatePageTypeProperties.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DuplicatePageTypeProperties.aspx.cs" Inherits="EPiServerSample.cms.admin.DuplicatePageTypeProperties" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<style type="text/css">
label { font-weight: bold; color: navy; }
select { margin-top: 0.5em; margin-bottom: 1em;}
</style>
</head>
<body>
<h1>EPiServer: Copy Page Type Properties to Another Page Type</h1>
<form id="form1" runat="server">
<div style="width:40%; float:left;">
<asp:Label runat="server" AssociatedControlID="lbSourcePageType">Source Page Type:</asp:Label><br />
<asp:ListBox Width="100%" Height="200" ID="lbSourcePageType" AutoPostBack="true" runat="server" /><br />
<asp:Label ID="Label1" runat="server" AssociatedControlID="lbSourceProperties">Source Properties:</asp:Label><br />
<asp:ListBox Width="100%" Height="200" ID="lbSourceProperties" SelectionMode="Multiple" runat="server" />
</div>
<div style="width:40%; float:left;">
<asp:Label ID="Label2" runat="server" AssociatedControlID="lbTargetPageType">Target Page Type:</asp:Label><br />
<asp:ListBox Width="100%" Height="200" ID="lbTargetPageType" runat="server" AutoPostBack="true" /><br />
<asp:Label ID="Label3" runat="server" AssociatedControlID="lbTargetProperties">Target Properties:</asp:Label><br />
<asp:ListBox Width="100%" Height="200" ID="lbTargetProperties" runat="server" />
</div>
<div style="clear:both; width:auto; margin-left:auto; margin-right:auto;">
<asp:Button ID="btnCopyProperties" runat="server" OnClick="btnCopyProperties_Click" Text="Copy Properties -->" />
</div>
</form>
</body>
</html>
DuplicatePageTypeProperties.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace EPiServerSample.cms.admin
{
public partial class DuplicatePageTypeProperties : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
EPiServer.DataAbstraction.PageTypeCollection p =
EPiServer.DataAbstraction.PageType.List();
lbSourcePageType.DataSource = p;
lbSourcePageType.DataValueField = "ID";
lbSourcePageType.DataTextField = "Name";
lbSourcePageType.DataBind();
lbTargetPageType.DataSource = p;
lbTargetPageType.DataValueField = "ID";
lbTargetPageType.DataTextField = "Name";
lbTargetPageType.DataBind();
}
lbSourcePageType.SelectedIndexChanged +=
new EventHandler(this.lbPageType_SelectedIndexChanged);
lbTargetPageType.SelectedIndexChanged +=
new EventHandler(this.lbPageType_SelectedIndexChanged);
btnCopyProperties.Enabled =
(lbSourcePageType.SelectedIndex != -1) &&
(lbTargetPageType.SelectedIndex != -1);
}
protected void lbPageType_SelectedIndexChanged(object sender, EventArgs e)
{
ListBox lb = (ListBox)sender;
ListBox lbp = null;
if (object.ReferenceEquals(lb, this.lbSourcePageType)) lbp = lbSourceProperties;
if (object.ReferenceEquals(lb, this.lbTargetPageType)) lbp = lbTargetProperties;
lbp.Items.Clear();
if (!String.IsNullOrEmpty(lb.SelectedValue))
{
EPiServer.DataAbstraction.PageType pt = EPiServer.DataAbstraction.PageType.Load(int.Parse(lb.SelectedValue));
lbp.DataSource = pt.Definitions;
lbp.DataTextField = "Name";
lbp.DataValueField = "ID";
lbp.DataBind();
}
}
protected void btnCopyProperties_Click(object sender, EventArgs e)
{
int[] selectedIndices = lbSourceProperties.GetSelectedIndices();
if (selectedIndices.Length == 0) return;
EPiServer.DataAbstraction.PageType source =
EPiServer.DataAbstraction.PageType.Load(int.Parse(lbSourcePageType.SelectedValue));
EPiServer.DataAbstraction.PageType target =
EPiServer.DataAbstraction.PageType.Load(int.Parse(lbTargetPageType.SelectedValue));
foreach (int selectedIndex in selectedIndices) {
EPiServer.DataAbstraction.PageDefinition sdef =
EPiServer.DataAbstraction.PageDefinition.Load(int.Parse(
lbSourceProperties.Items[selectedIndex].Value));
EPiServer.DataAbstraction.PageDefinition tdef = new EPiServer.DataAbstraction.PageDefinition();
tdef.PageTypeID = target.ID;
tdef.DefaultValueType = sdef.DefaultValueType;
tdef.DefaultValue = sdef.DefaultValue;
tdef.EditCaption = sdef.EditCaption;
tdef.FieldOrder = target.Definitions.Count;
tdef.HelpText = sdef.HelpText;
tdef.LanguageSpecific = sdef.LanguageSpecific;
tdef.LongStringSettings = sdef.LongStringSettings;
tdef.Name = sdef.Name;
tdef.Required = sdef.Required;
tdef.Searchable = sdef.Searchable;
tdef.Tab = sdef.Tab;
tdef.Type = sdef.Type;
tdef.PageTypeID = target.ID;
tdef.Save();
target.Definitions.Add(tdef);
target.Save();
}
EPiServer.DataAbstraction.PageType.ClearCache();
lbPageType_SelectedIndexChanged(lbTargetPageType, new EventArgs());
}
}
}
LocalizePageTypeProperties.aspx
LocalizePageTypeProperties.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="LocalizePageTypeProperties.aspx.cs" Inherits="EPiServerSample.cms.admin.LocalizePageTypeProperties" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<style type="text/css">
label { font-weight: bold; color: navy; }
select { margin-top: 0.5em; margin-bottom: 1em;}
label.property { float:left; width: 150px; }
input.property { width: 200px; }
</style>
</head>
<body>
<h1>EPiServer: Create Repeating Page Type Properties</h1>
<form id="form1" runat="server">
<div style="width:40%; float:left; margin-right:2em;">
<asp:Label runat="server" AssociatedControlID="lbSourcePageType">Page Type:</asp:Label><br />
<asp:DropDownList Width="100%" ID="lbSourcePageType" AutoPostBack="true" runat="server" /><br />
<asp:Label ID="Label1" runat="server" AssociatedControlID="lbSourceProperties">Template Property:</asp:Label><br />
<asp:ListBox Width="100%" Height="200" ID="lbSourceProperties" SelectionMode="Multiple" AutoPostBack="false" runat="server" />
</div>
<div style="width:40%; float:left;">
<asp:Label AssociatedControlID="btnMakeGlobal" runat="server">Globalization</asp:Label><br /><br /><br />
<asp:Button ID="btnMakeGlobal" Text="Make Properties Language Neutral" runat="server"
OnClick="btnMakeGlobal_Click" /><br /><br />
<asp:Button ID="btnMakeLocal" Text="Make Properties Language Specific" runat="server"
OnClick="btnMakeLocal_Click" />
</div>
</form>
</body>
</html>
LocalizePageTypeProperties.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace EPiServerSample.cms.admin
{
public partial class LocalizePageTypeProperties : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
EPiServer.DataAbstraction.PageTypeCollection p =
EPiServer.DataAbstraction.PageType.List();
lbSourcePageType.DataSource = p;
lbSourcePageType.DataValueField = "ID";
lbSourcePageType.DataTextField = "Name";
lbSourcePageType.DataBind();
}
lbSourcePageType.SelectedIndexChanged +=
new EventHandler(this.lbPageType_SelectedIndexChanged);
}
protected void lbPageType_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList lb = (DropDownList)sender;
ListBox lbp = null;
if (object.ReferenceEquals(lb, this.lbSourcePageType)) lbp = lbSourceProperties;
lbp.Items.Clear();
if (!String.IsNullOrEmpty(lb.SelectedValue))
{
EPiServer.DataAbstraction.PageType pt = EPiServer.DataAbstraction.PageType.Load(int.Parse(lb.SelectedValue));
lbp.DataSource = pt.Definitions;
lbp.DataTextField = "Name";
lbp.DataValueField = "ID";
lbp.DataBind();
}
}
protected void btnMakeGlobal_Click(object source, EventArgs e)
{
SetProperties(true);
}
protected void btnMakeLocal_Click(object source, EventArgs e)
{
SetProperties(false);
}
protected void SetProperties(bool global)
{
if (lbSourceProperties.SelectedIndex == -1) return;
int[] indices = lbSourceProperties.GetSelectedIndices();
foreach (int i in indices)
{
int propId = int.Parse(lbSourceProperties.Items[i].Value);
EPiServer.DataAbstraction.PageDefinition d =
EPiServer.DataAbstraction.PageDefinition.Load(propId);
d.LanguageSpecific = !global;
d.Save();
}
}
}
}
RepeatingPageTypeProperties.aspx
RepeatingPageTypeProperties.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="RepeatingPageTypeProperties.aspx.cs" Inherits="EPiServerSample.cms.admin.RepeatingPageTypeProperties" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<style type="text/css">
label { font-weight: bold; color: navy; }
select { margin-top: 0.5em; margin-bottom: 1em;}
label.property { float:left; width: 150px; }
input.property { width: 200px; }
</style>
</head>
<body>
<h1>EPiServer: Create Repeating Page Type Properties</h1>
<form id="form1" runat="server">
<div style="width:40%; float:left; margin-right:2em;">
<asp:Label runat="server" AssociatedControlID="lbSourcePageType">Page Type:</asp:Label><br />
<asp:DropDownList Width="100%" ID="lbSourcePageType" AutoPostBack="true" runat="server" /><br />
<asp:Label ID="Label1" runat="server" AssociatedControlID="lbSourceProperties">Template Property:</asp:Label><br />
<asp:ListBox Width="100%" Height="200" ID="lbSourceProperties" SelectionMode="Single" AutoPostBack="true" runat="server" OnSelectedIndexChanged="lbProperties_SelectedIndexChanged" />
</div>
<div style="width:40%; float:left;">
<asp:Label AssociatedControlID="tbName" runat="server">New Property</asp:Label><br /><br /><br />
<asp:Label CssClass="property" ID="Label2" AssociatedControlID="tbName" runat="server">Name:</asp:Label>
<asp:TextBox CssClass="property" runat="server" ID="tbName" /><br /><br />
<asp:Label CssClass="property" ID="Label3" AssociatedControlID="tbEditHeading" runat="server">Edit Heading:</asp:Label>
<asp:TextBox CssClass="property" runat="server" ID="tbEditHeading" /><br /><br />
<asp:Label CssClass="property" ID="Label4" AssociatedControlID="tbHelpText" runat="server">Help Text:</asp:Label>
<asp:TextBox CssClass="property" runat="server" ID="tbHelpText" /><br /><br />
<asp:Button ID="btnRepeatProperties" runat="server" OnClick="btnRepeatProperties_Click" Text="Create New Property -->" />
</div>
</form>
</body>
</html>
RepeatingPageTypeProperties.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace EPiServerSample.cms.admin
{
public partial class RepeatingPageTypeProperties : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
EPiServer.DataAbstraction.PageTypeCollection p =
EPiServer.DataAbstraction.PageType.List();
lbSourcePageType.DataSource = p;
lbSourcePageType.DataValueField = "ID";
lbSourcePageType.DataTextField = "Name";
lbSourcePageType.DataBind();
}
lbSourcePageType.SelectedIndexChanged +=
new EventHandler(this.lbPageType_SelectedIndexChanged);
btnRepeatProperties.Enabled =
(lbSourcePageType.SelectedIndex != -1) &&
(lbSourceProperties.SelectedIndex != -1);
}
protected void lbPageType_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList lb = (DropDownList)sender;
ListBox lbp = null;
if (object.ReferenceEquals(lb, this.lbSourcePageType)) lbp = lbSourceProperties;
lbp.Items.Clear();
if (!String.IsNullOrEmpty(lb.SelectedValue))
{
EPiServer.DataAbstraction.PageType pt = EPiServer.DataAbstraction.PageType.Load(int.Parse(lb.SelectedValue));
lbp.DataSource = pt.Definitions;
lbp.DataTextField = "Name";
lbp.DataValueField = "ID";
lbp.DataBind();
}
}
protected void lbProperties_SelectedIndexChanged(object source, EventArgs e)
{
tbName.Text = string.Empty;
tbHelpText.Text = string.Empty;
tbName.Text = string.Empty;
if (lbSourceProperties.SelectedIndex == -1) return;
EPiServer.DataAbstraction.PageDefinition p =
EPiServer.DataAbstraction.PageDefinition.Load(int.Parse(lbSourceProperties.SelectedValue.ToString()));
tbName.Text = p.Name;
tbHelpText.Text = p.HelpText;
tbEditHeading.Text = p.EditCaption;
}
protected void btnRepeatProperties_Click(object sender, EventArgs e)
{
if (lbSourcePageType.SelectedIndex == -1) return;
if (lbSourceProperties.SelectedIndex == -1) return;
int PageTypeID = int.Parse(lbSourcePageType.SelectedValue.ToString());
int sdefID = int.Parse(lbSourceProperties.SelectedValue.ToString());
EPiServer.DataAbstraction.PageType p = EPiServer.DataAbstraction.PageType.Load(PageTypeID);
EPiServer.DataAbstraction.PageDefinition sdef =
EPiServer.DataAbstraction.PageDefinition.Load(sdefID);
EPiServer.DataAbstraction.PageDefinition tdef =
new EPiServer.DataAbstraction.PageDefinition();
tdef.PageTypeID = p.ID;
tdef.DefaultValueType = sdef.DefaultValueType;
tdef.DefaultValue = sdef.DefaultValue;
tdef.EditCaption = tbEditHeading.Text;
tdef.FieldOrder = p.Definitions.Count;
tdef.HelpText = tbHelpText.Text;
tdef.LanguageSpecific = sdef.LanguageSpecific;
tdef.LongStringSettings = sdef.LongStringSettings;
tdef.Name = tbName.Text;
tdef.Required = sdef.Required;
tdef.Searchable = sdef.Searchable;
tdef.Tab = sdef.Tab;
tdef.Type = sdef.Type;
tdef.PageTypeID = p.ID;
tdef.Save();
p.Definitions.Add(tdef);
p.Save();
}
}
}
Versions
Metadata