My career in technology

This is part seven of my exploration of a solution I recently completed, using an event handler to programmatically create and configure a site based on form data provided by users and a site template created and managed by a SharePoint power user.

So far, I have:

  1. set up the requirements to run the event handler
  2. determined whether or not a site needs to be created, and, assuming that need exists…
  3. created the site
  4. created groups for site members to belong to, given those groups permissions, and added members to the groups
  5. added alerts for each of the group members on several lists
  6. added items to a list, based on information provided by the requestor
  7. activated a third-party feature on the new site
  8. modified views on a list, again based on data from the requestor

Whew! That’s a lot! Remember, all of these tasks had previously been done manually for each site. But wait! That’s still not all! “Now how much would you pay for it?” “You still can’t cook a chicken on it!” (Sorry, too much TV as a child. Warped my brain!) Anyway, there is still more to do.

Now it is time to fix the KPI list and fix the navigation.

(Links to the other parts in the series are at the bottom of the post!)

        private void DoAllSiteCreationSteps()
            //Make sure this runs with appropriate privileges to actually run the commands
                //ToDo #1: Create the site
                //make sure the site has finished baking before continuing
                for (int i = 0; i < 30; i++)
                //ToDo #2:  Create the site user groups
                //ToDo #3:  Provision the site with the data about the project type for correct display
                //ToDo #4:  Set the filters for the Eval Factors List in the new site
                //ToDo #5:  When a site is created from the template, the KPI List points to the template.  Change the KPIs to get their data from the site in which it resides.
                //ToDo #6:  Fix the top nav so it matches parent site

Having fixed the filters on the views of the Evaluation Factors, it is time to set those views as the source for the KPI indicators on the KPI List.

The KPI List is a special “custom list” for displaying KPIs. For each item in the list, you point it at another list, pick which view of the list you want to work with, and what your success criteria are. In this case, the KPIs indicate the completion rate of items for each of the project phases, so the data sources for the KPIs are supposed to be the views of the Evaluation Factors list. When a certain percentage of factors have been successfully completed, the indicator for that phase moves from red to yellow, or from yellow to green.

Unfortunately for this project, the data source URL is not relative, it is a full URL. So when the data sources are configured on the template site and the template is saved from that site, the KPI lists in new sites built from the template all point back to the Evaluation Factors on the template site.

Here’s a metaphor (I love metaphors): I’m giving a class on using a wristwatch (since no one wears them anymore, everyone uses their cell phone or PDA). I tell the students, “When I ask you ‘Where do you wear your watch?’, you respond ‘On my left wrist.'” I go down the line and ask each student, “Where do you wear your watch?”, and each one replies “On Jim’s left wrist.” That’s what’s happening in the site templates (students) – they are all looking at the template site (my wrist) for their data. And no matter how many factors have been completed successfully on a new site, the KPIs remain in red status, since factors on the template site are never modified to show as completed!

The old way of doing things, as I explained in the first post in the series, was that the power user went to the new site and manually reset the data sources of the indicators. The goal is to automate all those manual processes.

Let’s take a look at how to use code to reset the KPI’s data source.

        private void DoFixKPIListEntries()
                // In the template is a list of KPIs in the KPI list
                // [protocol]://[serverURL]/[MainProjectSite]/[ProjectSubsiteContainer]/[businessArea]/[siteName]/Lists/Project%20KPIs

                SPList ListToUpdate = BuildWeb.Lists["Project KPI's"];
                SPListItem ListItemToUpdate;
                string[] FilterNames = new string[]
                                    "Project Plan",
                                    "Project Kickoff",
                                    "Project Deliverables",
                                    "Detailed Project Review"
                string KPIDataSource = parentSiteUrl + siteName + "/Lists/Evaluation Factors/AllItemsg.aspx";
                string KPIDataSourceName = "Evaluation Factors";

                for (int i = 0; i < FilterNames.Length; i++)
                    ListItemToUpdate = ListToUpdate.Items[i];
                    ListItemToUpdate["Data Source"] = KPIDataSource;
                    ListItemToUpdate["View Guid"] = GetViewGUID(KPIDataSourceName, FilterNames[i]);
            catch (Exception ex)
                LogTheError("EventHandlerName", "Error in DoFixKPIListEntries(): " + ex.Message + " Stack Trace: " + ex.StackTrace);

(Remember that BuildWeb, parentSiteUrl and siteName are all previously defined class-level variables.)

The KPIs reside in a KPI List named “Project KPI’s”. The first item in the list is Items[0]. We set the the “Data Source” with the full URL of the new site’s Evaluation Factors list. The tricky part is that you also have to set the View Guid as well. Did anyone see where I put that Guid? No? Darn.

Fortunately, SharePoint can help me get the Guid I need. I wrote a little bit of code to get SharePoint to give me the Guid. GetViewGUID() takes the List Name and View Name as parameters and returns the Guid.

        private object GetViewGUID(string ListName, string ViewName)
            SPList ListToIdentify = BuildWeb.Lists[ListName];
            Guid ViewGUIDNeeded = ListToIdentify.Views[ViewName].ID;
            string ViewGUID = ViewGUIDNeeded.ToString();
            return ViewGUID;

Get the list by name from the SPWeb, then get the View by name from the SPList, and get its ID, which is the Guid, then format it as a string and return it.

That takes care of #5 on the To Do list. Like some of the others, To Do #6 is very straightforward.

        private void DoFixNav()
            //Fix the navigation
            BuildWeb.Navigation.UseShared = true;

When the new site is created, it doesn’t use the parent navigation. By setting UseShared to true, the code causes the site to use the navigation of the parent site.

Next comes the hard part!

                //ToDo #7:  Modify web part pages

In which I do things which will later cause mysterious, as-yet-unsolved errors! Join me for the fun, next time!

I’d love your feedback. Is there something you think I could be doing better? Are there questions about the code I haven’t answered? Am I full of it? Let me know! Feel free to use these code samples in accordance with my usage policy.

Check out Part One here (The Setup).
Check out Part Two here (The Decision).
Check out Part Three here (If You Built It…).
Check out Part Four here (…They Will Come).
Check out Part Five here (Bring ‘Em All In).
Check out Part Six here (Ride the CAML!).
You are reading Part Seven.
Check out Part Eight here (Taking Part!).
Check out Part Nine here (Deconfigured).
Part Ten (The Log Blog) is coming!

More posts about SharePoint.


Comments on: "Automated SharePoint Site Provisioning Solution – Act Seven (Pointing The Way)" (2)

  1. Very interesting and detailed post. If you revisit, I suggest taking another look at the SPSecurity.RunWithElevatedPrivileges wrapper.

    You may encounter unexpected behavior with that API call. Read about the best practices and proceed with caution.
    Daniel Larson’s Windwows Live Blog appears to be down, but there is a copy at this address:

    • Thanks Tom! That post looks very interesting, and I will look at updating my code. I appreciate the tip!

      For everyone else reading this blog, if you aren’t familiar with Tom, not only is he a nice guy, but he’s also a very sharp SharePoint MCM.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: