Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Server

Microsoft Content Management Server : Managing Template Galleries and Templates (part 2) - Creating Templates

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
3/19/2011 9:21:20 PM

Creating Templates

Another useful feature of the PAPI is its ability to generate templates through code. This is particularly useful when you need to generate many templates, consisting of placeholder and custom property definitions based on some predefined logic (for instance, a schema from a legacy application that is to be migrated to MCMS).

In this exercise, we will build a Create Template dialog for CMS Explorer:

1.
Add a new web form to the CMS Explorer project. Name the new form CreateTemplate.aspx.

2.
In Design view, drag and drop styles.css from Solution Explorer onto the web form.

3.
Toggle to HTML view and add a table consisting of six rows as shown below:

<table>
<tr>
<td colspan="2">
<h1>Create Template</h1>
<h2>
Parent Template Gallery:
(Add Literal for displaying the path here)
</h2>
</td>
</tr>
<tr>
<td>Name:</td>
<td>(Add text box for the Name here)</td>
</tr>
<tr>
<td>Description:</td>
<td>(Add text box for the Description here)</td>
</tr>
<tr>
<td>Source File:</td>
<td>(Add text box for the source file here)</td>
</tr>
<tr>
<td colspan="2">(Add the label for displaying error messages here)</td>
</tr>
<tr>
<td colspan="2" align="right">
(Add the Create Template button here)
<INPUT type="button" value="Close"
onclick="javascript:window.close();">
</td>
</tr>
</table>


4.
In Design view, add controls from the Web Forms section of the Toolbox and arrange them as described below:

ControlPropertyValue
LiteralIDlitParentGallery
TextBoxIDtxtName
TextBoxIDtxtDescription
 Rows3
 TextModeMultiLine
TextBoxIDtxtSourceFile
LabelIDlblErrorMessage
 Text(empty string)
ButtonIDbtnCreate
 TextCreate Template

5.
In the code-behind file, add the following namespaces:

. . . code continues . . .
// MCMS API
using Microsoft.ContentManagement.Publishing;
// Following is required for creating placeholder definitions
using Microsoft.ContentManagement.Publishing.Extensions.Placeholders;

namespace CmsExplorer
{
. . . code continues . . .
}


6.
In the Page_Load() event handler, add code that gets a reference to the current CmsHttpContext object as well as a reference to the parent template gallery in which to create the new template.

private TemplateGallery parentGallery;
private CmsHttpContext cmsContext;

private void Page_Load(object sender, System.EventArgs e)
{
cmsContext = CmsHttpContext.Current;
lblErrorMessage.Text = String.Empty;
string cmsObjectGuid = String.Empty;
if (Request.QueryString["CMSObjectGuid"] != null)
{
cmsObjectGuid = Request.QueryString["CMSObjectGuid"];
parentGallery = cmsContext.Searches.GetByGuid(cmsObjectGuid)
as TemplateGallery;
if (parentGallery != null)
{
litParentGallery.Text = parentGallery.Path;
}
else
{
lblErrorMessage.Text = "Parent Gallery not found!";
}
}
}


7.
Toggle to Design view and double-click on the btnCreate button. In the btnCreate_Click() event handler, add the code shown below:

private void btnCreate_Click(object sender, System.EventArgs e)
{
try
{
// create the new template
Template newTemplate;
if (parentGallery.CanCreateTemplates)
{
// get the template's name
string name = txtName.Text.Trim();
if (!Utility.ValidateMCMSObjectName(name))
{
throw new Exception("Specified template gallery name is not "
+ "valid. Must be only alphanumeric "
+ "characters, open or close parens, "
+ "hyphens, underscores, periods, or "
+ "spaces. No period at the end and no "
+ "consecutive periods are allowed. ");
}
newTemplate = parentGallery.CreateTemplate();
newTemplate.Name = name;
newTemplate.Description = txtDescription.Text;
newTemplate.SourceFile = txtSourceFile.Text;
// commit the changes
cmsContext.CommitAll();
// display the success message
lblErrorMessage.Text = "Template created successfully!";
}
else
{
lblErrorMessage.Text =
"You do not have rights to create a template.";
}
}
catch(Exception ex)
{
// rollback all changes
cmsContext.RollbackAll();
// the CMS context needs to be disposed of after a rollback
cmsContext.Dispose();
// display error message
lblErrorMessage.Text = ex.Message;
}
}


