Category Archives: Branding

Monkey Patching and SharePoint / Office 365

This post is a prelude for the one to follow in which I will show an application of this technique that overrides the workspace sizing routine in SharePoint 2010.

JavaScript is a wonderful language. It is easily accessible to anyone who understands C style syntax. This includes C# developers. However JavaScript is a dynamic language. In my experience most C# developers write poor JavaScript in a style that is appropriate to C#. However, getting the most out of SharePoint requires a good understanding of JavaScript and I am not talking about using jQuery or the Client Object Model. I am talking about fundamentals!

This is especially important if you are working in a sandbox environment like Office 365. It is very difficult (and often impossible) to fully achieve your UI goals given the restrictions of the sandbox architecture on the server side. However, with a good command of client side technologies, especially JavaScript, you can overcome many of these limitations.

The problem is that most of the really interesting components in SharePoint’s JavaScript libraries are undocumented. Furthermore, the chances are good that if you make heavy use of what I am about to show you, you will be disappointed when you have to fix your work when the next version of SharePoint drops and these undocumented libraries change. So, consider that fair warning – this is a powerful technique, but one with serious risks over time!

As Wikipedia tells us: ‘A monkey patch is a way to extend or modify the run-time code of dynamic languages without altering the original source code. This process has also been described as "duck punching".’

In JavaScript a function is a type and you can do things to functions that C# just doesn’t allow. You can assign them to variables, pass them as arguments, and even change their values.

For example (see it here on jsFiddle):

function sayHi() {
alert('Hi!');
}


function doFunction(func) {
func();
}


doFunction(sayHi);

 

 

This may be one of the longest Hello World style examples you can write! In it the function sayHi is invoked via the doFunction function by passing sayHi as an argument.

Now, imagine that sayHi is actually part of one of SharePoint 2010’s JavaScript libraries and you don’t like how it works. In a farm deployment scenario you could (but never, ever should) just open the file in the SharePoint root and change it. This is not an option in sandbox mode because you have no access to the actual script file. This is where monkey patching comes in.

Consider this example (see it here on jsFiddle):

function sayHi() {
alert('Hi!');
}


function doFunction(func) {
func();
}


var oldSayHi = sayHi;
sayHi = function() {
alert('What is the opposite of bye?');
oldSayHi();
}


doFunction(sayHi);

 

In this version the code copies the pointer to the original sayHi function into a new variable and then changes the value of the variable sayHi to a new function that shows a different alert before calling the original version and you get two alerts. This, in a nutshell, is what monkey patching is all about. With it you can replace an existing function completely or do custom pre/post processing as shown in the example above.

To get a feel for what you might do with this technique, add the following script via a Content Editor Web Part to the home page of a stock team site and then add a new Shared Document by clicking the link.

if (typeof NewItem2 != 'undefined') {
    var oNI2 NewItem2;
    NewItem2 this.NewItem2;
}


NewItem2 function(eventurl) {
    alert('NewItem2 called');
    oNI2(eventurl);
};

 

You should see something similar to the following.

For those of you who inherit nightmares because of misuse of this technique; I’m sorry!

Happy coding!
–Doug

Author: Doug Ware

SharePoint 2010 Fixed Width Master Pages Revisited

This post is an update to this post about fixed width pages I wrote when SharePoint 2010 was still in beta. If you follow the instructions in that post you’ll get a fixed width page, but it will have an unnecessary (and ugly) vertical scroll bar in the page’s main content area. The problem is in a function in init.js, FixRibbonAndWorkspaceDimensions. You can read about the work this function does in this post about ribbon positioning. FixRibbonAndWorkspaceDimensions does exactly what it says, but if you change the vertical layout of your page or add a footer it will give you fits. It does math and changes the size and position of various div elements independently of your CSS!

Here are the basic steps I use to create a fixed width page in the released versions of SharePoint Foundation and SharePoint Server 2010. You will almost certainly need to do more than this based on your specific design, but this should get you started. Note, this un-floats the ribbon. If you want to achieve the dynamic positioning FixRibbonAndWorkspaceDimensions provides, you’ll need to recreate it with your own script against your own element identifiers.

Find the following <DIV>

<div id="s4-workspace">

Change the id attribute to something else like:

<div id="my-workspace">

Add the appropriate styles to your CSS as follows:

