The AdditionalPageHead
control is one of the most commonly used delegate controls by developers to add custom code to the page. Controls registered to the AdditionalPageHead
control are added to the <head>
element of each page and multiple controls may be added, unlike most other delegate controls that only allow one user control.
In this recipe, we will create an ASCX
user control that will add references to a custom stylesheet and custom JavaScript. We will then register the control to be added to the AdditionalPageHead
delegate control. Using an AdditionalPageHead
delegate control allows us to add our custom stylesheet and custom JavaScript to every SharePoint page, regardless of which master page is being used. This is particularly useful when a custom master page is not required and when managing the master pages for sites on a large scale becomes impractical.
We should have already created our Visual Studio project in the Creating a Visual Studio solution for custom delegate controls recipe of this chapter before starting this recipe.
Follow these steps to create a delegate control to add JavaScript and stylesheet references to each page:
Layouts
mapped folder.CustomCSS.css
, for example./* CSS Comment */
CustomJS.js
, for example.// JavaScript Comment
CONTROLTEMPLATES
mapped folder.CustomJavaScriptAndStyleSheets.ascx
, for example.CustomJavaScriptAndStyleSheets.ascx.cs
, for example.CustomJavaScriptAndStyleSheets
class, override the CreateChildControls
method as follows:protected override void CreateChildControls() { }
CreateChildControls
method, add a new SPMonitoredScope
object:using (new SPMonitoredScope("Code6587EN.Ch07.CONTROLTEMPLATES.Code6587EN.Ch07.CustomJavaScriptAndStyleSheets::CreateChildControls")) { }
var url = SPContext.Current.Web.ServerRelativeUrl.TrimEnd('/') + "/_layouts/15/Code6587EN.Ch07/CustomJS.js";
ClientScriptManager
object of the current page:this.Page.ClientScript.RegisterClientScriptInclude("CustomJS", url);
ASCX
user control, CustomJavaScriptAndStyleSheets.ascx
for example.CssRegistration
control:<SharePoint:CssRegistration ID="customCssRegistration" Name="<% $SPUrl:~Site/_layouts/15/Code6587EN.Ch07/CustomCSS.css %>" runat="server"></SharePoint:CssRegistration>
CustomJavaScriptAndStyleSheets
, for example.Elements.xml
file of the new element, register our custom control with the AdditionalPageHead
control using the following code:<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Control Id="AdditionalPageHead" Sequence="10" ControlSrc="~/_controltemplates/15/Code6587EN.Ch07/CustomJavaScriptAndStyleSheets.ascx"> </Control> </Elements>
In similar fashion to the Layouts
mapped folder, items in a SharePoint 2013 solution within the CONTROLTEMPLATES
mapped folder will be located under /_CONTROLTEMPLATES/15/
.
Elements.xml
file within it) in the Solution Explorer pane.CustomJavaScriptAndStyleSheets
(the name of the user control we created without the .ascx
extension)$SharePoint.Project.AssemblyFullName$
Code6587EN.Ch07.CONTROLTEMPLATES.Code6587EN.Ch07
(the full namespace for the user control, without the name of the class itself)True
True
CustomJavaScriptAndStyleSheets
(the name of the class for the user control)Features
folder. Rename the feature to the project name. Each of the elements we add in the recipes for this chapter will automatically be added to this feature:Code6587EN.Ch07 Delegate Controls
, for example as shown in the following screenshot:The Elements.xml
file of our Empty Element instructs SharePoint to add our referenced user control to the delegate control with the Id
of AdditionalPageHead
. The sequence provides SharePoint the order in which to add controls referencing the same Id
to the page. For delegate controls that accept just one control, only the registered control with the lowest sequence will be added.
An SPMonitoredScope
object allows developers to designate portions of code to be monitored for usage statistics in the Unified Logging Service (ULS) logging and the developer dashboard. Using them is not a requirement; however, they do make it easier to identify bottlenecks and other potential issues in custom code. As a matter of best practice, I find it is valuable to use SPMonitoredScopes
whenever a block of code affects what is rendered on a page. They do not provide a whole lot of value for backend code that doesn't affect the user interface. The name provided for the scope is a bit arbitrary. You can use whatever you want. However, I find it helpful to use a standard pattern. The pattern used in the examples for this book is Namespace.ClassName::Method
. This pattern provides the information required to know exactly where the code is in our project.
Adding our safe control entry to Safe Control Entries of the Empty Element item will add the safe control entry to the SharePoint web application's web.config
configuration file. Without this registration, SharePoint will throw an exception indicating the control is not safe when attempting to load it.
Once loaded, our user control will add references to our custom stylesheet and JavaScript files to the page.
3.143.235.23