Ways to load jQuery in SharePoint (2010/2013)

There are many different approachs to using jQuery with SharePoint. Here is a summary of several different methods I have used, including how to get it to play nicely with NuGet.

1. Decide where to put jQuery files

i. In a site collection Document Library

Recently I have been putting scripts in the master page gallery, but putting them in Style Library is a common choice, as it is available across all templates (whereas libraries such as Site Assets are only in team sites). The feature needs to be activated to make the scripts available.

  1. In your Visual Studio SharePoint project, right click the project and select Add > New Item…
  2. Select Module, and use the name ‘Scripts’.
  3. Configure an appropriate Site Collection (SPSite) level feature to reference the module; this can be a new feature, or added to an existing one.
  4. Rename Elements.xml to Scripts.xml (I like to give each Elements file a different name, so I can tell them apart in Visual Studio).
  5. In Scripts.xml, add Url=”_catalogs/masterpage” or Url=”Style Library/Xyz” to the Module element, where Xyz is whatever subfolder name you are using for this project, e.g.
    <Module Name="Scripts" Url="_catalogs/masterpage">

    OR

    <Module Name="Scripts" Url="Style Library/Xyz">

    Note that generally for the master page gallery I just use the root (which will put scripts into _catalogs/masterpage/Scripts) whereas for the Style Library I use a folder for the project (which will put the scripts into Style Library/Xyz/Scripts).

ii. Under _layouts

Available to everything on the server, this is also the location where many existing system JS files are located. One drawback is that it can’t be used in sandbox solutions.

  1. On your development machine, go to C:\Program Files\Common Files\microsoft shared\Web Server Extensions\14\TEMPLATE\LAYOUTS
  2. Create a subfolder named Scripts (or it can be put in a company specific directory such as Xyz\Scripts).
  3. In your Visual Studio SharePoint project, right click the project and select Add > SharePoint Mapped Folder…
  4. Select TEMPLATE\LAYOUTS\Scripts.

2. Add the jQuery (and other) library to the project

The folder name ‘Scripts’ was specifically used, because that is where NuGet packages such as jQuery put JS files. By using this name, the files can be automatically added.

  1. In your Visual Studio SharePoint project, right click and select Manage NuGet Packages…
  2. Select Online, enter ‘jQuery’ in the search box, and click the search icon.
  3. Select jQuery and click Install.

This will place the jQuery files into your Scripts folder. You can also install a specific version of jQuery if you want, via the Package Manager Console.

If deploying into _layouts, then nothing more is needed.

If jQuery is being placed in a library, then the files will have been automatically added to the Scripts.xml elements file, but you will want to update to make them GhostableInLibrary, e.g.

<File Path="Scripts\jquery-2.1.0.min.js" 
    Url="Scripts/jquery-2.1.0.min.js" Type="GhostableInLibrary" />

In SharePoint 2013, you can also mark the file with ReplaceContent (although this is more relevant for custom scripts that will change during development):

<File Path="Scripts\jquery-2.1.0.min.js" 
    Url="Scripts/jquery-2.1.0.min.js" Type="GhostableInLibrary" 
    IgnoreIfAlreadyExists="TRUE" ReplaceContent="TRUE" />

The same technique can be used to add any other desired NuGet script packages, and your custom scripts can also be added in a similar way.

3. Referencing the scripts

A. Referenced in a custom master page.

The key thing here if deploying to a library is to use a site collection relative link to the script, e.g. via the ScriptLink control in SP2013:

<SharePoint:ScriptLink language="javascript" 
    name="~sitecollection/_catalogs/masterpage/Scripts/jquery-2.1.1.min.js" 
    runat="server" Localizable="false" />

If the scripts are being stored in _layouts, then a relative ScriptLink can be used:

<SharePoint:ScriptLink language="javascript" 
    name="Scripts/jquery-2.1.0.min.js" runat="server" Localizable="false" />

You can also directly insert a script tag by breaking the reference up into a beginning and ending literals around a reference that resolves the path relative to the current site collection:

<asp:literal runat="server" 
    Text="&lt;script type='text/javascript' src='" /><asp:literal runat="server" 
    Text="<% $SPUrl:~sitecollection/_catalogs/masterpage/Scripts/jquery-2.1.0.min.js %>" 
    /><asp:literal runat="server" Text="'&gt;&lt;/script&gt;" />

B. Injected via a CustomAction.

