Solution Development for SharePoint 2007 Part 7

June 7, 2008

Part 1 - Part 2 - Part 3 - Part 4 - Part 5 - Part 6 - Part 7 - Part 8

"Event Receivers and Page Creation"

In the last week or so I've been doing a lot of work with creating pages with content on it automatically based on event receivers firing when items are created on Lists. To follow on with the TV show Schedule scenario when a new schedule is created, I want to create a page in the Pages Library on the Site itself and add a Content By Query Web Part similar to the one on the homepage of the Site, but with a filter on the Show itself. So each episode will have a page and it will link to all other episodes created.

This is done in two steps, firstly adding the Event Receiver to the Schedule List and then creating the Event Receiver.

I added the Event Receiver code to the Web scoped Feature Receiver FeatureActivated method. This can also be done in the definition of the ListInstance, but as I discussed before, because I will be cleaning up after myself I keep the adds and deletes in the same place for consistency. For the purposes of this tutorial I'm not doing anything but an ItemAdded, but you could have triggers on editing the Schedule or deleting it too to clean up pages created etc.

web.Lists["Schedule"].EventReceivers.Add(
  SPEventReceiverType.ItemAdded,
  "jeremythake.tvshowschedulesite, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8eb9a930004f2f1a",
  "jeremythake.tvshowschedulesite.ScheduleListEventReceiver");

I added the delete code to the FeatureDeactivating method as below. Now there is a risk that other Event Receivers could be added here so you may wish to check you delete the correct ones you've added.

for(int i=0; i<web.Lists["Schedule"].EventReceivers.Count; i++)
    web.Lists["Schedule"].EventReceivers[i].Delete();

The actual Event Receiver code is a simple C# class (.cs) in the root of the STSDEV project. The base of this is:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Diagnostics;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.Publishing.WebControls;
using System.Globalization;
 
namespace jeremythake.tvshowschedulesite
{
    public class ScheduleListEventReceiver : SPItemEventReceiver
    {
        public override void ItemAdded(SPItemEventProperties properties)
        {
            SPListItem currentListItem = properties.ListItem;
            using (SPWeb web = properties.OpenWeb())
            {
 
            }
        }
    }
}
 

From here you can start doing the work to create the new Page. There were some teething problems in getting the Page title to appear correctly in the navigation and getting access to what is easy in the Interface as the Page Title by going to the Page Settings page:

image

Because the Page is in the Pages List, you have to access the List Item Properties to change this...setting the PublishingPage Title Property doesn't set it. This took a little time to fathom out!

PublishingWeb pw = PublishingWeb.GetPublishingWeb(web);
 
//Get List Template - used below
SPListTemplateCollection listTemplates = web.Site.RootWeb.ListTemplates;
SPListTemplate scheduleListTemplate = listTemplates[scheduleListTemplateName];
 
// Create the new page in the PublishingWeb.
PublishingPageCollection pages = pw.GetPublishingPages();
PageLayout[] pageLayouts = pw.GetAvailablePageLayouts();
PageLayout blankWebPartPageLayout = null;
foreach (PageLayout pageLayout in pageLayouts)
    if (pageLayout.Title == "Blank Web Part Page")
        blankWebPartPageLayout = pageLayout;
PublishingPage newPage = pages.Add(scheduleName + ".aspx", blankWebPartPageLayout);
string checkInComment = "Page created";
//Title modified here
newPage.ListItem["Title"] = scheduleName;
newPage.ListItem.Update();
newPage.CheckIn(checkInComment);

and then putting the web part on the page:

SPFile categoryPageFile = web.GetFile("Pages/" + scheduleName + ".aspx");
if (categoryPageFile.Exists)
{
    categoryPageFile.CheckOut();
    using (SPLimitedWebPartManager webPartManager = categoryPageFile.GetLimitedWebPartManager(PersonalizationScope.Shared))
    {
        ContentByQueryWebPart contentByQueryWebPart = new ContentByQueryWebPart();
        contentByQueryWebPart.Title = "Related Schedules";
        contentByQueryWebPart.WebUrl = web.Url;
        contentByQueryWebPart.BaseType = string.Empty;
        contentByQueryWebPart.ServerTemplate = Convert.ToString((int)scheduleListTemplate.Type, CultureInfo.InvariantCulture);
        contentByQueryWebPart.CommonViewFields = "Air_x0020_Date,AirDate;Episode_x0020_Number,Episode;Season_x0020_Number,Season";
        contentByQueryWebPart.ItemStyle = itemStyle;
        //filter by schedule
        contentByQueryWebPart.FilterField1 = web.Lists[listName].Fields["Title"].Id.ToString("B");
        contentByQueryWebPart.Filter1ChainingOperator = ContentByQueryWebPart.FilterChainingOperator.Or;
        contentByQueryWebPart.FilterOperator1 = ContentByQueryWebPart.FilterFieldQueryOperator.Contains;
        contentByQueryWebPart.Filter2ChainingOperator = ContentByQueryWebPart.FilterChainingOperator.And;
        contentByQueryWebPart.FilterValue1 = scheduleTttle;
        contentByQueryWebPart.FilterType1 = "Text";
        contentByQueryWebPart.ShowUntargetedItems = false;
        webPartManager.AddWebPart(contentByQueryWebPart, "Right", 0);
    }
    categoryPageFile.CheckIn("Added Page");
    categoryPageFile.Publish("Published");
}

Again, this can be extended to start showing further web parts as they are developed such as Character guides or RSS feeds from fan sites etc.

I've uploaded the zipped project again for you guys to have a look at here.

diigo itdeliciousdiggfacebookreddit

Comments

Friday, 20 Feb 2009 08:31 by

blog comments powered by Disqus