As before, the code performs the following validation checks before creating the template:

  • Checks to see if the user has the necessary rights to create templates in the current template gallery. We do this by retrieving the value of the TemplateGallery.CanCreateTemplates property.

  • Checks the name supplied in the txtName text box to see if it is a valid name. The same rules as for naming template galleries apply to templates.

The code basically uses the TemplateGallery.CreateTemplate() method to create the template. Once it has been created (and before we assign its Name, DescriptionSourceFile property values), the new template gets the following property values: and

  • The Custom Property and Placeholder Definition collections are both empty.

  • CreatedBy, LastModifiedBy, and OwnedBy reflect the user that carried out the create template operation.

  • CreatedDate and LastModifiedDate contain the date and time that the template was created.

  • The template’s state is New.

  • Its name is New Template.

  • SourceFile and Description are empty strings.

Once the template has been successfully created, we assign the new template the name, description, and source file values entered in the textboxes. Note that SourceFile is the PAPI equivalent of the Template File property seen in Template Explorer.

As before, in order for the changes to be made permanent, we commit them to the database. The CmsHttpContext.CommitAll() method is similar to the SaveNew to Saved. Should there be any errors, the message is displayed in the label and all changes are rolled back. function in Template Explorer. Once committed, the state of the template changes from

Submitting the Template

After the template has been created and committed to the repository, it will be in the Saved state. Until it is published, by checking it in with Template Explorer, other template designers are not able to modify it. The equivalent of checking in templates in the PAPI is the Template.Submit() method. Once submitted, the template’s state changes from Saved to Published. Authors and editors are then able to use it to create postings.

Modify the code in the btnCreate_Click() event handler to submit the new template as shown below:

private void btnCreate_Click(object sender, System.EventArgs e)
{
try
{
// create the new template
Template newTemplate;

if (parentGallery.CanCreateTemplates)
{
// get the template's name
string name = txtName.Text.Trim();

if (!Utility.ValidateMCMSObjectName(name))
{
throw new Exception("Specified template gallery name is not "
+ "valid. Must be only alphanumeric "
+ "characters, open or close parens, "
+ "hyphens, underscores, periods, or "
+ "spaces. No period at the end and no "
+ "consecutive periods are allowed. ");
}

newTemplate = parentGallery.CreateTemplate();
newTemplate.Name = name;
newTemplate.Description = txtDescription.Text;
newTemplate.SourceFile = txtSourceFile.Text;

// commit the changes
cmsContext.CommitAll();

// submit the template
if (newTemplate.CanSubmit)
{
newTemplate.Submit();
cmsContext.CommitAll();
// display the success message
lblErrorMessage.Text = "Template created successfully!";
}
else
{
lblErrorMessage.Text = "You do not have rights to submit"
+ " a template.";
}
    }
else
{
lblErrorMessage.Text = "You do not have rights to create a template.";
}

}
catch(Exception ex)
{
// rollback all changes
cmsContext.RollbackAll();

// the CMS context needs to be disposed of after a rollback
cmsContext.Dispose();

// display error message
lblErrorMessage.Text = ex.Message;
}
}


The code first checks the Template.CanSubmit property to see if the template can be submitted by the user. If so, it then calls the Template.Submit() method.

Creating Custom Property Definitions

Given a template object, you can add custom property definitions to its existing collection. In this example, we are going to take another shortcut. Instead of providing a user interface for entering the name, type, and default value of the custom property (like the one found in Template Explorer), we are going straight to coding. We will create a text custom property definition that has the following properties and values:

PropertyValue
NameLastSubmittedBy
DefaultValue(blank string)

In the btnCreate_Click() event handler, add the following code within the try block:

private void btnCreate_Click(object sender, System.EventArgs e)
{
try
{
// create the new template
Template newTemplate;

if (parentGallery.CanCreateTemplates)
{
. . . code continues . . .

newTemplate = parentGallery.CreateTemplate();
newTemplate.Name = txtName.Text;
newTemplate.Description = txtDescription.Text;
newTemplate.SourceFile = txtSourceFile.Text;

// create the custom property definition
CustomPropertyDefinition customProp;
customProp = newTemplate.CreateCustomPropertyDefinition();
customProp.Name = "LastSubmittedBy";
customProp.DefaultValue = String.Empty;

// commit the changes
cmsContext.CommitAll();

// submit the template
if (newTemplate.CanSubmit)
{
newTemplate.Submit();
cmsContext.CommitAll();

// display the success message
lblErrorMessage.Text = "Template created successfully!";
}
else
{
lblErrorMessage.Text = "You do not have rights to submit"
+ " a template.";
      }
}
else
{
lblErrorMessage.Text = "You do not have rights to create a template.";
}
}
catch(Exception ex)
{
// rollback all changes
cmsContext.RollbackAll();

// the CMS context needs to be disposed of after a rollback
cmsContext.Dispose();

// display error message
lblErrorMessage.Text = ex.Message;
}
}


The code uses the Template.CreateCustomPropertyDefinition() method to add a custom property definition to the template. Once the custom property has been created, we assign its property values.

When creating a template and adding custom property definitions to it with the PAPI, you must call CommitAll() somewhere between the TemplateGallery.CreateTemplate() and Template.Submit() calls. Otherwise, you will find that the template has an additional custom property definition named NewCustomPropertyDefinitionX (where X is an incremental number). This is a known bug with the PAPI.


In this example, we added a simple text custom property definition. For the more complex selection custom property definition, the technique is very similar. The code snippet below shows how to create a custom property definition named MenuLocation with four allowed values: Left, Right, Top, and Bottom. It specifies Top as the default value.

CustomPropertyDefinition customPropSelection;
customPropSelection = newTemplate.CreateCustomPropertyDefinition();
customPropSelection.Name = "MenuLocation";
customPropSelection.AddAllowedValue("Left");
customPropSelection.AddAllowedValue("Right");
customPropSelection.AddAllowedValue("Top");
customPropSelection.AddAllowedValue("Bottom");
customPropSelection.DefaultValue = "Top";

Creating Placeholder Definitions

Placeholder definitions can be created programmatically too, thanks to the PAPI’s Template.CreatePlaceholderDefinition() method. You can add any placeholder definition to a template. Before you do so, it is a good idea to import its namespace, which is why we imported Microsoft.ContentManagement.Publishing.Extensions.Placeholders earlier.

In this example, we add an HTMLPlaceholderDefinition to the newly created template. As before, we are going to take a shortcut here and have the placeholder definition automatically created with the following property values:

PropertyValue
NameBigBoxOfContent
DescriptionA placeholder created from the PAPI
AllowHyperlinksTrue
AllowLineBreaksTrue
AllowAttachmentsTrue
AllowImagesTrue
MustUseResourceGalleryFalse
UseGeneratedIconFalse
FormattingFullFormatting

The Template.CreatePlaceholderDefinition() method accepts a single input parameter. It could be one of two objects:

  • A placeholder definition type. You can create a new HtmlPlaceholderDefinition, XmlPlaceholderDefinition, ImagePlaceholderDefinition, AttachmentPlaceholderDefinition, or use one of your own creation.

  • An existing placeholder definition to create copies of. Using this method, the new placeholder definition will inherit the properties of the specified placeholder definition.

Add the highlighted code to the btnCreate_Click() event handler. The code creates an HtmlPlaceholderDefinition based on the property values defined in the table above.

