ENTERPRISE

Microsoft Content Management Server Development : An Image Rotator Placeholder Control (part 2) - Rotating Images Randomly

6/10/2013 2:53:02 AM

Loading Previously Saved Values

The control retrieves the previously saved resource gallery path and displays it in the textbox. As what we have saved to the content repository is XML, we will use the helper function GetResourceGalleryPath() (defined later) to extract it.

protected override void LoadPlaceholderContentForAuthoring(
                                          PlaceholderControlEventArgs e)
{
  EnsureChildControls();

  string xml = ((XmlPlaceholder)this.BoundPlaceholder).XmlAsString;
  m_resourceGalleryPath = GetResourceGalleryPath(xml);

  txtResourceGalleryPath.Text = m_resourceGalleryPath;
}

The GetResourceGalleryPath() helper function accepts the entire XML string that has been saved in the underling XmlPlaceholder as an input parameter. It loads it into an XmlDocument object and retrieves the path of the resource gallery from the <Path> child element.

private string GetResourceGalleryPath(string xml)
{
  string rgPath = "";
  try
  {
    XmlDocument xd = new XmlDocument();
    xd.LoadXml(xml);
    rgPath = xd.DocumentElement.SelectSingleNode("Path").InnerText;
  }
  catch
  {}
  return rgPath;
}

Rotating Images Randomly

In presentation view, a file is randomly picked from the resource gallery. As the resource gallery accepts files of all types, we won’t know if the selected file is an image, a Flash file, an Office document or a PDF. Therefore the control that we load in the presentation container has to be generic, like the ASP.NET PlaceHolder control from the System.Web.UI.WebControls namespace (don’t confuse this with the MCMS placeholder controls!). We will use the CreatePresentationChildControls() method to add the PlaceHolder control to the presentation container.

PlaceHolder ph;
protected override void CreatePresentationChildControls(
                                     BaseModeContainer presentationContainer)
{
  ph = new PlaceHolder();
  presentationContainer.Controls.Add(ph);
}

					  

When loading content, the placeholder control first ensures that all child controls, in this case the single PlaceHolder control we added earlier, have been created at run time before proceeding. Once it has done so, it retrieves the path of the resource gallery from the underlying XmlPlaceholder. To extract the information from the XML, we will use the GetResourceGalleryPath() method defined earlier.

protected override void LoadPlaceholderContentForPresentation(
                                              PlaceholderControlEventArgs e)
{
  EnsureChildControls();

  // Get the current CmsHttpContext
  CmsHttpContext cmsContext = CmsHttpContext.Current;

  // Get an instance of the selected resource gallery
  string xml = ((XmlPlaceholder)this.BoundPlaceholder).XmlAsString;
  m_resourceGalleryPath = GetResourceGalleryPath(xml);

  ResourceGallery rg = cmsContext.Searches.GetByPath(m_resourceGalleryPath)
                       as ResourceGallery;
}

					  

Once we have an instance of the resource gallery, a random number is generated. Again, we will write a helper function, RandomNumberGenerator(), to pick a number from zero to one less than the number of resources in the gallery:

private int RandomNumberGenerator(int max)
{
  // generate a random number
  int seed;
  int index = 0;
  seed = (int)System.DateTime.Now.Ticks % System.Int32.MaxValue;
  System.Random rand = new System.Random(seed);
  index = rand.Next(0,max);

  return index;
}

Next, we get the resource that corresponds to the randomly chosen index. Modify the LoadPlaceholderContentForPresentation() method as shown below:

protected override void LoadPlaceholderContentForPresentation(
                                        PlaceholderControlEventArgs e)
{
  . . . code continues . . .
  if (rg != null)
						{
						// Randomly select a resource from the gallery
						int indexOfResource = RandomNumberGenerator(rg.Resources.Count);
						Resource r = rg.Resources[indexOfResource];
  }
}

To determine the file’s type, we check its MIME type (Multipurpose Internet Mail Extensions type). MIME types are used by the browser to determine how content should be displayed. For example, a file with the MIME type applications/x-shockwave-flash will be played within a Flash player instead of being displayed as an image or text. The exact value returned by the Resource.MimeType property depends on the server’s registry.

Why don’t we check the file extension instead? Don’t all images have a file extension like GIF, JPEG, or even BMP?

We could check the file extension. However, doing so would mean having a collection of all possible file extensions. For example, to decide whether the file is actually an image, we would have to check if the file extension is *.bmp, *.gif, *.jpg, *.jpeg—the list goes on. While it’s a workable way of getting the job done, it is by no means exhaustive. What if someone uploads a *.png file? Our list will have to be updated with the latest file extension.


Checking the MIME type is a more efficient way of detecting the file type. Regardless of its extension, all images will have the word “image” as the main content type. The sub-type (for example, gif, jpeg, or png for images) follows after a forward slash.

Main Content TypeSub TypeMime Type
ImageGIFimage/gif
ImageJPEGimage/jpeg
ImagePNGimage/png
Applicationsx-shockwave-flashapplications/x-shockwave-flash

Once we have determined if the resource is an image, a Flash file, or something else altogether, we decide how to display it. For images, the answer is pretty straightforward; we create an Image control and set its ImageUrl property to point to the image.

