[Home] [Recent] [Site Map] [SharePoint] [XBOX]
The Microsoft Office Interactive Developer Map is a Windows Presentation Foundation (WPF) application that helps developers visualize the different programs, servers, services, and tools that will help them build solutions. It allows them to drill down to each product and technology and learn about new features, objects, Web services, namespaces, and schemas required to extend Microsoft Office and build custom Office Business Applications (OBAs).
The map is a living document that provides links to MSDN Library reference documentation, MSDN portal pages, and RSS feeds that describe how developers can use the 2007 Microsoft Office system and associated tools and technologies to develop solutions that meet their needs.
The map stores resource links in an XML file hosted on MSDN. Once you install it, the map pulls the latest version of the resource file. No need to reinstall!
The map"s default view:
One of the map"s detail views:
If you have any ideas or suggestions for improving the usability or usefulness of the map, please leave a comment.
<Lawrence />
Dominion Digital, a Virginia-based Microsoft Gold Partner, recently launched the Performance Food Group’s new website at www.pfgc.com. Performance Food Group markets and distributes more than 68,000 national and private label food and food-related products to over 41,000 restaurants, hotels, cafeterias, schools, healthcare facilities, and other institutions.
The following guest blog entry was written by Anthony Wenzel, a Principal at Dominion Digital, with assistance form a couple of his colleagues. Anthony was the Technical Lead for the website project, which included a complete UI and content redesign and was implemented using Microsoft Office SharePoint Server (MOSS) 2007. The project was completed on time and on budget with a very aggressive schedule even though those factors were not a requirement for getting the opportunity to write this guest blog entry. :-) If you were the Technical Lead for a novel and/or challenging SharePoint based project (and not necessarily an Internet facing website or even MOSS dependent) for which you and your customer are willing to share the technical reasons behind critical design decisions, tips and tricks, and innovative ways of leveraging SharePoint"s multitude of capabilities, please ping me.
<Lawrence />
The design of the website was accomplished by first understanding and defining the audience personas and then using that information to guide the information architecture and graphical design of the site. Next, the site map was developed, which was used to create the base site structure in MOSS. Once the page designs were completed, the MOSS master pages, page layouts, and content types were created to implement the design.
As with all of our projects, we followed an iterative process that allowed us to deliver designs and working versions of the site on a regular basis for review by the project team. This agile approach allowed all stakeholders to be part of the development process and provided timely review and feedback of all elements of the project.
The team was comprised of a Dominion Digital development team plus the PFG marketing and IT groups. We worked in a collaborative manner, such that knowledge transfer about how the site was being implemented in MOSS occurred throughout the development cycle. Development occurred on a few development servers and then implemented in the “Authoring” MOSS server farm. The Content Deployment feature was then used to publish the site to the “Production” MOSS server farm.
For this project, we used MOSS out-of-the-box features as much as possible, and only implemented custom web parts and web controls when absolutely necessary. For example, the Content Query Web Part (CQWP) was used extensively for displaying lists throughout the site, such as news, executive bios, events, etc.
Instead of describing all of the development tasks and website features in this article, I will focus on those areas that required a special approach or unique solution.
The design of the website included a consistent page design across the entire site, with different header graphics and color schemes for each of the major sections of the site. To support this design, we utilized Nested ASP.NET Master Pages. We implemented a main master page that includes the header (logo, site search, etc.), main menu and footer, which were consistent across all pages in the site. We then implemented nested master pages for each of the major sections of the site, which included the header graphics and colors for each section. Within MOSS, we configured each section (i.e. MOSS child sites) to utilize the appropriate section master page so that all pages in that section displayed the appropriate header graphics and colors.
Most of the pages in the website were based on one of 3 page types (home page, section landing page, content page), requiring only a few Page Layouts for most of the site. A few pages required custom formatting, for which we created additional Page Layouts. Instead of using generic web part pages with Content Editor web parts, we implemented content types and Page Layouts with content fields on them. This gave us better control over the editing view of the pages to provide a more WYSIWYG experience for the content authors.
The out-of-the-box menus provided with MOSS generate HTML with table-based layout. To achieve better standards compliance and to style the menus with CSS, we wanted menus based on unordered lists (i.e. HTML <ul> and <li> tags). There were various options available for doing this, including using the CSS friendly control adapters or using the MossMenu source code, each of which had its pros and cons. After some careful consideration, we chose to implement a custom web control derived from the CompositeDataBoundControl class, and our implementation was based on the sample code in Bryant Likes’ blog. This produced a web control that is referenced in our master pages for both the main menu and the local navigation menu, and gave us the flexibility to do custom formatting of our menus.
On a technical note about using the CompositeDataBoundControl class, we ran into an issue of our menu not working properly on a page postback. In that class, the CreateChildControls() function has a “datasource” parameter that contains a SiteMapNodeCollection, which includes the data for the menu. On a page postback, this parameter is null, which required storing the menu data in viewstate so that it could be accessed when generating the menu on a page postback.
The website included a database of recipes that were categorized and searchable. The data for these recipes was contained in a SQL database, and we originally considered (and prototyped) using the Business Data Catalog to interface MOSS directly to that database. While this worked and would have allowed the data to be kept in that database, it did not allow us to leverage the MOSS content management workflows for editing and maintaining the recipe data. Instead, we created a Content Type to hold the recipe data and created a custom Page Layout for displaying the recipes. This provided an out-of-the-box WYSIWYG recipe editing environment, as well as a review and approval workflow for new and revised recipes, thereby allowing many users in the organization to submit new recipes and maintain existing recipes.
Since the recipe data was already contained in a SQL database, we did not want to re-type all of the recipes into the MOSS pages. Instead, we wrote a data import script that read the data from the SQL database and created new web pages based on the Recipe Content Type. The import script left those recipes in a “Pending Approval” state so that each one could be reviewed and approved before being published to the production site. Our script was based on the code in the Building tylerbutler.com, Part 4 post on the ECM Team Blog.
The site design specified the ability to searching of recipes based on keywords and categories. The categories were setup as Lists in MOSS to allow easy maintenance, and a custom Recipe Search web part was implemented to display the category selection and keyword input controls. Since the Recipe Content Type included the categorization data for each recipe, a custom Recipe Search Results web part was implemented that performed the custom search query and displayed the results.
The website included content that is hosted by CareerBuilder.com and Shareholder.com. Instead of linking directly to those sites, we wanted those pages to appear within the PFG website. To implement that, we created pages that included <iframe> tags to link to the third-party pages.
We also integrated with Google Maps to provide a map of PFG locations. This was implemented as a page that utilized the Google Maps API, while still allowing editing of the content on that page.
Similar to the AspMenu web control, the default behavior of the Content Query Web Part (CQWP) generated HTML table-based layout, and we needed it to generate HTML unordered lists. Fortunately, the CQWP included support for XSL-based formatting, so we customized the XSL templates to generate the proper HTML, as described in Heather Solomon’s blog.
Our site required several different output formats, which were all implemented with custom XSL templates for the CQWP. The most complex formatting was for the Press Releases page, which included custom Javascript to cause the current year section to initially be open and all other sections to initially be collapsed.
The site included several “Contact Us” forms that would allow visitors to provide their contact information. The submitted information would then be routed to the appropriate PFG personnel to handle the request. We implemented a List to hold the submitted information and created a custom list form, as described here.
We initially implemented a custom event handler to send an email and/or launch a workflow each time a form was submitted. Unfortunately, due to a bug or limitation in MOSS, an anonymous user’s action could not launch a workflow, so this approach had to be scrapped. As a workaround, we wrote a custom script to read and remove the submitted items from the Lists. It is our hope that this issue will be resolved in the upcoming MOSS Service Pack.
The homepage of the website required a dynamic “Homepage Spotlight” feature that would allow PFG to easily specify and schedule pages in the site to be spotlighted on the homepage. To allow flexibility, we needed a scheduling and prioritization mechanism that was beyond the capabilities of the CQWP.
To implement this feature, we added a set of scheduling, prioritization, and content fields to the base page content type – these fields could then be edited on each page in the site. We then implemented a custom web part based on the CQWP that performed a custom query with the scheduling and prioritization fields to select the correct page to be spotlighted. From that point, all display formatting was done using the standard CQWP XSL formatting capabilities.
As a Microsoft Gold Partner, Dominion Digital had significant experience with .NET development. Nonetheless, this project required us to get ramped up on many of the moving parts in MOSS. However, even with that, the vast capabilities of the MOSS platform allowed us to create and deliver this website within a short timeframe.
We had heard the marketing pitch that “MOSS was 100% built on the .NET 2.0 Framework,” but we were initially skeptical. However, every time we dug into the details of the new capabilities in MOSS, we were pleasantly surprised to find that it was truly based directly on .NET 2.0. Not once did we find an aspect of the product that did not derive directly from the .NET 2.0!
Although this project focused solely on the web content management aspects of MOSS and not on the many other capabilities including business intelligence with Excel Services, Office 2007 client integration, collaboration, personalization, or enterprise search, based on our experience on this project as well as further work with some of those other capabilities, we have found MOSS to be a stable and feature rich platform for creating practically any web-based applications.
Anthony Wenzel
Principal, Dominion Digital
awenzel@dominiondigital.com
Lora Bouchard
Managing Consultant, Dominion Digital
lbouchard@dominiondigital.com
Darrell Estabrook
Art Director, Dominion Digital
destabrook@dominiondigital.com
Since Microsoft Popfly was announced about a week ago, the buzz about it has continued to grow. In fact, Popfly got a huge boost from being part of the Facebook Platform announcement yesterday. Since Facebook’s aspiration for being the “social OS” for the Web reflects some aspects of what SharePoint has already achieved within the enterprise as a collaborative application platform or as Mary Jo Foley opined, the “missing link between personal productivity and line-of-business applications,” the natural question to ask is, “So, what can SharePoint do with Popfly?”
The short answer is, “Quite a lot.” The longer answer is provided here by Mike Gannotti, a Microsoft Technology Specialist for SharePoint based in Raleigh, NC.
<Lawrence />
With the ability to create rich mashups of information for display in a web page, Popfly presents a great opportunity for SharePoint users to create new exciting data presentations within SharePoint. When looking at possible synergies and points of integration between the two there are two primary areas of focus. These are; Popfly consumption and display of SharePoint driven content, as well as SharePoint consumption and display of Popfly delivered content. In this write-up I will walk you through both of these approaches with the hope that it will prepare you to begin creating your own dynamic renderings of Popfly coupled with SharePoint on the Internet.
With its libraries and lists, often tailored with custom content to meet organizational needs, SharePoint instantiations potentially have a wealth of data that can be served up, and rendered by, Popfly. The primary means of data delivery today that can be taken advantage of is SharePoint RSS. SharePoint serves up all of its library and list data as RSS by default, and Popfly is built to take advantage of this out of the box.
Popfly uses a construct known as blocks to capture and consume data as well as to render it. In the case of SharePoint RSS feeds, the block of choice is easy to single out: It is simply titled RSS. You can drag and drop one or more RSS blocks to grab RSS data from SharePoint, as well as from other RSS sources.
Once you have your block(s) on the Popfly canvas, you can then set them to pull your RSS feeds of choice. Click on the wrench to open the attributes interface and then type or paste the RSS feed in the given box. For example: I can copy the URL to my blogs RSS feed for my posts as seen below (note that I have left the default Operations options to getItems rather than getFeed).
You can do this for up to three feeds, and the information consumed can be varied (for examples of different types of RSS data and their uses, see my Popfly – SharePoint Integration screencast). If we are only tying to a single feed, then we are ready to go about setting up the presentation of our data. However, if we have chosen more than one feed, then we need to combine them into a single source of data for our presentation layer. Luckily for us, this is easily accomplished with the Combine block.
The Combine block allows us to combine two or three feeds into a single data feed. Doing this is also very simple. First, drag the Combine block onto your Popfly canvas. Click on the first RSS block and then move your mouse cursor over the Combine block and click again. This will cause there to be a push connection from the RSS block to the Combine block. You should now see a resulting blue bar indicating the connection as well as a yellow warning triangle in the Combine block. Repeat this procedure for each remaining RSS block.
To get rid of the warning triangle and to prepare our data for rendering, we need to edit the Combine block by clicking on the “wrench” icon. Under Operations, we can setup the Combine block for two or three data sources. Then for each feed, we will go through in turn and select the RSS block under Source and then [entire RSSItem object] under Value. Repeat for each desired RSS block.
Once finished, the yellow warning triangle will disappear and you are ready to set up your information’s visual appearance and delivery.
Now that our SharePoint RSS feed(s) are setup, our next step is to determine how we will display that information and deliver it. If we have geotagging information as part of the feeds, then we may want to display our data on a map. If we simply want to display text content we can do so in a reader. For our purposes here, we will select and illustrate the latter.
Having decided to display our data in a reader, we will find the News Reader block and drag it on to our canvas.
We will click on the Combine block and then on the News Reader block to create a connection much in the same manner as we did earlier with the RSS blocks to the Combine block. Once our connection is set, the next step is to edit the News Reader block’s properties by clicking on its “wrench.” Upon doing so, we will be greeting with settings for headline, date, content, and fullStoryURL. Under Source, we will select Combine for each of the dropdowns. This will in turn automatically set the attributes for display under Value.
We can now preview our resulting application by selecting Preview at the top of the Popfly canvas. After previewing, click Customize at the bottom of the screen to return to the canvas. If we wanted to pretty up our Reader, we could add custom HTML code and continue to preview and rework until we were totally satisfied with the results.
Next, we save project and then select the option to Share it. This will allow us to easily embed the project as mashup in a SharePoint site (or another website) as well as to have it used as a Windows Vista Gadget! That’s right, we can combine SharePoint’s RSS feeds through a Popfly mashup and expose it as a Windows Vista Gadget on the desktop with any coding!
Now that our Popfly mashup is done, how can we embed it, or any other Popfly mashup for that matter, on a SharePoint site? Luckily for us, the Popfly folks have made this very simple. We will be taking advantage of their Embed It functionality in combination with SharePoint’s Content Editor web part.
Our first step will be to grab the embed code from Popfly. To do this, from our Projects page, we will select Embed It under the desired mashup and copy the exposed code.
On the desired SharePoint page, we will add the Content Editor web part where we want to place our mashup. Once the web part is in place, we will edit the web part, naming it as desired, and setting the Chrome Type to None. Optionally, we can go into the Rich Text Editor view and add text, links, or pictures. In the Source Editor view, we will simply paste the embed code copied from Popfly. We can play around with the height and width settings as necessary either in the Popfly code or in the Content Editor web part to achieve our desired look.
That’s it! We’re done, and our mashup is now rendering through SharePoint. We can now export our Content Editor web part if desired and reuse it on another SharePoint site by simply importing it.
The same content can now be available as a Gadget on our desktop as well if desired as mentioned previously. Quick, easy, and very cool!
Popfly and SharePoint can be used in tandem to provide rich mashups against a number of data types including SharePoint RSS feeds. Information can be pulled from SharePoint into Popfly, served up from Popfly to SharePoint, and even re-exposed as a Windows Vista Sidebar gadget. All of this can be done literally in a few minutes by users with little or no programming skills and easily shared with others.
You can see more examples of Popfly content rendering in SharePoint on my Silverlight Showcase page.
I have also created a Popfly – SharePoint Integration screencast in which I walk through the creation of several different types of mashups to include mapping features, image rendering, and more.
I hope that you’ve enjoyed this blog entry and that you will start creating your own mashups in Popfly very soon. Let your imagination fly – Popfly that is! :-)
Michael Gannotti, TSP SharePoint
Microsoft Greater Southeast District
[Cross-posting of RandallI"s blog entry.]
Here is the rundown of Technical Articles, Visual How-to Screencasts, and their accompanying downloads published over the last couple of weeks on MSDN.
Technical Articles
Visual How-to Screencasts
Although development techniques involving HttpHandler components are useful when creating standard ASP.NET applications, you should also see them as a valuable building block for building business solutions for Microsoft Windows SharePoint Services 3.0 and Office SharePoint Server 2007.
When a user clicks a menu item in the entry control block, it runs an application page. The code behind the application page typically must program against the list item or document that supplied the menu item. To do this, the application page must be able to identify the list item or document. Windows SharePoint Services does this by passing the information that identifies the list item or document to the application page in a query string. The page uses this information within the page-initialization code to create an SPListItem object and its containing SPList object.
If you want to audit the actions of users as they view your custom application pages, you must add code that writes custom audit entries into the Windows SharePoint Services audit log. You can write custom audit entries within the context of any auditable object, such as those of type SPSite, SPWeb, SPList, and SPListItem.
I"ve received several inquiries about the SendTec website that was mentioned in a recent blog entry, so I"m very pleased to post the following "how we did it" guest blog entry written by Ted Vreeland (Application Architect) and Dave Redman (Managing Sr. Software Engineer), who were the Technical Leads for the project.
<Lawrence />
SendTec, Inc. is a multi-channel marketing company deploying traditional agency resources as well as innovative technology solutions for the benefit of ROI-minded advertisers. As part of an overall corporate rebranding effort, SendTec wanted to redesign the look and feel of their corporate website. The overall goals for the new site were:
The SendTec Business Technology Team had very limited experience with SharePoint technologies. A key decision needed to be made whether to build the new site with ASP.NET (which had been used to build the existing site) or with MOSS 2007. Two members of the Business Technology team quickly ramped up on MOSS 2007 with an emphasis on the Web Content Management (WCM) capabilities, customizing MOSS sites, developing custom web parts, and content deployment. The decision was made to move forward with building the new site with MOSS 2007, but there were some design features in the new site that would prove to be significant challenges for the Business Technology team.
Design. The design of the new site was done by SendTec’s in-house creative team. To achieve the look and feel as laid out by the designers, the project team needed to create a new master page; custom content types; several new page templates; and define many new custom CSS styles.
Navigation. The new site included three-tiered navigation. At first glance, it appeared that MOSS only supported two tiers. After some digging under the covers, it was discovered that MOSS did provide the underlying functionality to support more than two-tiered navigation by using a custom administrative tool to manage the additional level. In addition, the design called for the top menu bars to appear on the left-hand side of the pages. This was achieved by creating a custom menu control that inherited from the standard ASP.NET 2.0 menu control along with the use of the CSS Control Adapter Toolkit for ASP.NET 2.0.
Search Engine Rankings & SEO. The new site had to maintain its existing search engine rankings and needed to provide SEO support by way of keywords and description “meta” tags. To support the first part of this challenge, the Business Technology team created a custom ASP.NET module to handle stripping out the “/pages” portion of the in-bound URL as well as removing it from the HTML being returned to the browser. In addition, a redirect handler was employed to ensure that pages that no longer existed in the old site were routed to the appropriate page in the new site. To support the SEO requirement, the default Page content type within MOSS was extended with custom column types that allow copywriters to modify the keywords and description of a page themselves. The site’s Master Page was modified to include these values in the header section of the output HTML.
Content Management. Several areas of the new site were to be managed by copywriters, designers, and content managers. To achieve this, the WCM features within MOSS were enabled within an intranet version of the site. In addition, several lists were created to allow content managers the ability to quickly add new press releases, articles, white papers, and job postings. To support design requirements, custom web parts were created to query the lists and format the output. Incremental content deployment jobs are used to periodically push new and updated content to the Internet-facing MOSS farm.
Performance. MOSS 2007 provided performance well beyond our expectations right out of the box. Server load and response times were significantly better than our old site. However, we felt that we could improve site performance even more, so we implemented the built-in caching capabilities of MOSS that are well documented here. The first part of the implementation was using the BLOB caching. This reduced the amount of database overhead since there was no need to retrieve content from the database each time an image, document, or any other infrequently changing item was requested. The second part of the implementation was the use of profile output caching. Since our site is primarily visited by anonymous users, we decided to enable the “Public Internet (Purely Anonymous)” cache profile with no changes to the default settings. The implementation of BLOB caching and cache profiles immediately cut our response times in half. Our final step to improve performance was to reduce our page size. The biggest reduction of page size was to eliminate the need to have the 257KB core.js in our pages for anonymous users. So we implemented a simple custom control to remove the core.js script from the HTML output for non-authenticated users.
The SendTec.com website was launched on April 24, 2007. Shortly after going live, the project team made some modifications to the HTTP modules to improve security. The content managers and designers have been utilizing the WCM features of MOSS, and they really like being able to make site changes without the need to involve the Business Technology Team. The SendTec management team is very pleased with the decision to implement the new site using MOSS 2007, and in fact, is planning on utilizing MOSS for future client websites. This would give clients the best of both worlds – having SendTec provide the creative and technical expertise to design, build, and host their site, but still give clients the ability to add or modify content as they wish.
Ted Vreeland
Application Architect, MCD
tvreeland@sendtec.com
Dave Redman
Managing Sr. Software Engineer, MCAD
dredman@sendtec.com
Have you ever wanted to have a persistent chat session right on your SharePoint team or collaboration site? It can be much easier and quicker for typing a message than SharePoint’s built-in Discussion Board. The ChatterBox web part provides an example of how such a persistent chat session can be implemented by utilizing a SharePoint list, so there’s no need to create a custom database. If you need more than one chat session on your site, you can simply create another instance of the ChatterBox web part and associate it with another SharePoint list. Here’s a screenshot of it in action.
You can download the ChatterBox 1.0 web part and source code, which have been released as part of the Community Kit for SharePoint, right here. An enhanced, ASP.NET AJAX-based version of the ChatterBox web part is already in the works and will be released shortly after Service Pack 1 for WSS 3.0 and MOSS 2007 becomes available, so I’d recommend that you don’t spend too much time trying to extend the current version. Just play with it and see what innovative ideas you and its users can come up with in terms of new features. Color coding and online detection are already planned for the next version, so you’ll need to be more creative than that! :-)
If you cannot wait until SP1 to start taking advantage of ASP.NET AJAX for SharePoint, I’d encourage you to take a look at the SharePoint AJAX Toolkit on CodePlex, but note that this is a community driven shared source project and is not owned or sponsored by Microsoft.
<Lawrence />
One of the challenges of accessing SharePoint calendars via the object model is that there are so many different types of events – normal events, all-day events, recurring events, recurrence exceptions, and deleted instances – and they all look more or less the same! In this post, I will shed some light on how to work with calendar events, describe the subtleties of recurrences, and put that knowledge to work exporting events to the RFC 2445 iCalendar format.
First, before we can do anything with a Calendar list, we need a way to distinguish between different event types.
Calendar items in SharePoint fall into several categories. Single events are those which don’t repeat and only appear once on the calendar, while recurring events may show up any number of times depending on the recurrence pattern selected by a user. Either type of event may have a defined start and end time, or it may be an all-day event which lasts from midnight to 11:59 PM.
Furthermore, individual instances of a recurring event may be deleted or edited, creating a new event which takes its place. The event created by a deleted instance instructs the calendar not to render that day’s instance of the recurring event.
Calendar events can be distinguished by looking at the fRecurrence, fAllDayEvent, and EventType field values:
|
Type |
Description |
fRecurrence |
fAllDayEvent |
EventType |
|
Single event |
An event created with the All Day Event and Recurrence checkboxes unselected. |
False |
False |
0 |
|
All-day event |
An event created with the All Day Event checkbox selected. |
False |
True |
0 |
|
Recurring event |
An event created with the Recurrence checkbox selected. Has a recurrence icon in the All Events view. Appears as a single master event on the All Events view, but as recurring instances on the Current Events and Calendar views. |
True |
False |
1 |
|
Recurring all-day event |
Same as above, but with the All Day Event checkbox selected at creation time. |
True |
True |
1 |
|
Recurrence exception |
Created by editing an instance of a recurring event. Has a strikethrough recurrence icon in the All Events view. |
True |
False |
4 |
|
All-day recurrence exception |
Same as above, but created by editing an instance of an all-day recurring event. |
True |
True |
4 |
|
Deleted instance of a recurring event |
Created by deleting a instance of a recurring event. Title is prefixed with “Deleted:” in the All Events view, and is hidden in the Current Events and Calendar views. |
True |
False |
3 |
|
Deleted instance of an all-day recurring event |
Same as above, but created by deleting an instance of an all-day recurring event. |
True |
True |
3 |
Recurring events have a number of subtleties not found in single events. Most importantly, one recurring event item expands into any number of recurring event instances when it is rendered in the calendar view. Recurring events also make use of fields left empty in single events.
Certain fields are interpreted differently depending on whether the item in question is a recurring event or a single event:
|
Field |
Value for single event |
Value for recurring event |
|
EventDate |
Start date and time |
Start date and time set for the recurring event when it was created, which may be an earlier date than the first instance of the recurring event. |
|
EndDate |
End date and time |
End date and time for the last instance of the recurring event. For recurring events with no end date, this is a computed date several years in the future. |
|
Duration |
The time in seconds between EventDate and EndDate. |
The duration in seconds of an individual instance of the recurring event. |
Similarly, exceptions and deleted instances have fields which relate the event back to the parent recurring event:
|
Field |
Value for exception or deleted instance |
|
MasterSeriesItemID |
The ID of the recurring event from which this exception or deleted instance was made. |
|
RecurrenceID |
The date and time of the instance of the recurring event which this exception or deleted instance takes the place of. |
Once you’ve determined that you’re working with a recurring event, you’ll likely want to work with individual instances of the recurrence.
Recurring events store the pattern used to display instances of the recurring event as XML in the RecurrenceData field. While this data is best used in a read-only fashion, the following are examples of the patterns you may encounter:
|
Recurrence type |
RecurrenceData field value |
|
Daily every 1 days, no end date |
<recurrence><rule> <firstDayOfWeek>su</firstDayOfWeek> <repeat><daily dayFrequency="1" /></repeat> <repeatForever>FALSE</repeatForever> </rule></recurrence> |
|
Weekly every Monday, Tuesday, and Wednesday, end by 5/31/2007 |
<recurrence><rule> <firstDayOfWeek>su</firstDayOfWeek> <repeat><weekly mo="TRUE" tu="TRUE" we="TRUE" weekFrequency="1" /></repeat> <windowEnd>2007-05-31T22:00:00Z</windowEnd> </rule></recurrence> |
|
Monthly the third Wednesday of every 2 months, no end date |
<recurrence><rule> <firstDayOfWeek>su</firstDayOfWeek> <repeat><monthlyByDay we="TRUE" weekdayOfMonth="third" monthFrequency="2" /></repeat> <repeatForever>FALSE</repeatForever> </rule></recurrence> |
|
Yearly every May 18, end after 10 instances |
<recurrence><rule> <firstDayOfWeek>su</firstDayOfWeek> <repeat><yearly yearFrequency="1" month="5" day="18" /></repeat> <repeatInstances>10</repeatInstances> </rule></recurrence> |
Thankfully, you don’t need to parse this XML yourself to get the actual instances of the recurring event. Instead, you can use the SharePoint object model to expand recurring events during a given month:
// Get the Events list
SPSite site = new SPSite("http://localhost");
SPWeb web = site.RootWeb;
SPList calendarList = web.Lists["Calendar"];
// Construct a query that expands recurring events
SPQuery query = new SPQuery();
query.ExpandRecurrence = true;
query.Query = "<Where><DateRangesOverlap><FieldRef Name=\"EventDate\" /><FieldRef Name=\"EndDate\" /><FieldRef Name=\"RecurrenceID\" /><Value Type=\"DateTime\"><Month /></Value></DateRangesOverlap></Where>";
// Look forward from the beginning of the current month
query.CalendarDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
// Returns all items (including recurrence instances) that
// would appear in the calendar view for the current month
SPListItemCollection calendarItems = calendarList.GetItems(query);
foreach (SPListItem item in calendarItems)
{
Console.WriteLine(item["Title"] + ": starts "
+ item["EventDate"].ToString() + " and ends "
+ item["EndDate"].ToString());
}
Note that after expansion, each instance of a recurring event has the same ID as the recurring event that produced it. In other words, a recurring event with ID 7 will appear as many recurring event instances in the code above, each with an ID of 7.
It’s always easier to learn from an example than from dry technical descriptions, and to that end I’ve developed a SharePoint Solution which uses the functionality I’ve described above. When installed and activated, it adds an “Export Calendar to iCal Format” button to the Actions menu of every Calendar list in the site collection as pictured below.
To convert events to RFC 2445 iCalendar format, I loop through each event, translating recurrence patterns into iCalendar format and associating exceptions and deleted instances with the recurring event they came from. The majority of the code deals with interpreting the recurrence pattern; however, there is also a significant amount of code to translate SharePoint timezone information as well.
You can download the iCalendar Exporter solution and source code, which have been released as part of the Community Kit for SharePoint, right here. Launch Visual Studio, take a look at my source code, and have fun developing custom solutions with the SharePoint calendar! Please leave a comment if you have any questions or want to showcase an innovative solution that you"ve built.
Matt Swann
SDET, SharePoint