As previously mentioned, searching for a collection of assets can be further categorized by the type of asset retrieved: Channel objects, Posting objects, Template objects, or Gallery objects. These Searches methods are different from our previous searches in several ways. These methods return a collection of assets rather than just a single asset. If no assets are found, the method returns an empty collection rather than a null reference. There isn't a Boolean operator, so multiple, separate searches must be performed, and the results can be combined using the Union method. In certain publishing modes, assets with IsHiddenModePublished equal to true will automatically be removed from the collection. Returning a Collection of ChannelsThe following sections cover how the GetChannelsByCustomProperty, NewChannels, and ImportantChannels methods can be used to return a collection of Channel objects. GetChannelsByCustomPropertyThis method can be called with just the name of the CustomProperty to find or the name and the value (up to 300 characters) of the CustomProperty to find. But we don't currently have a CustomProperty on our Scratch channel to search for. Creating CustomProperties and entering their values is done very differently for channels than it is for postings. What follows are brief instructions to help you create a couple of custom properties to search for. If you have a channel that already has custom properties, feel free to use it in the code sample instead.
NOTE: We illustrate creating and manipulating custom properties for a channel in Chapter 25. First, create CustomProperties for the Scratch channel by following these steps:
Next, enter values for each CustomProperty on the Scratch channel by following these steps:
Now we can search for channels with a CustomProperty with a given Name. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Check to be sure a value was entered. // Note that there is no checking for value validity if (TextBox1.Text.Length>0) { //2. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //3. Find all the channels that have a CustomProperty // with a property name equal to the string provided ChannelCollection cmsChannelsFound = cmsContext.Searches.GetChannelsByCustomProperty( TextBox1.Text.ToString()) as ChannelCollection; //4. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //5. List the name of every channel returned by the search foreach(Channel cmsChannel in cmsChannelsFound) { ListBox1.Items.Add(cmsChannel.Name.ToString()); } //6. If the collection is empty, show No Channels Found if (cmsChannelsFound.Count==0) { ListBox1.Items.Add("No Channels Found"); } } else { //7. Provide nonerror feedback to the developer Label1.Text = "TextBox must contain a value"; } } Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, enter the name of one of the custom properties that we created (like customPropertyOne) into the text box, and click the Button. The page should reload and look similar to Figure 28-2. Figure 28-2. Find collection of channelsIf we type a custom property name that doesn't exist, the Scratchpad posting should reload, adding the literal "No Channels Found" to the ListBox. If we change the third line of code to the following, we can also search for the value of a CustomProperty: //3. Find all the channels that have a CustomProperty // with a CustomProperty name equal to customPropertyOne and // a value equal to the string provided in the TextBox ChannelCollection cmsChannelsFound = cmsContext.Searches.GetChannelsByCustomProperty( "customPropertyOne", TextBox1.Text.ToString()) as ChannelCollection; Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, enter the value of the first custom property that we created (we gave it a value of "One") into the text box, and click the Button. The page should reload and look similar to Figure 28-2. NewChannelsThis Searches method retrieves a collection of CMS channels based upon when they were last modified. If the Channel object's ChangeDate property is within the last seven days (or a user-specified number of days), it will be retrieved. Since we just added two CustomProperties (in the GetChannelsByCustomProperty section) to the Scratch channel, the change date should be within the time period to be classified as a "New" channel. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all Channels with their ChangeDate <= three // days from the current date ChannelCollection cmsChannelsFound = cmsContext.Searches.NewChannels(3) as ChannelCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every channel returned by the search foreach(Channel cmsChannel in cmsChannelsFound) { ListBox1.Items.Add(cmsChannel.Name.ToString()); } //5. If the collection is empty, show No Channels Found if (cmsChannelsFound.Count==0) { ListBox1.Items.Add("No Channels Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer, or browse to it and click the Button. The page should reload and look similar to Figure 28-2. ImportantChannelsThis Searches method retrieves a collection of CMS Channel objects whose Important Channel property is checked. This property can be checked at design time in the Options area on the Publishing tab of the Channel Properties dialog in Site Manager. Or it can be checked at runtime in the Publishing Options area on the Standard tab of the Channel Properties dialog launched from the CMS default console. Check the box to the left of Important Channel in order for the channel to be considered Important and subsequently returned by this search. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all Channels marked as Important ChannelCollection cmsChannelsFound = cmsContext.Searches.ImportantChannels() as ChannelCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every channel returned by the search foreach(Channel cmsChannel in cmsChannelsFound) { ListBox1.Items.Add(cmsChannel.Name.ToString()); } //5. If the collection is empty, show No Channels Found if (cmsChannelsFound.Count==0) { ListBox1.Items.Add("No Channels Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer, or browse to it and click the Button. The page should reload and look similar to Figure 28-2. Uncheck the box to the left of Important Channel and rerun the search. The Scratch channel should no longer show in the ListBox. Returning a Collection of PostingsThe following sections cover how the GetPostingsByCustomProperty, NewPostings, ImportantPostings, UserApprovalsPending, and UserPostingsInProduction methods can be used to return a collection of Posting objects. GetPostingsByCustomPropertyWe don't currently have a CustomProperty on our Scratchpad posting to search for. Creating custom properties and entering their values is done very differently for postings than it is for channels. Although custom properties are exposed to PAPI, they must be created in CMS Site Manager for channels and VS.NET for templates (upon which postings are based). PAPI can only update the current value of an existing CustomProperty property. So, to see this Searches method in action, we need to do a little prework. What follows are brief instructions to help you create a couple of custom properties to search for. If you have a posting that already has custom properties, feel free to use it in the code sample instead.
NOTE: We illustrate creating and manipulating custom properties for a posting in Chapter 26. First, create custom properties for the Scratchpad template definition by following these steps:
Next, enter values for each custom property on the Scratchpad posting by following these steps:
Now we can search for postings with specific CustomProperty characteristics. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Check to be sure a value was entered. // Note that there is no checking for value validity if (TextBox1.Text.Length>0) { //2. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //3. Find all Postings that have a CustomProperty // with a property name equal to the string provided PostingCollection cmsPostingsFound = cmsContext.Searches.GetPostingsByCustomProperty( TextBox1.Text.ToString()) as PostingCollection; //4. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //5. List the name of every Posting returned by the search foreach(Posting cmsPosting in cmsPostingsFound) { ListBox1.Items.Add(cmsPosting.Name.ToString()); } //6. If the collection is empty, show No Postings Found if (cmsPostingsFound.Count==0) { ListBox1.Items.Add("No Postings Found"); } } else { //7. Provide nonerror feedback to the developer Label1.Text = "TextBox must contain a value"; } } Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, enter the default name of one of the custom properties that we created (like NewTextProperty1) into the text box, and click the Button. The page should reload and look similar to Figure 28-3. Figure 28-3. Find collection of postingsIf we change the third line of code to the following, we can also search for the value of a custom property: //3. Find all the postings that have a CustomProperty // with a property name equal to NewTextProperty1 and a // CustomProperty value equal to the string provided PostingCollection cmsPostingsFound = cmsContext.Searches.GetPostingsByCustomProperty( "NewTextProperty1", TextBox1.Text.ToString()) as PostingCollection; Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, enter the value of the first custom property that we created (we gave it a value of "First") into the text box, and click the Button. Again, the page should reload and look similar to Figure 28-3. NewPostingsThis Searches method retrieves a collection of CMS postings based upon when they were last modified. If the Posting object's ChangeDate property is within the last seven days (or a user-specified number of days), it will be retrieved. Since we just added two CustomProperties (in GetPostingsByCustomProperty section) to the Scratchpad posting, the change date should be within the time period to be classified as a "New" posting. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all Postings with their ChangeDate <= three // days from the current date PostingCollection cmsPostingsFound = cmsContext.Searches.NewPostings(3) as PostingCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every Posting returned by the search foreach(Posting cmsPosting in cmsPostingsFound) { ListBox1.Items.Add(cmsPosting.Name.ToString()); } //5. If the collection is empty, show No Postings Found if (cmsPostingsFound.Count==0) { ListBox1.Items.Add("No Postings Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer, or browse to it and click the Button. The page should reload and look similar to Figure 28-3. ImportantPostingsThis Searches method retrieves a collection of CMS postings whose Important Posting property is checked. This property can only be checked at runtime in the Publishing Options area on the Standard tab of the Posting Properties dialog launched from the CMS default console. Check the box to the left of Important Posting in order for the posting to be considered Important and subsequently be returned by this search. Changes to this property do not change the state of the posting. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all Postings marked as Important PostingCollection cmsPostingsFound = cmsContext.Searches.ImportantPostings() as PostingCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every Posting returned by the search foreach(Posting cmsPosting in cmsPostingsFound) { ListBox1.Items.Add(cmsPosting.Name.ToString()); } //5. If the collection is empty, show No Postings Found if (cmsPostingsFound.Count==0) { ListBox1.Items.Add("No Postings Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer, or browse to it and click the Button. Again, the page should reload and look similar to Figure 28-3. Uncheck the box to the left of Important Posting and rerun the search. The Scratchpad posting should no longer show in the ListBox. UserApprovalsPendingTo obtain a collection of the postings that are shown when the Approval Assistant link is clicked in the CMS default console, we would use the Searches UserApprovalsPending method. For our Scratchpad posting to show up, we need to alter something that would require approval. One easy thing to change is the current value of the NewTextProperty1 CustomProperty on the Custom tab of the Page Properties dialog launched from the CMS default console. Save the changes and notice that the Approve link is now showing in the CMS default console. Don't click it yet. Depending on how your permissions are set, you may need to click the Submit link. If the posting state doesn't go all the way to Published, the following code sample will produce the correct result. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all Postings with UserApprovalsPending PostingCollection cmsPostingsFound = cmsContext.Searches.UserApprovalsPending() as PostingCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every Posting returned by the search foreach(Posting cmsPosting in cmsPostingsFound) { ListBox1.Items.Add(cmsPosting.Name.ToString()); } //5. If the collection is empty, show No Postings Found if (cmsPostingsFound.Count==0) { ListBox1.Items.Add("No Postings Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, click the Switch to Edit Site link in the CMS default console to put the context into the correct mode, and click the Button. Again, the page should reload and look similar to Figure 28-3. Leave the Unpublished posting unapproved until the UserPostingsInProduction section is complete. UserPostingsInProductionTo obtain a collection of the postings that are shown when the Production Manager link is clicked in the CMS default console, we would use the Searches UserPostingsInProduction method. Our modified Scratchpad posting should show up because we haven't yet approved the changes. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all Postings with UserPostingsInProduction PostingCollection cmsPostingsFound = cmsContext.Searches.UserPostingsInProduction() as PostingCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every Posting returned by the search foreach(Posting cmsPosting in cmsPostingsFound) { ListBox1.Items.Add(cmsPosting.Name.ToString()); } //5. If the collection is empty, show No Postings Found if (cmsPostingsFound.Count==0) { ListBox1.Items.Add("No Postings Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, click the Switch to Edit Site link in the CMS default console to put the context into the correct mode, and click the Button. Again, the page should reload and look similar to Figure 28-3. Click the Approve link in the CMS default console to publish the CustomProperty changes. Browse to the Scratchpad posting again, click the button labeled Button, and the Scratchpad posting should reload, adding the literal "No Postings Found" to the ListBox. Returning a Collection of TemplatesThe GetTemplatesBySourceFile method is the only means to return a collection of Template objects. The next section covers this in detail. GetTemplatesBySourceFileThis Searches method retrieves a collection of CMS template definitions based upon the value of their TemplateFile property. When we initially created the template definition in VS.NET, we set the TemplateFile property (Figure 28-4). Figure 28-4. The TemplateFile propertyReplace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Check to be sure a value was entered. // Note that there is no checking for value validity if (TextBox1.Text.Length>0) { //2. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //3. Find all Templates with a specific TemplateFile using // GetTemplatesBySourceFile TemplateCollection cmsTemplatesFound = cmsContext.Searches.GetTemplatesBySourceFile( TextBox1.Text.ToString()) as TemplateCollection; //4. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //5. List the name of every Template returned by the search foreach(Template cmsTemplate in cmsTemplatesFound) { ListBox1.Items.Add(cmsTemplate.Name.ToString()); } //6. If the collection is empty, show No Templates Found if (cmsTemplatesFound.Count==0) { ListBox1.Items.Add("No Templates Found"); } } else { //7. Provide nonerror feedback to the developer Label1.Text = "TextBox must contain a value"; } } Build the solution and then refresh the Scratchpad posting in Internet Explorer; or browse to it, enter the name of the TemplateFile to search for into the text box, and click the Button. The page should reload and look similar to Figure 28-5. Figure 28-5. Find collection of templatesReturning a Collection of GalleriesThe following sections cover how the UserResourceGalleries and User TemplateGalleries methods can be used to return a collection of objects. UserResourceGalleriesTo obtain a collection of ResourceGalleries and the Resource objects they contain, we use the Searches UserResourceGalleries method. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all ResourceGalleries available to the user ResourceGalleryCollection cmsGalleriesFound = cmsContext.Searches.UserResourceGalleries() as ResourceGalleryCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every ResourceGallery returned foreach(ResourceGallery cmsGallery in cmsGalleriesFound) { ListBox1.Items.Add(cmsGallery.Name.ToString()); //5. List the name of every Resource in each Gallery found // Prefix the name with dashes foreach(Resource cmsResource in cmsGallery.Resources) { ListBox1.Items.Add("----" + cmsResource.Name.ToString()); } } //6. If the collection is empty, show No ResourceGallery Found if(cmsGalleriesFound.Count==0) { ListBox1.Items.Add("No ResourceGallery Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer, or browse to it and click the Button. The page should reload and look similar to Figure 28-6. Figure 28-6. Find collection of resource galleriesWe increased the height of the ListBox on the template file for this example so that Figure 28-6 would show ten entries. You may need to scroll down to see all the entries. Most of these are coming from the Woodgrove and BOTS Consulting sites. Remember, this is one of the CMS sitewide searches. UserTemplateGalleriesSimilarly, to obtain a collection of TemplateGalleries and the Template objects they contain, we use the Searches UserTemplateGalleries method. Replace the Button1_Click function of our Scratchpad template file with the following code: private void Button1_Click(object sender, System.EventArgs e) { //1. Grab the current CMS Context CmsHttpContext cmsContext = CmsHttpContext.Current; //2. Find all TemplateGalleries available to the user TemplateGalleryCollection cmsGalleriesFound = cmsContext.Searches.UserTemplateGalleries() as TemplateGalleryCollection; //3. Empty the ListBox of all previous entries ListBox1.Items.Clear(); //4. List the name of every TemplateGallery returned foreach(TemplateGallery cmsGallery in cmsGalleriesFound) { ListBox1.Items.Add(cmsGallery.Name.ToString()); //5. List the name of every Template in each Gallery found // Prefix the name with dashes foreach(Template cmsTemplate in cmsGallery.Templates) { ListBox1.Items.Add("----" + cmsTemplate.Name.ToString()); } } //6. If the collection is empty, show No TemplateGallery Found if(cmsGalleriesFound.Count==0) { ListBox1.Items.Add("No TemplateGallery Found"); } } Build the solution and then refresh the Scratchpad posting in Internet Explorer, or browse to it and click the Button. The page should reload and look similar to Figure 28-7. Figure 28-7. Find collection of template galleriesWe increased the height of the ListBox on the template file for this example so that Figure 28-7 would show ten entries. You may need to scroll down to see all the entries. Most of these are coming from the Woodgrove and BOTS Consulting sites. Remember, this is one of the CMS sitewide searches. |