protected override void LoadPlaceholderContentForPresentation(
                                      PlaceholderControlEventArgs e)
{
  . . . code continues . . .

  if (rg != null)
  {
    // Randomly select a resource from the gallery
    int indexOfResource = RandomNumberGenerator(rg.Resources.Count);
    Resource r = rg.Resources[indexOfResource];

    if (r.MimeType.StartsWith("image"))
						{
						// If it is an image, display it
						Image img = new Image();
						img.ImageUrl = r.Url;
						ph.Controls.Add(img);
						}
  }
}

Flash files are played using a Flash plug-in. Visitors should already have the plug-in installed, otherwise the browser will prompt them to install it from download.macromedia.com. In Internet Explorer, the Flash plug-in is really an ActiveX control, which we can invoke using the HTML <object> tag as shown overleaf. The <EMBED></EMBED> element is included overleaf to support non-Microsoft browsers that don’t use ActiveX technology. Because it is surrounded by the <OBJECT></OBJECT> tag, it will be ignored by Internet Explorer.

The highlighted code below indicate places where we have to replace MyMovie.swf with the actual URL of the resource:

<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#
version=7,0,0,0" id="MyMovie">
<PARAM NAME=movie VALUE="MyMovie.swf">
<PARAM NAME=quality VALUE=high>
<PARAM NAME=bgcolor VALUE=#FFFFFF>
<EMBED src="MyMovie.swf" quality=high bgcolor=#FFFFFF
      NAME="MyMovie" TYPE=\"application/x-shockwave-flash"
      PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer">
</EMBED></OBJECT>

					  

A Literal control is used to display the entire HTML string. Add the highlighted portion as shown to the LoadPlaceholderContentForPresentation() method:

protected override void LoadPlaceholderContentForPresentation(
                                              PlaceholderControlEventArgs e)
{
  . . . code continues . . .

  if (r.MimeType.StartsWith("image"))
  {
     // If it is an image, display it
     Image img = new Image();
     img.ImageUrl = r.Url;
     ph.Controls.Add(img);
  }
  else if (r.MimeType.EndsWith("x-shockwave-flash"))
						{
						// If it is a shockwave flash file, display it
						Literal swf = new Literal();
						string html = "<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-"
						+ "444553540000\" "
						+ "codebase=\"http://download.macromedia.com/pub"
						+ "/shockwave/cabs/flash/swflash.cab#version=7,0,0,0\""
						+ "id=\"" + r.Name + "\">"
						+ "<PARAM NAME=movie VALUE=\"" + r.Url + "\">"
						+ "<PARAM NAME=quality VALUE=high>"
						+ "<PARAM NAME=bgcolor VALUE=#FFFFFF>"
						+ "<EMBED src=\"" + r.Url + "\" quality=high "
						+ "bgcolor=#FFFFFF NAME=\"" + r.Name + "\" "
						+ "TYPE=\"application/x-shockwave-flash\" "
						+ "PLUGINSPAGE=\"http://www.macromedia.com/go/"
						+ "getflashplayer\"></EMBED></OBJECT>";
						swf.Text = html;
						ph.Controls.Add(swf);
						}
}

					  

For all other file types, we will simply display their thumbnails within an Image control. You could choose not to display them at all and get the random-file generator to pick only images and Flash files. Or perhaps you may have some other creative way of tackling such files. For example, you could read the contents of a text file to make a quote-of-the-day control. If you do, just add the logic to deal with them here.

protected override void LoadPlaceholderContentForPresentation(
                                               PlaceholderControlEventArgs e)
{
  . . . code continues . . .

  if (r.MimeType.StartsWith("image"))
  {
      . . . code continues . . .
  }
  else if (r.MimeType.EndsWith("x-shockwave-flash"))
  {
      . . . code continues . . .
  }
  else
						{
						// For all other types, show the thumbnail
						Image img = new Image();
						img.ImageUrl = r.UrlThumbnail;
						ph.Controls.Add(img);
						}

					  

The control is complete. Save and build the solution.

The selected resource gallery contains many file types. But I only wish to display images in the control. Is there a quick way to filter the unwanted files without deleting them from the gallery?

You could use the ResourceCollection.FilterByMimeType() or ResourceCollection.FilterByExtension() methods of the PAPI to retrieve resources of specific MIME types or extensions. For example, the following code selects only images from the gallery.

// Get an instance of the resource gallery
ResourceGallery rg = cmsContext.Searches.GetByPath(m_resourceGalleryPath)
                     as ResourceGallery;
// Select only images from the resource
ResourceCollection rc = rg.FilterByMimeType("image", true);


Using the Image Rotator Placeholder Control

To use the image rotator placeholder control, add it to a template file and bind it to an XmlPlaceholderDefinition. Within a posting, supply the control with the path of a resource gallery that contains some resources. Load the posting in presentation view and watch the images rotate on each load.

With a few modifications, the control can be enhanced to accommodate advertisements:

  • Store the URL of the site that the visitor will be redirected to in the resource’s description field.

  • Wrap the images, Flash movies, and icons of attachments within an anchor tag. Set the href attribute to point to the target website.

Other  
 
Top 10
Free Mobile And Desktop Apps For Accessing Restricted Websites
MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
TOYOTA CAMRY 2; 2.5 : Camry now more comely
KIA SORENTO 2.2CRDi : Fuel-sipping slugger
How To Setup, Password Protect & Encrypt Wireless Internet Connection
Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
Backup & Restore Game Progress From Any Game With SaveGameProgress
Generate A Facebook Timeline Cover Using A Free App
New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
Popular Tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone