in

Platinum Bay

Peace, Love, and...

This Blog

Syndication


.NETicated

Hacking Community Server: Event Calendars Part 1

This is the first of a five-part series on implementing an event calendar in Community Server 2007. Our first step today will be to implement dynamic URLs, and the page stubs to go with them.

Your first instinct might be to dive right in to the SiteUrls.config file, and start adding content. While you can certainly do this, Community Server provides support another file for just such a purpose: SiteUrls_Override.config. The benefit of using this file lies in encapsulation and separation. If and when an upgrade comes along that modifies the SiteUrls.config file, you won't have to scramble to save your changes. You also won't have to dig through hundreds of default URL configurations to find your stuff.

Go ahead and create a file called SiteUrls_Override.config in your root Community Server directory. For our purpose, the contents look like this:

<?xml version="1.0" encoding="utf-8" ?>
<
Overrides>
    <
Override xpath="/SiteUrls/locations" mode="add">
        <
location name="events" path="/events/" themeDir="events">
            <
url name="eventhome" path="" pattern="default.aspx" physicalPath="##eventthemeDir##" vanity="{2}" page="eventlist.aspx" />
            <url name="eventapplication" path="default.aspx" pattern="default.aspx" physicalPath="##eventthemeDir##" vanity="{2}?App=${{app}}" page="eventlist.aspx" />
            <url name="eventday" path="archive/{1}/{2}/{3}.aspx" pattern="archive/(\d{4})/(\d{1,2})/(\d{1,2})\.aspx" physicalPath="##eventthemeDir##" vanity="{2}?y=$1&amp;m=$2&amp;d=$3" page="eventlist.aspx" />
            <url name="eventmonth" path="archive/{1}/{2}.aspx" pattern="archive/(\d{4})/(\d{1,2})\.aspx" physicalPath="##eventthemeDir##" vanity="{2}?y=$1&amp;m=$2&amp;d=1" page="eventlist.aspx" />
            <url name="eventId" path="archive/{1}/{2}/{3}/{4}.aspx" pattern="archive/(\d{4})/(\d{1,2})/(\d{1,2})/(\d+)\.aspx" physicalPath="##eventthemeDir##" vanity="{2}?y=$1&amp;m=$2&amp;d=$3&amp;EventID=$4" page="event.aspx" />
            <url name="eventName" path="archive/{1}/{2}/{3}/{4}.aspx" pattern="archive/(\d{4})/(\d{1,2})/(\d{1,2})/([a-zA-Z0-9\-\._]*?)\.aspx" physicalPath="##eventthemeDir##" vanity="{2}?y=$1&amp;m=$2&amp;d=$3&amp;EventName=$4" page="event.aspx" />
            <url name="eventcategory" path="archive/category/{1}.aspx" pattern="archive/category/(\d+)\.aspx" physicalPath="##eventthemeDir##" vanity="{2}?CT=Event&amp;CategoryID=$1" page="eventlist.aspx" />
            <url name="eventalltags" path="archive/tags/default.aspx" pattern="archive/tags/default.aspx" physicalPath="##eventthemeDir##" vanity="{2}" page="eventtaglist.aspx"/>
            <url name="eventtags" path="archive/tags/{1}/default.aspx" pattern="archive/tags/(.*?)/default.aspx" physicalPath="##eventthemeDir##" vanity="{2}?Tags=$1" page="eventlist.aspx"/>
        </
location>
    </
Override>
    <
Override xpath="/SiteUrls/transformers" mode="add" where="after">
        <
add key = "##eventthemeDir##" value = "/themes/{0}/{1}/" />
        <
add key = "##eventdirectory##" value = "{0}/" />
    </
Override>
    <
Override xpath="/SiteUrls/navigation" mode="update">
        <
navigation>
            <link name="home" resourceUrl="home" resourceName="home" roles="Everyone" />
            <link name="blog" resourceUrl="webloghome" resourceName="weblogs" roles="Everyone" applicationType = "Weblog" />
            <link name="events" navigateUrl="/events/" resourceName="events" roles="Everyone" />
            <link name="forums" resourceUrl="forumshome" resourceName="forums" roles="Everyone" applicationType = "Forum" />
            <link name="gallery" resourceUrl="galleryhome" resourceName="photos" roles="Everyone" applicationType = "Gallery" />
            <link name="files" resourceUrl="fileshome" resourceName="files" roles="Everyone" applicationType = "FileGallery" />
            <link name="controlpanel" resourceUrl="controlpanel" resourceName="controlpanel" roles="SystemAdministrator,BlogAdministrator,ForumsAdministrator,Moderator,GalleryAdministrator,FileAdministrator,ReaderAdministrator,MembershipAdministrator" />
        </
