Creating and Deleting Placeholders and PlaceholderDefinitions

Predictably, all the methods in this section will require that the Context be in Update mode (see the Getting into Update PublishingMode sidebar in Chapter 25). We will be using the function introduced in Listing 25-1 to get an authenticated CmsApplicationContext in Update Publishing Mode. If we skip this step, we will receive a verbose .NET error page that basically says, You must be in Update mode to do this.

As always, after an object has been deleted, attempting to call any of its methods will cause an exception. Also, attempting to call any of these methods on a historical revision will cause an exception.

In general, the OwnedBy property (also discussed in Chapter 25) is implicitly changed to the current user so that other authors cannot concurrently update the Posting object or any of its ConnectedPostings. All changes only become permanent and ownership released (if appropriate) once the Context CommitAll method is called. Calling the Context RollbackAll method before CommitAll will return the Posting object to its previously committed condition.

The simple error handling in the code throughout these code samples isn't meant to be the model for how to handle CMS exceptions; there is an application code block from Microsoft on how to do exception handling in .NET. These functions also assume the presence of both a ListBox1 and a Label1 to provide visual feedback to the user, which certainly won't typically be normal, but it works for our purposes.

The first thing we will tackle in code is the creation of a new PlaceholderDefinition. Like the CmsApplicationContext covered in Chapter 24, PlaceholderDefinitions are created using a constructor.

NOTE: Protected members are outside the scope of this chapter and are covered in the context of creating a custom placeholder in Chapter 29.


PlaceholderDefinition Constructor, CreatePlaceholder

The PlaceholderDefinition constructor creates a new instance of a PlaceholderDefinition within a given template. The new PlaceholderDefinition will need to be of a specific PlaceholderDefinition constructor because the .NET Framework will not let us create an instance of an abstract class; so we will use the HtmlPlaceholderDefinition constructor in our example.

The steps that we would need to go through to create a PlaceholderDefinition in a template manually are similar to the steps that we need to follow programmatically:

  1. We would start out in VS.NET by selecting a specific TemplateDefinition to add our new PlaceholderDefinition into.

  2. In the Placeholder Definition Collection Editor, for the PlaceholderDefinitions property we would add a specific type of PlaceholderDefinition (in this sample, an HtmlPlaceholderDefinition).

  3. We would then replace the default Name given by VS.NET with the Name that we want to use and set any other properties for the PlaceholderDefinition (we take the defaults for the other properties).

  4. We click OK to dismiss the Editor and save our changes.

After we have a PlaceholderDefinition, we create an in-memory Placeholder object based upon that new definition. Once again, we will be using the function introduced in Listing 25-1 of Chapter 25 to get an authenticated CmsApplicationContext in Update PublishingMode.

