| The Content Query Web Part (CQWP) is the workhorse of SharePoint Publishing sites. The power behind the CQWP is that it allows you to configure a query using the web part tool pane, but then style the resulting XML by using your own custom XSL style sheets. Unless you want to modify the existing XSL file in SharePoint Designer, however, you need to modify a property of the web part (called ItemXslLink) to point to your new, custom XSL file. You can't update this property within the web part tool pane; the only way you can do it is to utiize a version of the web part that already has this value set. You can do this by either uploading a version of the .webpart file with this property set, or you can add a version of this .webpart file to your Web Part Gallery.
Often times, when developing SharePoint solutions using Visual Studio, the optimal things to do is to add this modified .webpart file to a solution package, and include it in a Feature, so that when the Feature is activated, this modified .webpart file gets uploaded to the Web Part Gallery.
There is a problem, though. The XslItemLink property requires an absolute URL. It does not use a site-collection-relative URL. That is to say, if you give your ItemXslLink property a value of "/XSL Style Sheets/MyStyleSheet.xsl", it will always look for the file in the site collection with a base URL of "/", so SharePoint will look for a file with a URL of something like http://mysite.com/XSL Style Sheets/MyStyleSheet.xsl. It doesn't matter if your site collection is actually located at http://myurl.com/sites/accounting/. If you try to use the original URL in a different site collection, SharePoint displays an error message when you try to use the web part, which says, essentially, you can't use that XSL file because it's in a different site collection. If you wanted the style sheet to work in the latter site collection, you'd have to use a different version of the .webpart file that has an ItemXslLink property set to that current site collection's URL, such as http://mysite.com/sites/accounting/XSL Style Sheets/MyStyleSheet.xsl.
Why is this a problem? Because if I deploy a Feature scoped to the Site Collection level, my assumption is that the Feature should work in any site collection where the Feature is activated, not just in the single site collection where that ItemXslLink property path points to. (It completely defeats the purpose of reusability in Features.)
Although I'm not typically a fan of customization, I don't see a way around it when dealing with this issue. The code you see below is code you can put in a Feature event receiver that will dynamically look for the CQWPs in your Web Part Gallery (which presumably were just added there when the Feature was activated), search the .webpart XML for the ItemXslLink node, and populate it with a site collection-specific URL.
Please note that the query looks for any web part file in the Web Part Gallery that begins with "CQWP_". I have purposely given my CQWPs this prefix, so my web parts have names like CQWP_NewsRollup.webpart, etc. You can choose to do a different CAML query if it suits you. Also, please substitute the path to the XSL style sheet with the path to your own style sheet. Finally, this code would obviously work, with a little modification, if you wanted to modify other properties in the CQWP web part file, too. SPQuery query = new SPQuery(); query.Query = "<Where><BeginsWith><FieldRef Name=\"FileLeafRef\"/><Value Type=\"Text\">CQWP_</Value></BeginsWith></Where>";
SPListItemCollection items = site.RootWeb.GetCatalog(SPListTemplateType.WebPartCatalog).GetItems(query);
if (items.Count > 0) { XmlDocument xmlDoc = null; XmlReader xmlReader = null;
foreach (SPListItem item in items) { Stream fileStream = item.File.OpenBinaryStream(); StreamReader fileReader = new StreamReader(fileStream); StringReader stringReader = new StringReader(fileReader.ReadToEnd()); xmlReader = XmlReader.Create(stringReader); xmlDoc = new XmlDocument(); xmlDoc.Load(xmlReader);
XmlNamespaceManager nsm = new XmlNamespaceManager(xmlDoc.NameTable); nsm.AddNamespace("wp", "http://schemas.microsoft.com/WebPart/v3");
XmlNode propertiesNode = xmlDoc.DocumentElement.ChildNodes[0].ChildNodes[1].ChildNodes[0]; XPathNavigator navigator = propertiesNode.CreateNavigator(); XPathNavigator selectedNode = navigator.SelectSingleNode("wp:property[@name='ItemXslLink']", nsm);
if (selectedNode != null) { selectedNode.InnerXml = site.ServerRelativeUrl + "/Style Library/XSL Style Sheets/CustomItemStyle.xsl";
if (item.File.CheckOutType == SPFile.SPCheckOutType.None) { item.File.CheckOut(); item.ParentList.RootFolder.Files.Add(item.File.Url, Encoding.UTF8.GetBytes(xmlDoc.InnerXml), true); item.File.CheckIn("Modified by feature event receiver."); } } } }
|
| Although Business Connectivity Services provide a robus way of connecting to back-end data sources, it's sometimes easier to use the ADO.NET object model. However, there's a catch with this approach: because SharePoint web front end servers can be load balanced, it's not usually a good idea to modify the web.config files on your servers directly in order to add your connection string information. Instead, you're supposed to use the SPWebConfigModification class. This presents its own problem, though; if you have to embed the connection string in code, it defeats the reason why you wanted to put the connection string in the web.config file in the first place... to provide an uncompiled way to change the connection string for each new environment (such as Dev, QA, ad Prod)!
A way around this is to store connection string information in the property bag of an SPWeb object, or in the property bag of your web application (SPWebApplication) object. The nice thing about this approach is it allows you to modify the connection string in different farms. The downside is that there's no native ability to modify property bag data in the SharePoint user interface.
I decide to go ahead and build my own quick-and-dirty Connection String Manager. (The link to the Visual Studio project is at the bottom of this article.) It allows you to add, remove, and edit connection strings for a particular web application.
First, you'll deploy the solution package (BB.ConnectionStringManager.wsp). After that, you'll see a new farm-scoped feature called Connection String Manager. Once you activate the feature, you'll see a new link show up in Central Administration on the Application Management page, under the Web Applications heading. It will say Connection String Manager.

If you click on this link, it will take you to the Connection String Manager page. From here, you can select the web application you want to add connection strings to.

All this interface does is add a property to the underlying SPWebAppilication.Properties property bag, with the name of the connection string (prefixed by the word ConnectionString). If you want to access the connection string, you can simply do it in your code by accessing the current site's web application object and retrieving the value directly, like this:
SPContext.Current.Site.WebApplication.Properties["ConnectionStringDatabaseA"].ToString();
Otherwise, you can use a public static class that's part of the BB.ConnectionStringManager assembly, like this:
string connectionString = BB.ConnectionStringManager.ConnectionString.GetConnectionString("DatabaseA");
You can download the zipped up Visual Studio project here:
BB.ConnectionStringManager.zip |
| Thanks to everyone who came to hear Marty Hansen and I present our lecture "Step 1: Create Retention Rules that Work" lecture, whether you heard us in Kansas City this weekend at SharePoint Saturday, or whether you heard us at the St. Louis User Group on Tuesday.
For those who are interested, you can download the slide deck here:
Developing Retention Rules that Work
(To the left is a pictue of me and my little elf at SharePoint Saturday Kansas City.) |
| For those who attended my "How Do I Connect to That?" lecture in Chicago on Thursday and in Kansas City today, thanks for coming! Here's the slide deck in case you'd like to download it.
How Do I Connect to That.pptx |
| The fine folks at Mindjet have allowed me to peruse a couple of their products: Mind Manager 2012 and Connect SP. The best way to sum up this product is that it's "brainstorming" software. However, the great thing about this type of product is that it's concept is so basic, it can be used in numerous different scenarios.
I was first introduced to the product by my uncle, who professionally helps scientists bring inventions to market. He typically works with PhDs who have an idea and have to get funding, perform some research and development, get a working prototype running, and then mass produce their invention. There are a lot of steps involved in this process and it's a dance to balance the creative process of inventing something (which can't always be done on a timeline) with funding, project timelines, etc. My uncle uses Mind Manager to map out his projects.
Once I took a look at the tool, I was excited about how it could be used in developing information architectures for SharePoint sites. When clients are trying to organize where content belongs in their site, a tool like this could be a great way for people to spitball ideas of what should go in their new site, and then easily drag and drop these ideas into new locations.
The tool is even helpful for business planning. I am a consultant, but I also am a small business owner (of one employee... myself), an MVP, and a trainer. There are a number of tasks I need to do on a regular basis to keep my business running and to keep my professional image and skills current. It can get easy to lose sight of these types of activities when my primary job is to show up at clients and carry out tasks for them (instead of for my own business). I decided to create a "mind map" that lays out my strategic initiatives. I can drill down to any one of these areas and assign tasks to each area as needed. This will help me track my progress towards my various goals over time.
The most basic functionality of Mind Manager is that it allows you to easily create hierarchies of ideas, starting with a "topic", then drilling down to a "subtopic", etc. These topics can be connected or not connected. They can be prioritized or not. These topics can be linked to URLs, notes can be added to them, they can be assigned to be people as tasks, they can be exported, and more.