private void btnCreate_Click(object sender, System.EventArgs e)
{
try
{
// create the new template
Template newTemplate;

if (parentGallery.CanCreateTemplates)
{
newTemplate = parentGallery.CreateTemplate();
newTemplate.Name = txtName.Text;
newTemplate.Description = txtDescription.Text;
newTemplate.SourceFile = txtSourceFile.Text;

// create the custom property definition
CustomPropertyDefinition customProp;
customProp = newTemplate.CreateCustomPropertyDefinition();
customProp.Name = "LastSubmittedBy";
customProp.DefaultValue = String.Empty;

// create the placeholder definitions
HtmlPlaceholderDefinition placeholderDef;
placeholderDef = newTemplate.CreatePlaceholderDefinition(
new HtmlPlaceholderDefinition()) as HtmlPlaceholderDefinition;
placeholderDef.Name = "BigBoxOfContent";
placeholderDef.Description = "A placeholder created from the PAPI";
placeholderDef.AllowHyperlinks = true;
placeholderDef.AllowLineBreaks = true;
placeholderDef.AllowAttachments = true;
placeholderDef.AllowImages = true;
placeholderDef.MustUseResourceGallery = false;
placeholderDef.UseGeneratedIcon = false;
placeholderDef.Formatting =
HtmlPlaceholderDefinition.SourceFormatting.FullFormatting;

// commit the changes
cmsContext.CommitAll();

. . . code continues . . .


The Create Template dialog is now complete. Save and build the solution. Let’s test it to see if it works:

1.
In CMS Explorer, click on the Templates button. Open the MyTemplateGallery template gallery created earlier.

2.
Select New | New Template.

3.
In the Create Template dialog, enter the following values:

PropertyValue
NameMyTemplate
DescriptionThis template was created using the PAPI
SourceFile/tropicalgreen/plantcatalog/plant.aspx

4.
Click Create Template and close the dialog.

5.
Refresh the CMS Explorer screen and verify that MyTemplate has been created in MyTemplateGallery.

Creating Connected Templates

Connected templates are created in the same way as templates, with the exception that we now call the TemplateGallery.CreateConnectedTemplate() method.

Let’s try it out:

1.
Add a new web form to the project with the name CreateConnectedTemplate.aspx.

2.
Drag and drop Styles.css onto the web form.

3.
Toggle to HTML view and enter the following code (including the text markers):

<table>
<tr>
<td colspan="2">
<h1>Create Connected Template</h1>
<h2>
Original Template:
(Add literal for displaying the path of the original template here)
<h2>
</td>
</tr>
<tr>
<td>Name:</td>
<td>(Add the text box for the Name here)</td>
</tr>
<tr>
<td>Description:</td>
<td>(Add the text box for the Description here)</td>
</tr>
<tr>
<td>Source File:</td>
<td>(Add text box for the source file here)</td>
</tr>
<tr>
<td colspan="2">(Add the Label for displaying error messages here)</td>
</tr>
<tr>
<td colspan="2" align="right">
(Add the Create Connected Template button here)
<INPUT type="button" value="Close"
onclick="javascript:window.close();">
</td>
</tr>
</table>


4.
Switch to Design view. Drag and drop the following controls from the Web Forms section of the Toolbox and delete the text markers.

ControlPropertyValue
LiteralIDlitOriginalTemplate
TextBoxIDtxtName
TextBoxIDtxtDescription
 Rows3
 TextModeMultiLine
TextBoxIDtxtSourceFile
LabelIDlblErrorMessage
 Text(empty string)
ButtonIDbtnCreate
 TextCreate Connected Template

The completed web form in Design view looks like this:

5.
Now let’s get an instance of the template (or the original template) on which to base the connected template. Before we do so, first consider how template designers and administrators create connected templates from CMS Explorer. They will:

  • Click the Templates button.

  • Navigate to the template gallery that contains the original template.

  • Click the Edit link next to the original template.

  • Select the Create Connected Template link.


Coded within the Create Connected Template link is the path to CreateConnectedTemplate.aspx and a querystring parameter named CMSObjectGuid, which contains the GUID of the original template. Here’s a sample of the generated URL, split on to several lines for readability:

http://localhost/cmsexplorer/CreateConnectedTemplate.aspx?
NRMODE=Update
&FRAMELESS=true
&CMSObjectGuid=%7b5010EF8C-C33C-4F68-8430-D8DFAABA2EE0%7d
&NRNODEGUID=%7bE4D19123-9DD3-11D1-B44E-006097071264%7d

In order to get an instance of the original template, we will extract the GUID from the CMSObjectGuid querystring parameter and pass it as the input parameter for the Searches.GetByGuid() method.

To show that we really have an instance of the original template, we will display the path of the original template on the screen. If, for some reason, we are not able to get an instance of the template, an error message will be displayed instead. We’ll add the code that does the job next.

1.
Double-click anywhere on the web form to get to its code-behind file. Add the Microsoft.ContentManagement.Publishing namespace.

. . . code continues . . .
// MCMS API
using Microsoft.ContentManagement.Publishing;

namespace CmsExplorer
{
. . . code continues . . .
}

2.
Above and within the Page_Load() event handler, add the highlighted code:

private CmsHttpContext cmsContext;
private Template originalTemplate;

private void Page_Load(object sender, System.EventArgs e)
{
cmsContext = CmsHttpContext.Current;
// Clear all error messages, if any.
lblErrorMessage.Text = String.Empty;
// Get an instance of the original template
string cmsObjectGuid = String.Empty;
if (Request.QueryString["CMSObjectGuid"] != null)
{
cmsObjectGuid = Request.QueryString["CMSObjectGuid"];
originalTemplate = cmsContext.Searches.GetByGuid(cmsObjectGuid)
as Template;
if (originalTemplate!=null)
{
// Display the template's path
litOriginalTemplate.Text = originalTemplate.Path;
}
else
{
// Uh-oh we can't get an instance of the template.
lblErrorMessage.Text = "Original Template not found!";
}
}
}


3.
Now that we have an instance of the original template, we are ready to create a connected template. A couple of checks are first done to ensure that the user has rights to create templates in the destination template gallery as well as that the name given to the new template is valid.

The TemplateGallery.CreateConnectedTemplate() method takes the original template as an input parameter and returns a reference to the new connected template. We set the name, description, and source file properties of the new connected template based on the values entered by the user in the textboxes provided. Double-click on the btnCreate button to get to the btnCreate_Click() event handler. Add the code as shown below:

private void btnCreate_Click(object sender, System.EventArgs e)
{
try
{
// Get an instance of the template gallery
TemplateGallery parentGallery = originalTemplate.Parent;
// Create the new connected template
Template newConnectedTemplate;
if (parentGallery.CanCreateTemplates)
{
// get the template's name
string name = txtName.Text.Trim();
if (!Utility.ValidateMCMSObjectName(name))
{
throw new Exception("Specified template gallery name is not "
+ "valid. Must be only alphanumeric "
+ "characters, open or close parens, "
+ "hyphens, underscores, periods, or "
+ "spaces. No period at the end and no "
+ "consecutive periods are allowed. ");
}
newConnectedTemplate =
parentGallery.CreateConnectedTemplate(originalTemplate);
//set the connected template's name
newConnectedTemplate.Name = txtName.Text;
//Set the connected template's description
newConnectedTemplate.Description = txtDescription.Text;
// Set the connected template's source file
newConnectedTemplate.SourceFile = txtSourceFile.Text;
// Commit the changes
cmsContext.CommitAll();
// Submit the connected template
if (newConnectedTemplate.CanSubmit)
{
newConnectedTemplate.Submit();
cmsContext.CommitAll();
// display the success message
lblErrorMessage.Text = "Connected Template created successfully!";
}
else
{
lblErrorMessage.Text = "You do not have rights to submit"
+ " a template.";
}
}
else
{
lblErrorMessage.Text =
"You do not have rights to create a template.";
}
}
catch(Exception ex)
{
// rollback all changes
cmsContext.RollbackAll();
// the CMS context needs to be disposed of after a rollback
cmsContext.Dispose();
// display error message
lblErrorMessage.Text = ex.Message;
}
}


Try out the code!

1.
On the CMS Explorer toolbar, click Templates.

2.
Select the MyTemplateGallery template gallery that we created earlier.

3.
Click the Edit link next for the MyTemplate template.

4.
Click Create Connected Template.

5.
Enter the following values in the Create Connected Template dialog:

PropertyValue
NameMyConnectedTemplate
DescriptionThis connected template was created using the PAPI
Source File/tropicalgreen/plantcatalog/columns.aspx

6.
After you have filled in all the fields, click Create Connected Template.

7.
Close the dialog and refresh CMS Explorer. Note that the new connected template has been created!

Until the connected template is published by calling the Template.Submit() method, all templates connected to it will be “checked-out” by the current user and thus not available to other template designers for editing. Authors, editors, and moderators can, however, use the template for creating postings after it has been committed even though it has not been submitted.

Other -----------------
- Integrating Exchange Server 2010 in a Non-Windows Environment : Administrative Improvements with Windows Server 2008
- Integrating Exchange Server 2010 in a Non-Windows Environment : Understanding the Identity Management for UNIX Components
- Using Services for UNIX to Integrate UNIX Systems with an Active Directory/Exchange Server 2010 Environment (part 3)
- Using Services for UNIX to Integrate UNIX Systems with an Active Directory/Exchange Server 2010 Environment (part 2) - Installing Services for Network File Server (NFS)
- Using Services for UNIX to Integrate UNIX Systems with an Active Directory/Exchange Server 2010 Environment (part 1)
- Managing Identity Information Between LDAP Directories and Exchange Server 2010
- Exchange Server 2010 : Synchronizing Directory Information with Forefront Identity Manager (FIM)
- Windows Server 2008 R2 : Using Operations Manager 2007 R2 (part 2) - Scheduling Reports
- Windows Server 2008 R2 : Using Operations Manager 2007 R2 (part 1) - Alert Tuning
- Windows Server 2008 R2 : Monitoring DMZ Servers with Certificates
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server