A custom action can be used to add actions to the Ribbon, however it can also reference scripts. Although usually for scripts referenced by ribbon elements, this can actually load any script needed for the site.

  1. In your Visual Studio SharePoint project, right click the project and select Add > New Item…
  2. Select Empty Element, and use the name ‘CustomActions’.
  3. Configure an appropriate Site Collection (SPSite) level feature to reference the module; this can be a new feature, or added to an existing one.
  4. Rename Elements.xml to CustomActions.xml (I like to give each Elements file a different name, so I can tell them apart in Visual Studio).
  5. In CustomActions.xml, add a ScriptLink custom action pointing to the script location, e.g.
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <CustomAction Id="Xyz.ScriptLink.jQuery" Location="ScriptLink" 
        ScriptSrc="~sitecollection/_catalogs/masterpage/Scripts/jquery-2.1.0.min.js" 
        Sequence="10010">
      </CustomAction>
    </Elements>

If the link is wrong (not found), then the page will still load as the script reference is injected directly as HTML, although the script request itself will 404.

A relative link (not starting with ~ or /) will default to the _layouts directory and use the ScriptLink control:

<CustomAction Id="Xyz.ScriptLink.jQuery" 
    Location="ScriptLink" ScriptSrc="Scripts/jquery-2.1.0.min.js" 
    Sequence="10010">
</CustomAction>

One drawback of the ScriptLink control is that if the file is not found, the whole page will fail with an error like: Cannot make a cache safe URL for “scripts/jquery-2.1.0.min.js”.

C. Reference via a DelegateControl replacement

A common target for this is by replacing the AdditionalPageHead control. This will add jQuery to all pages in the site.

For an example of this technique, see: http://www.sharepointbriefing.com/features/article.php/3924951/jQuery-and-SharePoint-Part-I–The-Easy-Way-to-Load-the-jQuery-Library.htm

D. Reference via a custom Web Part

This involves creating a custom web part that add the reference to the script (such as via a ScriptLink or other control). It is useful if you only want jQuery available on one or two pages, wherever the web part is added. Be careful of multiple references to jQuery if you use this technique.

For an example of this, as well as the custom action approach, see Recipe 2 at: http://www.threewill.com/2012/01/adding-jquery-to-sharepoint/

E. Reference in user content

There are various content controls where HTML can be directly added. Probably the easiest in SP2010 is the HTML Form Web Part (in the Forms category), which allows direct editing of the HTML source (this can be less prone to error than the Content Editor web part). In SP2013, use the Script Editor web part.

<script type="text/javascript" 
    src="/sites/team1/_catalogs/masterpage/scripts/jquery-2.1.0.min.js" 
    ></script>

A downside of this approach is that the script source can’t use the ~sitecollection token and needs to reference the correct path.

Recommendations

These days I tend to prefer deploying into a document library (method i), and then referencing in either a custom master page, if used (method A), or using the CustomAction trick, if there is no custom master (method B).

Leave a comment

WSRP ‘support’ in SharePoint 2013

Web Service for Remote Portlets (WSRP) is a standard for aggregating content within a host system, allowing the content to come from an external system, yet styling to be provided by the host.

SharePoint has ‘support’ for WSRP since SharePoint 2007, via the WSRP Viewer web part (Enterprise), however while it may technically meet the standard it is all but useless for anything except the most basic of requirements (as at the current version, SharePoint 2013).

How WSRP works is, once configured, the host inserts an iframe into the page (to contain the portlet), with the source of that iframe pointed back to a proxy running on the host server itself. This allows the host server the opportunity to intercept and rewrite the requests and responses, for example style sheets from the host server can be injected, and page resources (such as images) can also be rewritten to point to the proxy.

Limitations with SharePoint:

* The code implementing the WSRP consumer (there is no producer support) appears to have been simply translated from Java, still contains many Java features/conventions, and isn’t very responsive.

* It does not work in SharePoint Online. In SPO, the WSRP Viewer web part is available, and can actually be added to a page, but there is no way to configure it to display anything. Configuration requires updating an XML file in ‘C:\Program Files\Microsoft Office Servers\15.0\Config’, which simply isn’t possible in SPO. See http://support.microsoft.com/kb/2871282

That means you need to have an full installation; it is an Enterprise feature, so you require an Enterprise version.