One of the great features of Mind Manager, as you can see from this screenshot, is that you can assign tasks to yourself in Outlook based on a task you put into your mind map. (You can see that you also have a number of other export options as well.) You also can import task information into your mind map from a SharePoint site collection. This means that you can maintain task information in your SharePoint environment (where you can integrate your task lists with other SharePoint lists, outlook, workflows, etc.) but use Mind Manager to keep track of the statuses of various tasks associated with a project or other structure you've mapped out in Mind Manager.

As you can see in the example above, I've incorprated tasks from my SharePoint site "Becky Bertram's Blog" (the current site you're looking at), into my "Administrative overhead" topic. If I click the refresh icon, it will do a query to the SharePoint site to update the completion status of that task.
Luckily, just as I was working with Mindjet to get a copy of Mind Manager, they just released A product called Connect SP. This product not only has a web part that allows you to view mind maps, it also allows you to create mind maps within the browser in your SharePoint site, much the way Office Web Applications work. This is a very slick solution to allow your enterprise to develop and use mind maps without having to install the desktop version of Mind Manager on all your workstations.

Some of the other really neat features of this product that I like are:
- The ability to export your mind maps as PowerPoint slides.
- The ability to take your brainstorming topics and put them on analysis charts, like the "magic quadrant" type charts.
- The built-in "idea cards" that help you brainstorm. These contain questions such as "What if you changed the rules? What would change?"
These are helpful for getting your creative juices flowing.
I am really looking forward to using this product with my own business as well as using it help my clients strategize about their SharePoint initiatives. |
| After taking some time off from public speaking after the birth of my daughter in May, I'm back at it! I'll be speaking at the three upcoming events in December:
SharePoint User Group Chicago December 8, 2011 - 1 p.m. - 5 p.m. Topic:How Do I Connect to That? You might of heard of one or more of these terms before: Business Connectivity Services, ADO.NET, the Entity Framework, and LINQ. You might know that these can all be used in one way or another to connect SharePoint to external data sources. However, it can be confusing to know the various options available to you for getting information from an external data source into SharePoint and getting information written back to that data source. It can be even more difficult to know which connectivity model to choose given your particular SharePoint application. I will give an overview of how BCS, ADO.NET, and the ADO.NET Entity Franework can all be used independently or in combination with one another to connect your SharePoint environment to back end data sources.
SharePoint Saturday Kansas City December 10, 2011 Topics: How Do I Connect to That? and Managing Records in SharePoint – Step 1: Develop Retention Rules that Work Your organization has decided to manage records and information in SharePoint. Your first step must be to develop an accurate file plan and retention rules. Without applying retention rules to SharePoint, you might be headed for trouble. This session will guide you through the process of developing a file plan with retention rules and implementing it in SharePoint. This session will also show you how you can use the SharePoint object model to write code that will create and update retention policies programmatically. I'll be co-presenting with Marty Hansen from Jordan Lawrence.
SharePoint User Group St. Louis December 13, 2011: 8:00 a.m. - 11:00 a.m. Topic: Managing Records in SharePoint – Step 1: Develop Retention Rules that Work In addition to the topic outlined above, I'll be walking through a code snippet that shows how to program your own retention policy. This lecture will be following a lecture by several folks from Knowledge Lake who will be talking about Enterprise Content Management in SharePoint. |
| Rob Bogue is a SharePoint MVP who is well-known for one of the only published books out there written for SharePoint end-users (as opposed to the myriad of books written for developers or IT folks), called The SharePoint Shepherd's Guide for End Users. (This book can actually be licensed in a digital edition as well, for use in corporate environments.) The SharePoint Shepherd's Guide takes users through the step-by-step actions they need to take to perform particular tasks such as uploading a document to a library or adding a colleague to a My Site. It's written in a reference manual way, so users can quickly look up the kind of task they want to execute and learn how to do it, rather than feeling like they need to sit down and read the book cover-to-cover before they can use a SharePoint site. Most of the tasks include numerous screen shots to guide users through the process.
Rob recently came out with a new DVD series that dovetails on his book. It's called The Psychology of SharePoint Adoption and Engagement. Although it's important to explain to someone how to carry out a task (whether that's showing an end-user how to check in a document or helping a programmer know how to use the SharePoint object model), when it comes to SharePoint, there's something much bigger at stake, and that's ensuring that the SharePoint site that's being built is going to be used, period, by users.
I've often said that SharePoint sites need "more carrot, less stick" (as Christian Buckley so nicely summed up) in terms of getting users to use the site you're building. After all, building a fantastic site that no one uses is a fantastic waste of effort. Rob's video goes into great depth of explaining why it's important to go beyond just getting users to "adopt" SharePoint (i.e. forcing them to use the site you've built for them), instead getting them to fully "engage" with SharePoint, which means users are making the platform their own and actively using SharePoint as a tool that makes their life better. Rob uses many illustrations and analogies to help drive his points home.
Although the price of the video can seem a bit steep for 2.5 hours, I actually think it's rather reasonable in price. Watching the video is like watching a recorded class lecture at a university. In that context it wouldn't be unreasonable at all to pay several hundred dollars for a good lecture. Along those same lines, much of the content Rob covers in his video is much of the same kind of content I spend hours communicating to my own clients. In the long run it could be cheaper to buy the DVD than to pay a consultant like myself to deliver the same content. I think this DVD could be helpful not only for organizations who want to know how to get their users to engage with SharePoint, but is also helpful for consultants who want to learn the basics of SharePoint adoption so they can guide their own clients through the process of creating a great SharePoint site. |
| Often times, companies and organizations want to have a "master" calendar which shows all the important events for a given timeframe. Some of these events might originate from other calendars. For instance, the Human Resources department might have calendar entries for events such as enrollment periods for health insurance. Someone from the HR department might want to add a date to their local HR calendar on their local HR departmental site in SharePoint, and have this event show up on the master calendar so everyone in the company can see it. However, the HR department might also have a chili cook-off on Friday and it might be nice to put that on their local HR subsite calendar, too. However, that event should not be displayed on the master calendar, since it's only pertitent to those folks in HR. It's easy to accomplish this functionality in SharePoint.
- First, create both calendars: your Master calendar and your Child calendar.
- In your Child calendar, add a new column to your Event content type that is of type Yes/No. Call the column something like "Show on Master".
- Next, create a new view on your Child list called Master Calendar View. Base that view on the Calendar View. Use the default settings, except add a filter that says Show on Master equals Yes. Save your view.
- Now, go to your Master calendar and click on the Calendars Overlay button on the Calendar tab.
- Click on the New Calendar button.
- Give the calendar the name that you want to show up for users on the Master calendar. Type in the URL of the subsite to which your Child calendar belongs. Select the Child calendar in the List drop down menu, and select Master Calendar View in the List View dropdown menu. Save your changes.
Your Master calendar will now show an overlay of your Child calendar, but it will only display those events where the Show on Mater checkbox was checked. |
| I've been writing code that will create a new content type in the site collection root with a retention policy, the create a new library using that content type. I kept getting the following error when opening up the "Compliance Details" window for new documents in my new library: "Column '_dlc_Exempt" does not exist. It may have been deleted by another user."

Column _dlc_Exempt is a hidden column that's part of Records Management in SharePoint Server that indicates whether a document is allowed to be exempt from a retention policy. It almost seemed as if the content type was still in the process of having these additional columns attached to it when my code was going ahead and provisioning the library that used the content type, so my library didn't get these new columns added to it, which the content type needed when trying to display the "Compliance Details" widow.
The solution to the problem was simple: I just needed to make sure my new retention policy got added to the site collection content type after I provisioned my new library that used it. The content type in the library will automatically pick up the retention policy applied to the same content type in the site collection. |
| If you’re like me, you have a bookcase somewhere in your office where you keep books and documents that you want easy access to because you might want to reference that information at some later date. My bookcase has a shelf where I keep things such as training manuals, design specifications for past projects, industry publications, as well as books by my favorite authors. Unfortunately, after several years of collecting these sorts of materials, I find that the information I’m keeping is pretty outdated. I have to start asking myself if I really need to keep that book about SharePoint 2003 or if that MSDN Magazine from 2006 is really going to be helpful anymore. There comes a point in time where I have to clean out the old so I have room for the new. If I don’t do some house cleaning, I’ll have so much outdated material on my shelf that I’ll no longer easily be able reach for my more recent documents or books without having to sift through a decade or more of old papers.
The same logic holds true for document retention in an electronic document repository like SharePoint. Old documents stored in a SharePoint environment take up server space just as my documents take up my shelf space.
Read the rest of this article, "Applying Document Retention in SharePoint 2010" on the official MVP blog.
|
Manage Subscriptions /_layouts/images/ReportServer/Manage_Subscription.gif /_layouts/ReportServer/ManageSubscriptions.aspx?list={ListId}&ID={ItemId} 0x80 0x0 FileType rdl 350 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rdl 351 Manage Shared Datasets /_layouts/ReportServer/DatasetList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rdl 352 Manage Parameters /_layouts/ReportServer/ParameterList.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 353 Manage Processing Options /_layouts/ReportServer/ReportExecution.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 354 Manage Cache Refresh Plans /_layouts/ReportServer/CacheRefreshPlanList.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 355 View Report History /_layouts/ReportServer/ReportHistory.aspx?list={ListId}&ID={ItemId} 0x0 0x40 FileType rdl 356 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsds 350 Edit Data Source Definition /_layouts/ReportServer/SharedDataSource.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsds 351 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 350 Manage Clickthrough Reports /_layouts/ReportServer/ModelClickThrough.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 352 Manage Model Item Security /_layouts/ReportServer/ModelItemSecurity.aspx?list={ListId}&ID={ItemId} 0x0 0x2000000 FileType smdl 353 Regenerate Model /_layouts/ReportServer/GenerateModel.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 354 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType smdl 351 Load in Report Builder /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderModelContext&list={ListId}&ID={ItemId} 0x0 0x2 FileType smdl 250 Edit in Report Builder /_layouts/images/ReportServer/EditReport.gif /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderReportContext&list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 250 Edit in Report Builder /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderDatasetContext&list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 250 Manage Caching Options /_layouts/ReportServer/DatasetCachingOptions.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 350 Manage Cache Refresh Plans /_layouts/ReportServer/CacheRefreshPlanList.aspx?list={ListId}&ID={ItemId}&IsDataset=true 0x0 0x4 FileType rsd 351 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rsd 352 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 353 |
|
|
|