<style type="text/css">

    body.v4master { 

        overflow:visible;

        background-color:blue

     }

     #my-workspace    

     {

        margin-left: auto; 

        margin-right: auto; 

        width: 960px;

    }

    #s4-mainarea

    {

        background-color: white;

    }

</style>

 

This is what it looks like on a stock Team site.

Author: Doug Ware

MSDN SharePoint Web Cast on Branding this Thursday

On Thursday, December 4, 2008 at 2:00pm EST, I will be doing a live MSDN Web Cast on .COM Branding.

The event is part of a larger series of 11 Web Casts about SharePoint Development that starts tomorrow and ends on January 15th, just in time for your holiday learning and reflection! You can signup and see the whole schedule here: http://www.microsoft.com/events/series/sharepointserver.aspx?tab=webcasts&id=liveall

This series is going to be great!

–Doug

Demystifying SharePoint CSS Links

There seems to be a lot of confusing, incomplete, or incorrect information (some of it from yours truly) out there about the choices available to you when the time comes to create your own styles or override existing ones so I thought I should shed a little light on the subject and talk about the Web Controls that actually emit said <Link> elements.

SharePoint:CssLink and CssRegistration

Have a look at the default.master page in the GLOBAL site definition (12TemplateGlobal). You’ll see a control named SharePoint:CssLink.

<HEAD runat="server">
    <META Name="GENERATOR" Content="Microsoft SharePoint">
    <META Name="progid" Content="SharePoint.WebPartPage.Document">
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    <META HTTP-EQUIV="Expires" content="0">
    <SharePoint:RobotsMetaTag runat="server"/>
    <Title ID=onetidTitle><asp:ContentPlaceHolder id=PlaceHolderPageTitle runat="server"/></Title>
    <SharePoint:CssLink runat="server"/>
    <SharePoint:Theme runat="server"/>
    <SharePoint:ScriptLink language="javascript" name="core.js" Defer="true" runat="server" />
    <SharePoint:CustomJSUrl runat="server" />
    <SharePoint:SoapDiscoveryLink runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderAdditionalPageHead" runat="server"/>
    <SharePoint:DelegateControl runat="server" ControlId="AdditionalPageHead" AllowMultipleControls="true"/>
</HEAD>

The CssLink Web Control renders <LINK> elements in this order:

  1. The primary CSS file (core.css)
  2. An optional CSS file specified by the control’s DefaultUrl property
  3. The value of the site definition’s AlternateCSS attribute if one exists. (If you are using the MOSS publishing features, you can also set this property for a single site by using the Site Master Page Settings page.)

Note that the AlternateCSS attribute affects every page in the site, even the application pages.

If you examine any of the master pages included in either of the MOSS publishing site definitions, you will see another control, SharePoint:CssRegistration.

For example, the following code comes from OrangeSingleLevel.master:

<Sharepoint:CssLink runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/~language/Core Styles/SingleLevel.css%>" runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/controls.css %>" runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/zz1_orange.css%>" runat="server"/>

The CssRegistration control adds each of the style sheets to an internal collection in the SPContext and the CssLink renders each of them in alphabetical order before rendering the primary, default, and alternate CSS links. If you want one of them to appear after core.css, set the DefaultUrl property of CssLink.

So, if you want to ensure that zz1_orange.css appears after core.css, you would change the above to match the following:

<Sharepoint:CssLink runat="server" DefaultUrl="<% $SPUrl:~SiteCollection/Style Library/zz1_orange.css%>"/>
<SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/~language/Core Styles/SingleLevel.css%>" runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/controls.css %>" runat="server"/>

It’s very easy to get confused by this because the CssRegistration controls are after CssLink, but they don’t render the links, CssLink does!

One advantage that the publishing definitions have over the WSS default.master is the $SPUrl expression that allows dynamic creation of the URL for sites under the root web that use the root web’s master pages. Unfortunately, while CssRegistration is part of the core Microsoft.SharePoint.dll, $SPUrl requires the publishing features of MOSS.

Theme

On either of these master pages, somewhere under SharePoint:CssLink is SharePoint:Theme. The Theme Web Control just renders a <LINK> to the current theme if one is applied (Default is actually the lack of a theme).

For example, here the rendered HTML source for a page on a site that has the Simple theme applied.

<link rel="stylesheet" type="text/css"

   href="/_layouts/1033/styles/core.css"/>