* Resource redirects do not work. Requests for resources from the proxy pages, such as images, fail with a security error unless the target authority (host name + port) is added to a list of allowed redirection servers.

These can be added to the configuration file with the undocumented <RedirectServer> element (repeating for each server), which gets past the security issue, however it still doesn’t work because the proxy page never sets the content type, leaving it at “text/html”. This means images aren’t displayed, scripts won’t be run, etc, all because they have the wrong MIME type.

This is probably why the configuration is undocumented. The feature was simply never completed.

* Portlets can’t be easily styled. While SharePoint does inject a style sheet into the rewritten content, it is hard coded to “/_layouts/1033/styles/core.css” (varying by language), with no way to configure.

This means it has SharePoint styling, but to style with any kind of site branding you would need to do something like directly edit the CSS file in the LAYOUTS directory, which I strongly advise against due to maintainability issues.

Features:

The few features that the WSRP Viewer part does have in SharePoint include that it can be integrated with the Secure Store for trusted subsystem style authentication. The <SsoApplication> element needs to be configured with the name of the Secure Store application that holds the credentials.

These credentials, if present, are then used as the network credentials for accessing the external (source) system. The WSRP Viewer can either be anonymous, or if configured to use the current user, it will pass through the Name property of the current SharePoint user in the <UserContext> element, userContextKey attribute, in requests to the source system. There is no way to configure this except turn it on or off.

There is also another undocumented configuration option where you can add <RegistrationProperty> elements, with Name and Value attributes, to the producer, which appear to be used as name/value pairs passed through to the RegistrationURL, if used. (I have not tested this, so it may not work.)

Summary:

In a pinch, WSRP could be used to display some plain text in an installed Enterprise environment, but you will very quickly hit limitations with customisation to the point that a plain iframe (Page Viewer web part) would generally do just as well.

I would recommend against changing the core.css style sheet in the LAYOUTS directory, but if your organisation is strongly committed to WSRP and you don’t mind a maintenance nightmare with SharePoint, then you could test to see if it works. (I haven’t yet).

Bottom line — WSRP isn’t really supported in any practical way.

Leave a comment

Vote Compass

So, usually I blog about technology, but it’s about time I added a bit of social commentary.

A cool feature of the recent Australian Federal Election was the ABC Vote Compass. Here it is, showing where the major political parties are placed:

VoteCompass2

This concept, of plotting both the economic and social position of politics, has been around for a while, e.g. the Political Compass or Political Quiz (note: both of these have the Y-axis the other way around, so you have to swap top-bottom to compare to the ABC Vote Compass).

It also shows why none of the major Australian political parties are a good fit for me — I want a mix of the economic right AND social liberalism, I want the social policies of the Greens / Labor, and the economic policies of the Coalition.

The positions of the major parties is something I could never quite understand: why is social liberalism so connected to the economic left, and why is the economic right (economic liberalism) so connected to conservative social policies?

That leaves me to turn to minor parties such as the Liberal Democratic Party (LDP), often with below the line voting (and wishing we had above the line optional preferences).

Leave a comment

XML Logging in the .NET Framework

This was originally going to be some guideline instructions for a CodePlex project, Essential.Diagnostics that I work on, but it ended up being more an opinion piece so I thought it would fit better on a blog.

There are several trace listeners (loggers) in the .NET Framework that can produce XML output. Outputting to XML results in more complex (verbose) files than, say, a simple text file output, but usually has the benefit of being better processed by tools, correlated across tiers, etc.

There are three main XML listeners, plus one extension in Essential.Diagnostics:

  • XmlWriterTraceListener
  • RollingXmlTraceListener (in Essential.Diagnostics)
  • EventSchemaTraceListener (in System.Core)
  • EventProviderTraceListener (in System.Core)

Examples of how to configure and use each one (used to produce the output below) is provided in the Essential.Diagnostics project.
Read the rest of this entry »

, ,

Leave a comment

Windows 8 Developer Preview Safe Mode

In Windows 8 the ‘Safe Mode’ option is not available on the boot with F8 screen, prompting several guides on creating an additional boot entry using BCDEDIT and chaning the properties via the Windows GUI — not much use if your machine has already run into trouble.

Shift+F8 is the secret key that gets the old boot options menu, with ‘Safe Mode’, but you need to hold it down during POST and keep holding it down until the “Advanced Boot Option” screen appears, otherwise you can’t time it right (unlike F8, or F10 below, which you just hit at the beginning of the boot).