navigation>
    </
Override>
</
Overrides>

Don't worry; it's not really as bad as it looks. Inside of the Overrides root tag are two Override tags. The Override tag tells Community Server which section of the SiteUrls.config you are overriding. The override tag has two main attributes; xpath and mode. The xpath attribute defines which section of the SiteUrls.config file you are overriding. The mode specifies how you are overriding that section, and has three options: add, update, and change. For the add value, you can specify an additional attribute: where.

<Override xpath="" mode="[add|update|change]" where="[start|end]">
</Override>

The URL has a number of attributes that need to be specified.

  • name -- the name of the URL which can be used as the UrlName on the <CSControl:SiteUrl /> control to generate links to this new URL.
  • path -- the path is used to format the URL through controls such as <CSControl:SiteUrl />
  • pattern -- when matching a request, the pattern (which supports RegEx syntax) is used to detect if the requested URL matches the <url />
  • physicalPath -- because this is a themed page, physicalPath should be set to "##themeDir##"
  • vanity -- vanity defines the reformatting of the requested URL (which can use RegEx matches from the pattern attribute) to the local URL. For themed pages, {2} will identify the page within the <location />s themeDir.
  • page -- page represents the name of the ASPX file within the <location />s themeDir in the current theme that implements the UI of this <url />

One exception to the above attributes is that in this case I am using ##eventthemeDir## because we are using a custom theme directory. This takes place in the transformers override.

In the first group, I am adding a new location tag, and adding URLs to that location. URLs include tags, categories, and separation by date, just like blog posts. In the second group I am rebuilding (updating) the navigation bar that lives right below the header. Though it seems like duplication, you need to use mode="update", and re-include each item that you want in the navigation in order to be able to place your new item where you want.

And voila, you now have a new menu item in your menu bar.

But don't get too excited, we're not done yet. If you were to attempt to navigate to your /events/ folder, the request would most likely fail. This is because when IIS receives the request for the folder, it sees that the folder doesn't exist and throws a 404 error, rather than passing it on to the ASP.NET runtime. In order to fix that situation, we need to create the /events/ folder, and add an empty Default.aspx file to it. Well, not quite empty, you need to add an empty Page declaration. I added a comment line as well for maintainability.

<%@ Page %>

<%
-- Placeholder for URL rewriting--%>

Yup, that's it. The reason for this is to make sure any requests for this directory get passed to the ASP.NET runtime (aspnet_wp.dll).

So we're almost there, but there is still one more thing to do. In order to accommodate our new event location URLs, we need to create the event theme directory and the page stubs. For now, create a directory named Events in your Themes/[theme] directory. Next, create three normal ASPX files called eventlist.aspx, eventtaglist.aspx, and event.aspx. What I did was to add a little content to the page to identify each one, and write out the querystring value.

event content here
<p>
<%= Server.UrlDecode(Request.Url.Query) %>
</p>

Now you can go ahead and test out your URL rewriting, and check the results on the resulting pages.

Here are some URLs to try:

  • /events/archive/category/mycategory.aspx
  • /events/archive/2007/06/01.aspx
  • /events/archive/2007/06.aspx
  • /events/archive/tags/default.aspx
  • /events/archive/tags/mytag/default.aspx

Stay tuned for Part 2 of this series, where we will explore creating a Community Server data and application provider for our calendar event system; the business and data layers of our event calendar.

Comments

December 29, 2007 10:12 PM

Any chance you will post more details on how to build the Event Calendar functionality for CS?  Your solution here looks pretty clean.  I really need this functionality on a site I'm hosting and would rather not recreate the wheel since you've already done it.

Maybe you can package it up as an official add on for CS.

 

November 7, 2008 9:13 AM

Hello,

Where can i access the rest of this series?

-thanx

Phil Luong
 

Leave a Comment

(required )  
(optional )
(required )  
Add

About Steve

Steve Andrews is an independent consultant, INETA speaker, and Microsoft MVP for Visual Studio ALM. He has been working in technology for over ten years focusing on custom application development and Application Lifecycle Management. Steve is also Microsoft and IBM certified and a community fanatic having led sessions at nearly 100 events across North America. When he's not developing software solutions or engaging with the community about software technology, Steve is a closet singer and songwriter and plays the guitar and keys. Occasionally, Steve even gets to sleep. Occasionally.
Powered by Community Server (Commercial Edition), by Telligent Systems
© Platinum Bay | Some Rights Reserved Creative Commons License

Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Feel free to challenge me, disagree with me, or tell me I'm completely nuts in the comments section of each blog entry, but I reserve the right to delete any comment for any reason whatsoever (abusive, profane, rude, or annonymous comments) - so keep it polite, please.