<link rel="stylesheet" type="text/css"

   id="onetidThemeCSS"

   href="/sites/y/_themes/simple/simp1011-65001.css"/>

Note that the href points, not to the 12 hive, but to the site’s _themes folder. When a user applies a theme, the themes files are copied to the site to allow customization.

Also note that like AlternateCSS, themes affect the application pages.

Summary

So, to summarize the rendering order on a MOSS publishing site page is:

  1. The CssRegistration entries in alphabetical order
  2. Core.css
  3. The value of the CssLink Web Controls DefaultUrl property if one is specified
  4. The AlternateCSS if one is specified
  5. The current theme if there is one

If you want to add your own HTML <LINK> by hand bypassing any of these and want to be sure it comes last, simply place it after both SharePoint:CssLink and SharePoint:Theme.

–Doug Ware

Author: Doug Ware

Using a Document Property as a Page Title

There are a few pages on this site located in a basic Web Part Page library that is cleverly named Webpart Pages. The default page title for these pages is ‘ListName – ItemName‘.

The code that does this is:

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

    <SharePoint:ListProperty Property="Title" runat="server"/> –

    <SharePoint:ListItemProperty Property="BaseName" MaxLength=40 runat="server"/>

</asp:Content>

If I left this alone and added a page named MyPage to the library, the page title will be Webpart Pages – MyPage.

The user will see this title on their browser’s title bar, but more importantly, the title will show up in any search engine results.

If you need more control you can add a column to the document library and use its contents instead. Add a column named PageTitle to the library and set it to whatever you want to display.

Change the code to:

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

    <SharePoint:ListItemProperty Property="PageTitle" MaxLength=40 runat="server"/>

</asp:Content>

As you can see, the SharePoint:ListItemProperty web control is a handy way to insert the value of any column in the current item wherever you need it in your page.

New eLumenotion SharePoint Skinner Setup

I just uploaded a new version of the installer. The program is the same and it will stay that way for a few more weeks at least. But, this version of the MSI should alleviate some of the issues people have reported with the Microsoft.mshtml assembly. The file is now installed locally instead of assuming it will be in the GAC. It turns out that machines without Visual Studio might not have the interop assembly and this caused a variety of errors that I could not reproduce because… I have Visual Studio.

Don’t you just love COM interop?

Introducing SharePoint Skinner!

NOTE: This is for the OLD version! For the new and far better version, see this post.

With the improvements to the security model in WSS 3.0 and the addition of blog and wiki site templates many more people are using SharePoint for public facing sites. Usually, they will want to brand the site and radically alter the look and feel of the site to make it look like something very different from the default often with the goal of obscuring the underlying SharePoint as much as possible. There are two common approaches to meeting this goal. You can use cascading style sheets and you can alter the actual pages via master pages and content pages. For a serious branding effort you will usually do both.

There are a number of approaches you can take to affect the styles. You can override styles using content editor, you can use the AlternateCSS attribute in the site’s definition, you can attach a style sheet using SharePoint Designer, you can place html <link> elements in your master pages, and you can create themes. Each of these approaches has its advantages and disadvantages depending on your requirements, but in my opinion the latter is the most robust option. I will expound on why I believe this in another post. The topic of this post is a tool I created to make skinning a site via css or a custom theme much easier.

If you have attempted to override the styles on an out of the box SharePoint site, you know that it isn’t a very easy thing to do.

The core.css file that contains the basic rules has 979 different style rules.

The core.css file uses a palette of 132 colors and 143 images.

The default page of a newly provisioned team site uses only 61 of those rules.

So, unless you have branded a lot of SharePoint sites and are intimately familiar with core.css and the default master pages and page layouts, just figuring out where to start modifying can be a daunting task. With SharePoint Skinner you can create new styles by altering existing styles in a WYSISWYG fashion. If you are not expert in writing CSS I recommend complimenting Skinner with a good style builder like the one included in most versions of Visual Studio including the free Visual Web Developer Express Edition. I also recommend the free Internet Explorer Developer Toolbar to help find those hard to locate style elements. Skinner includes an inspector tool that helps with this, but the toolbar is a great help when the built in inspector comes up short!

You can download the installer here. Once you’ve got it installed, come back and read the next posts to learn how to use it.

Author: Doug Ware