Kirk Evans is a Microsoft Architect for the Azure Center of Excellence.
Introduction to SharePoint and Azure IaaS
Building SharePoint Apps with Windows Azure Platform as a Service
SharePoint Solutions and Architectures on Windows Azure Infrastructure Services
Understanding Authentication and Permissions with Apps for SharePoint and Office
A customer asked how they could add jQuery to every page in SharePoint. They wanted to modify core.js on the disk, but of course we all know that Microsoft does not support modifying files that reside in the _layouts folder. Of course there are supported ways to do this without such hacks.
All of the out-of-box SharePoint master pages (v4.master, default.master, minimal.master, and nightandday.master) include the following in the HEAD section of the HTML markup:
Chris O’Brien has a great write-up of Using the Delegate Control. The DelegateControl provides a plugin framework for SharePoint, telling ASP.NET to find any registered delegate controls, and for each call the LoadControl method to load your control. It’s a very slick way to add controls to pages without modifying the master page.
The solution for us is to deploy the jQuery script to SharePoint, and then deploy a delegate control that references that script location.
This is one of those things that I think every SharePoint developer should become instantly familiar with. You can add your own user controls to SharePoint and reference them from your pages just like you can with ASP.NET. In Visual Studio 2010, create a new empty SharePoint project called “Microsoft.PFE.DSE.Samples” and make it a farm solution.
Note: We could deploy a delegate control using the sandbox as well. I chose to use a farm solution because I am deploying the jQuery library to the SharePoint root (aka 14 hive), which you cannot do with sandboxed solutions.
In Visual Studio, click “Add New Item” and add a new User Control called jQueryControl.ascx.
In the source view for the control, add the following line of code:
The result looks like this:
That’s how easy it is to create a control and deploy it to SharePoint. You can now use your control in your pages in SharePoint. Now, let’s see how to register it as a delegate control.
The next step is to add a feature to the project that tells SharePoint about our control. In Visual Studio, add a new “Empty Element” to your project named “elements”.
Change the resulting Elements.xml to the following:
<?xml version="1.0" encoding="utf-8"?>
Now that the feature element is created, we need to edit the feature that deploys it. Open the feature in the SharePoint project and change the scope to “Web”. Give it a title and description as well.
By deploying your feature with web scope, every page in the web where the feature is activated will include the jQuery script, including pages in the layouts directory (remember that they use master pages with AdditionalPageHead, too). If you change the scope to “Site”, every page in your site collection will include the script, changing to WebApplication means every page in your application gets it, and Farm means every single page in the farm gets it.
The last part of the puzzle is to deploy the jQuery script file to the layouts directory. Right-click your project and add a SharePoint “Layouts” Mapped Folder.
Hit F5 in Visual Studio 2010 to deploy the solution and start debugging. The debugger will automatically attach to the page, and you will see the script loaded in the debugger, without having to modify the master page, the page you are viewing, and certainly you won’t be modifying core.js to make it happen!
The source for the project is attached.
Using the Delegate Control
Couldn't you just do this with a Module and a custom action targeting the ScriptLink?
Sure, that's another approach. Yet another is to edit and deploy custom master pages. Yet another is to embed the script in page layouts so that only certain types of pages get the script reference. Another is to add the ScriptManagerProxy into your page and reference the script. I could go on, there's lots of ways to accomplish it, each provides various benefits. The benefit for the delegate control is that it can be overridden by deploying another feature to the same delegate with a lower sequence. See: panvega.wordpress.com/.../sharepoint-delegate-controls