Also the Edit Boot Options menu, available via boot with F10, is still available, and that allows low level control of all the boot options.

I couldn’t track down a current reference for the options, but did find one for Windows XP / Server 2003, most of which still appear relevant: http://support.microsoft.com/kb/833721

To get the same as ‘Safe Mode with Networking’:

  1. Press F10 while booting
  2. You should get a text screen titled “Edit Boot Options”, with a section “Edit Windows Boot options for: Windows Developer Preview”
  3. There should be an input area that already has “/NOEXECUTE=OPTIN” (in my case it also had “/HYPERVISORLAUNCHTYPE=AUTO”, which I think is because I am running Hyper-V)
  4. Add “/SAFEBOOT:NETWORK” (Note: “/NOGUIBOOT” doesn’t seem to work — it still shows the loading screen, so options like “/SOS” didn’t work)
  5. Hit ENTER to boot

Safe Mode is important for an early Developer Preview like this as drivers issues are much more likely (I ran into problems trying to add the NVIDIA drivers for my Alienware M14x and had to boot into safe mode to uninstall them).

1 Comment

Comparison of logging frameworks

I added a comparison of the major logging/tracing frameworks for .NET to the CodePlex site for Essential.Diagnostics, to demonstrate how System.Diagnostics stacks up against log4net, NLog and the Enterprise Library.

I also added a performance comparison (the source code is in the CodePlex project if you want to verify the results).

Look at the results for yourself, but I think System.Diagnostics does okay — and the extensions in Essential.Diagnostics (plus others such as Ukadc.Diagnostics and UdpPocketTrace) fill out the gaps compared to log4net and NLog. Similarly on the performance side, all have very little overhead (NLog is a winner on overhead, but does relatively worse on actually writing the messages to a log file).

What about the Enterprise Library Logging Application Block? Well, I just don’t think it does well compared to the others. Sure it was a lot better than .NET 1.0 System.Diagnostics, but a lot of that was added in .NET 2.0 System.Diagnostics (such as multiple sources). In some cases it is worse than what is currently available in the standard framework — e.g. no delayed formatting. This shows up in the performance figures which indicate several magnitudes greater overhead than any of the other frameworks!

I’m obviously biased, but I really think that the best solution is to stick with the standard, out-of-the-box, System.Diagnostics, extended where necessary to fill any gaps (Essential.Diagnostics, etc, for additional listeners, filters & formatting).

P.S. Also check out my guidance on Logging Levels.

Leave a comment

SharePoint 2010 logging levels

According to MSDN “in Microsoft SharePoint Foundation 2010 the preferred method of writing to the Trace Logs is to use the SPDiagnosticsServiceBase class” (http://msdn.microsoft.com/en-us/library/ff512746.aspx).

MSDN also provides some guidance on the trace and event log severity levels to use (http://msdn.microsoft.com/en-us/library/ff604025.aspx), however the WriteEvent() and WriteTrace() methods use slightly different enums; the diagnostics logging configuration in Central Administration is slightly different again, and then you have a third set of values accessed by the PowerShell command Get-SPLogEvent.

The table below shows the mapping of levels from these different sources.

Despite the complicated mapping, in general I think things go in the right direction with events writing to the event log and trace log at the same time, and having a high trace level. The distinction between event logging and trace information is also good, with independently set thresholds.

EventSeverity EventLogEntryType TraceSeverity ULSTraceLevel ULSLogFileProcessor
.TraceLevel
None = 0 None = 0 0 (None) Unassigned = 0
ErrorServiceUnavailable = 10 Error 1 Critical = 1 (or ErrorCritical)
ErrorSecurityBreach = 20
ErrorCritical = 30
Error = 40
Exception = 4
Assert = 6
Warning = 50 Warning 8 Warning = 8
FailureAudit = 60
Unexpected = 10 Unexpected = 10 Unexpected = 10
Monitorable = 15 Monitorable = 15 Monitorable = 15
SuccessAudit = 70 Information 18 Information = 18
Information = 80
Success = 90
Verbose = 100
High = 20 High = 20 High = 20
Medium = 50 Medium = 50 Medium = 50
Verbose = 100 Verbose = 100 Verbose = 100
VerboseEx = 200 VerboseEx = 200 VerboseEx = 200

Read the rest of this entry »

Leave a comment

Follow

Get every new post delivered to your Inbox.