Replace the Button1_Click function of our Scratchpad template file (see the Scratchpad sidebar in Chapter 24 for details) with the following code:

 private void Button1_Click(object sender, System.EventArgs e) {   try   {     //1. Check to be sure a new PlaceholderDefinition name was     //   entered. Note that there is no checking for name validity     if (TextBox1.Text.Length > 0)     {       //2. Grab the current Template       Template cmsCurrentTemplate =         CmsHttpContext.Current.Posting.Template;       //3. Check to see if the user has sufficient rights       if (cmsCurrentTemplate.CanSetProperties)       {         //4. Grab an Authenticated Context in Update PublishingMode         //   from Listing 25 1         CmsApplicationContext cmsContextApp =           GetAuthenticatedCmsApplicationContext(             PublishingMode.Update);         //5. Find the current Template in the Update Context in         //   which to create the PlaceholderDefinition         //   Cast the result of a Searches object as a Template         Template cmsUpdateTemplate =           cmsContextApp.Searches.GetByGuid(cmsCurrentTemplate.Guid)           as Template;         //6. Create HtmlPlaceholderDefinition object using         //   a constructor         HtmlPlaceholderDefinition cmsDefinition =           new HtmlPlaceholderDefinition();         //7. Replace the default name with the value in         //   the TextBox         cmsDefinition.Name = TextBox1.Text.ToString();         //8. Create the PlaceholderDefinition in the         //   Update Template         HtmlPlaceholderDefinition cmsCreatedDefinition =           cmsUpdateTemplate.CreatePlaceholderDefinition(             cmsDefinition)           as HtmlPlaceholderDefinition;         //9. Check if the PlaceholderDefinition create         //   was successful         if (cmsCreatedDefinition != null)         {           //10. Create Placeholder using new PlaceholderDefinition           HtmlPlaceholder cmsCreatedPlaceholder =             cmsCreatedDefinition.CreatePlaceholder()             as HtmlPlaceholder;           //11. Check if the Placeholder Object create           //    was successful           if (cmsCreatedPlaceholder != null)           {             //12. Populate the label with Template Name             Label1.Text = "<b>Update Template Name: </b>" +               HttpUtility.HtmlEncode(                 cmsUpdateTemplate.Name.ToString());             //13. Add to label the New PlaceholderDefinition Name             Label1.Text +=               "<br><b>New PlaceholderDefinition Name: " +               "</b>" + HttpUtility.HtmlEncode(                 cmsCreatedDefinition.Name.ToString());             //14. Add to the label the New Placeholder Object Name             //    Because this is only an in-memory Placeholder it             //    does not have a Datasource, a Name, etc.             Label1.Text +=               "<br><b>New Placeholder Object Type: </b>" +               cmsCreatedDefinition.GetType().ToString();           }           else           {             //15. Provide nonerror feedback to the developer             Label1.Text = "HtmlPlaceholder create failed";           }         }         else         {           //16. Provide nonerror feedback to the developer           Label1.Text = "PlaceholderDefinition create failed";         }         //17. Commit all changes         cmsContextApp.CommitAll();         //18. Dispose of the stand-alone Application Context         cmsContextApp.Dispose();       }       else       {         //19. Provide nonerror feedback to the developer         Label1.Text = "User does not have CanSetProperties rights";       }     }     else     {       //20. Provide nonerror feedback to the developer       Label1.Text = "TextBox must be a PlaceholderDefinition name";     }   }   catch(Exception eError)   {     //21. Provide error feedback to the developer     Label1.Text = "<b>Error: </b>" + eError.Message.ToString();   } } 

At the top of the code window is a list of namespaces in use. If there isn't a line that looks like the following, you will need to add it:

 using Microsoft.ContentManagement.Publishing.Extensions.Placeholders; 

Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, type the name for a new PlaceholderDefinition (we used TestPlaceholderDefinition), and click the Button. The page should reload and look similar to Figure 27-2.

Figure 27-2. Create PlaceholderDefinition and Placeholder object

graphics/27fig02.gif

When we close the browser or the posting goes out of scope, the in-memory Placeholder object will be expunged, but the PlaceholderDefinition is a permanent part of our template definition.

Open the PlaceholderDefinitions collection property for the ScratchTemplate in VS.NET, and we can see the PlaceholderDefinition that was created in our code at the bottom of the list in the Editor (Figure 27-3). It may be necessary to right-click the templates TemplateGallery and select Refresh before VS.NET will requery the database to see the change.

Figure 27-3. PlaceholderDefinition in VS.NET

graphics/27fig03.jpg

If in line 7 we hadn't altered the Name of the created PlaceholderDefinition or if the name that we gave had already existed, CMS would have given the default name of NewPlaceholderDefinitionX, where X is a sequential number incremented by one until a unique name is found.

We also could have provided an alternate Datasource when we created our in-memory Placeholder object, and then we could have put in content and later retrieved that content. However, there is an example of how to do this in Chapter 29.

Clone

The Clone method is an alternative way of creating a new PlaceholderDefinition in the same or a different template. It works exactly the same as the previous example, except that line 6:

 //6. Create HtmlPlaceholderDefinition with a Constructor HtmlPlaceholderDefinition cmsDefinition =   new HtmlPlaceholderDefinition(); 

would be changed to get a clone of an existing definition (we'll clone the PlaceholderDefinition that we created in the last example):

 //6. Create HtmlPlaceholderDefinition as a read-only Clone //   of the TestPlaceholderDefinition previously created HtmlPlaceholderDefinition cmsDefinition =   cmsCurrentTemplate.PlaceholderDefinitions     ["TestPlaceholderDefinition"].Clone()   as HtmlPlaceholderDefinition; 

We can optionally pass in a Boolean parameter that if true would make the created PlaceholderDefinition read-only. The default value of this parameter is false. Of course, then we couldn't modify any of the PlaceholderDefinition's properties.

Delete

The Delete method is used to remove unwanted PlaceholderDefinitions. However, there are some rules. The PlaceholderDefinition must be retrieved via the PlaceholderDefinitions collection of the template rather than the Definition property of a specific placeholder. The user must have sufficient rights in this case, CanSetProperties rights and as always the Context must be in Update mode. Deleting a PlaceholderDefinition may change the state of the template.

Let's remove the TestPlaceholderDefinition that we created in the earlier example.

Once again, we will be using the function introduced in Listing 25-1 of Chapter 25 to get an authenticated CmsApplicationContext in Update PublishingMode.

Replace the Button1_Click function of our Scratchpad template file with the following code:

 private void Button1_Click(object sender, System.EventArgs e) {   try   {     //1. Grab the current Template     Template cmsCurrentTemplate =       CmsHttpContext.Current.Posting.Template;     //2. Check to see if the user has sufficient rights     if (cmsCurrentTemplate.CanSetProperties)     {       //3. Grab an Authenticated Context in Update PublishingMode       //   from Listing 25 1       CmsApplicationContext cmsContextApp =         GetAuthenticatedCmsApplicationContext(           PublishingMode.Update);       //4. Find the current Template in the Update Context       //   Cast the result of the Searches object as a Template       Template cmsUpdateTemplate =         cmsContextApp.Searches.GetByGuid(cmsCurrentTemplate.Guid)         as Template;       //5. Populate the ListBox with the Names of all the       //   PlaceholderDefinitions in the collection       foreach(PlaceholderDefinition cmsDefinition in         cmsUpdateTemplate.PlaceholderDefinitions)       {         ListBox1.Items.Add("Before: " +           cmsDefinition.Name.ToString());       }       //6. Grab the PlaceholderDefinition to delete, must be       //   referenced thru the PlaceholderDefinitions collection       PlaceholderDefinition cmsDoomedDefinition =         cmsUpdateTemplate.PlaceholderDefinitions           [TextBox1.Text.ToString()]         as PlaceholderDefinition;       //7. Check to see if we found the PlaceholderDefinition       if (cmsDoomedDefinition != null)       {         //8. Populate the label with PlaceholderDefinition Name         Label1.Text = "<b>PlaceholderDefinition To Delete: </b>" +           HttpUtility.HtmlEncode(             cmsDoomedDefinition.Name.ToString());         //9. Delete the PlaceholderDefinition         cmsDoomedDefinition.Delete();         //9. Commit all changes         cmsContextApp.CommitAll();         //10. Populate the ListBox with the Names of all the         //    PlaceholderDefinitions that remain         foreach(PlaceholderDefinition cmsDefinition in           cmsUpdateTemplate.PlaceholderDefinitions)         {           ListBox1.Items.Add("After: " +             cmsDefinition.Name.ToString());         }         //11. Dispose of the stand-alone Application Context         cmsContextApp.Dispose();       }       else       {         //12. Provide nonerror feedback to the developer         Label1.Text = "Didn't find the PlaceholderDefinition";       }     }     else     {       //13. Provide nonerror feedback to the developer       Label1.Text = "User does not have CanSetProperties rights";     }   }   catch(Exception eError)   {     //14. Provide error feedback to the developer     Label1.Text = "<b>Error: </b>" + eError.Message.ToString();   } } 

Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, type the name for a PlaceholderDefinition to delete (we used TestPlaceholderDefinition), and click the Button. The page should reload and look similar to Figure 27-4.

Figure 27-4. Delete PlaceholderDefinition

graphics/27fig04.gif

We increased the height of the ListBox on the template for this example so that Figure 27-4 would show all five entries. You may need to scroll down to see the last one.

Serialize, DeserializeObject

The Serialize method removes all the state (property values) from the specified PlaceholderDefinition into either an XML string or an Xml Writer. In the example that follows, we place that XML string into the label so we can see it.

The DeserializeObject method does just the opposite. It takes a previously serialized PlaceholderDefinition as represented by an XmlNode and hydrates a PlaceholderDefinition object from that XML.

Replace the Button1_Click function of our Scratchpad template file with the following code:

 private void Button1_Click(object sender, System.EventArgs e) {   try   {     //1. Grab the current Template     Template cmsTemplate =       CmsHttpContext.Current.Posting.Template;     //2. Grab the HtmlPlaceholderDefinition to serialize     HtmlPlaceholderDefinition cmsDefinition =       cmsTemplate.PlaceholderDefinitions[TextBox1.Text.ToString()]       as HtmlPlaceholderDefinition;     //3. Check to see if we found the PlaceholderDefinition     if (cmsDefinition != null)     {       //4. Show the name of the original PlaceholderDefinition       ListBox1.Items.Add("Original: " +         cmsDefinition.Name.ToString());       //5. Serialize the PlaceholderDefinition XML into the label       Label1.Text = HttpUtility.HtmlEncode(         cmsDefinition.Serialize());       //6. Declare and initialize an XmlDocument object       System.Xml.XmlDocument xmlDocument =         new System.Xml.XmlDocument();       //7. Populate the xmlDocument with PlaceholderDefinition XML       xmlDocument.InnerXml = cmsDefinition.Serialize();       //8. Declare and initialize an XmlNode object with the XML       System.Xml.XmlNode xmlDefinition =         xmlDocument.DocumentElement;       //9. Use the XmlNode to hydrate a new PlaceholderDefinitnion       HtmlPlaceholderDefinition cmsDeserializedDefinition =         HtmlPlaceholderDefinition.DeserializeObject(xmlDefinition)         as HtmlPlaceholderDefinition;       //10. Show the name of the hydrated PlaceholderDefinition       ListBox1.Items.Add("Deserialized: " +         cmsDeserializedDefinition.Name.ToString());     }     else     {       //11. Provide nonerror feedback to the developer       Label1.Text = "Didn't find the PlaceholderDefinition";     }   }   catch(Exception eError)   {     //12. Provide error feedback to the developer     Label1.Text = "<b>Error: </b>" + eError.Message.ToString();   } } 

Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, type the name for a PlaceholderDefinition to serialize (we used NewHtmlPlaceholderDefinition1), and click the Button. The page should reload and look similar to Figure 27-5.

Figure 27-5. Serialize and Deserialize PlaceholderDefinition

graphics/27fig05.jpg

PropertyChanged

The PropertyChanged event for a PlaceholderDefinition is fired whenever changes are made to the PlaceholderDefinition through a public property setter.



Microsoft Content Management Server 2002. A Complete Guide
Microsoft Content Management Server 2002: A Complete Guide
ISBN: 0321194446
EAN: 2147483647
Year: 2003
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net