Showing posts with label SharePoint2010. Show all posts
Showing posts with label SharePoint2010. Show all posts

Jun 12, 2012

Working With Boolean (Checkbox) List Fields

While it is rather straightforward to retreive a value from a text field in code, the checkbox is a little bit more tricky, being a boolean field. 

Using boolean (checkbox) field in a CAML query 

To retreive items from a list with a CAML query, you use the elements <Eq> or <Neq>, as in equals to (Eq) or is not equal to (Neq), value. In Checkbox fields there is no actual value string touse in the CAML equasion, but the Value element is needed to state that the value is boolean, and thus the equal to comparison is made against TRUE/FALSE, namely whether value is false or not:
  • unchecked = false --> to retreive unchecked items, use <Eq>
  • checked = true --> to retreive checked items, use <Neq>
So the following CAML would return all the items where the NotDisplayed field ("Do not display in webpart") is not checked.

<Where><Eq><FieldRef Name='NotDisplayed'/><Value Type='Boolean'></Value></Eq></Where>

Using boolean (checkbox) field in code, to retreive or set the value

In your code you might need to determine whether the checkbox of a list item (or any list item) is checked or not in order to do something, e.g.

bool YesOrNoValue= (bool)item["YesOrNoField"];
if (YesOrNoValue == true)
{
   ...do something
}
else
{
   ...do something
}

If you need to retrieve the value to use it as a string, you need a slightly different approach:

SPFieldBoolean YesOrNo = item.Fields["Item value is yes?"] as SPFieldBoolean;
bool YesOrNoValue= (bool)YesOrNo.GetFieldValue(item["YesOrNoField"].ToString());

To set the checkbox value, you can use a simple

item["YesOrNoField"] = true;
item.Update();

May 8, 2012

That Darn Navigation!

Earlier, I have written about the two different global navigation controls that can be used in SharePoint 2010 MasterPages, the foundation (v4.master) version, and the publishing navigation. Essentially, they both come out the same, but then again not. In publishing navigation, you can quite easily hide the top level site link, as the site logo quite frequently serves that purpose and thus the link on navigation bar is most often more or less futile and takes up space. In the foundation navigation control, this cannot be done (as easily, maybe? so far I have not figured out a way).

Both controls can be used in any kind of MasterPages, whether targeted to publishing or foundation sites, as long as 
a) using the foundation navigation you are ok to display the top level site in the navigation or
b) using the publishing navigation you are either ok with always using the complete global navigation on team sites too, or configure the start node to be displayed and set the static display levels to 2 (otherwise the navigation will be empty when team sites don't use the navigation bar of parent site)

There is just one little problem with the publishing navigation, at least when using the CombinedNavSiteMapProvider, and same applies to GlobalNavSiteMapProvider. When using special characters, such as & marks in the site names, they get html encoded in the navigation bar,
e.g. Test & Try > Test &amp; Try

In the publishing sites, i.e. publishing site targeted MasterPages, you can alternately use the CurrentNavigation as the sitemap provider, which does not have this character problem, but with the foundation sites, this again causes a problem, as Lists, Libraries, Discussions etc. start invading the top navigation!

Finally, after testing out different providers, I found that one option is to revert back to the one used in MOSS 2007: the GlobalNavigation. It works both in foundation and publishing sites, and supports both the special characters and hiding the top level site. So far, I know of no actual problems with it, so here you go:

<publishingnavigation:portalsitemapdatasource id="topSiteMap" runat="server" enableviewstate="false"
              sitemapprovider="GlobalNavigation" startfromcurrentnode="true" startingnodeoffset="0"
              showstartingnode="false" trimnoncurrenttypes="Heading" />
          <!-- top navigation menu (set to use the new Simple Rendering) -->
          <SharePoint:AspMenu ID="TopNavigationMenuV4" runat="server" EnableViewState="false"
              DataSourceID="topSiteMap" AccessKey="<%$Resources:wss,navigation_accesskey%>"
              UseSimpleRendering="true" UseSeparateCSS="false" Orientation="Horizontal" StaticDisplayLevels="1"
              MaximumDynamicDisplayLevels="0" SkipLinkText="" CssClass="s4-tn">
          </SharePoint:AspMenu>

Mind, that if you want the team sites to use their own instead ot parent's navigation, you still ought to use e.g. the foundation navi control or set the attributes to this navigation as stated earlier.  

May 3, 2012

Creating a Metro Tile Web Part

Metro style is the hot topic right now, so it is only right to take a look at how to make your SharePoint site more Metro too. You can build Metro blocks in the Content Editor Web Part, of course, but wouldn't it be so much easier to manage the tile content if the data was in a SharePoint list instead of being static content in a CEWP?


What you need in your (Empty SharePoint project) is
  • a List Definition and a List Instance for your source list - and I took it one step further by creating the Content Type for the list as well
  • the WebPart
  • your own CSS stylesheet in the mapped _Layouts folder
I am not going to go step by step through the process of creating these elements. For more info on creating SharePoint projects, webparts, content types, stylesheets etc. please check out some of my previous posts, e.g. in categories WebPartsBranding and Customization.

There's a whole lot of little things to do to put the thing together, and I will walk through the main points here.

For the Content Type (or the List Definition, if you are not creating a Content Type), you need to add the list fields and field references in its Elements.xml file. I used four fields in addtion to the Title field:
  • tile icon url field
  • tile content note field, setting the parameter HTMLEncode="true" to enable HTML tags in the content
  • tile background color (text) field for the background color as HEX code
  • tile url field (used to create a link wrapper around the icon and title)
In the ListDefinition Schema file you need to add the field references to the default view (BaseViewID 1) to show them in the AllItems view of the list. With the Fields and FieldRefs, remember that whether the tag has an endind tag or not really is of essence:
  • in Content Type Elements.xml both the Field and FieldRef tags are one-piece, eg:
    <Field Name="TileLink" DisplayName="Tile Hyperlink" ID="{GUID here}" Type="URL" Required="true"/>
    and
    <FieldRef Name="TileLink"/>
  • in List Definition Schema.xml the FieldRef inside the Content Type element is as above, but the FieldRefs in the View elements are two-piece:
    <FieldRef Name="TileLink">
    </FieldRef>
Also, remember to check the titles, descriptions and urls for the ContentType, ListDefinition and ListInstance, as well as the Web Part too, of course.

Once the list is done (and tested), add the Layout folder mapping to your project, and an empty CSS stylesheet in the project folder inside Layouts.

Then, add the WebPart to your project. In the WebPart .cs file, inside the CreateChildControls method, you need to
  • add the CSS reference
    If you are not trying to override corev4.css, this simple line is fine:
    CssRegistration.Register("/_layouts/MetroTileWebPart/TileStyles.css");
    and as for this project, this goes fine, since only our own classes need to be used. But if you need to make sure that the CSS is read after the corev4.css, see this blog post for the instructions.
  • retrieve the list items
    SPSite thisSite = SPContext.Current.Site;
    SPWeb rootsite = thisSite.RootWeb;
    SPList tilelist = rootsite.Lists["MetroTilesList"];
    SPListItemCollection items = tilelist.GetItems();
  • loop through the items 
    A foreach loop is fine. 
  • get field values for each item
    For any e.g. string type data (here the color and the content) you can use:
    string tilecontent = item["TileContent"].ToString();
    But if you try this with the hyperlink fields, due to the Description field embedded in it, you will get a double hyperlink value, separated by a comma, and that won't work. So you need to use the SPFieldUrlValue to get only the url value:
    SPFieldUrlValue TileUrlvalue = new SPFieldUrlValue(item["TileLink"].ToString());
    string tileurl = TileUrlvalue.Url;
    As for the title, you can simply refer to it with item.Title.
  • and create the html for the webpart
    Using LiteralControls you can quite easily create the HTML for each tile, using the field values in the places needed:

And then you need to create the CSS for the classes. The key points in the CSS here being:
  • the main element here is the tilecontainer, and for this 3 in a row, my CSS rules for it are:
    width:30%;
    padding: 10px;
    float:left;
    margin: 5px; /* to create a consistent 10px space between tiles */
     
  • using the pseudo-element :nth-type-of(N), you can make the n:th (in this case the fourth) tile position itself neatly below the first tile instead of e.g. below the last tile of the row, if the tiles differ in height:
    div.tilecontainer:nth-of-type(3n+1) {clear: left;}
  • the background of the content span is white opaque so that it sits nicely with which ever color tile, but the IE7 and IE8 don't understand the rgba-rule, so I set the background as #dedede for them:
    background: rgba(255, 255, 255, 0.4);
    *background: #dedede;
Otherwise, the CSS is all about the positionings and colors and margins etc. of the contents of the tiles.

For more info on Metro style UX desing, see: http://msdn.microsoft.com/en-us/windows/apps/.

[See also: Add Properties to Your Web Part]

Apr 25, 2012

Tip of the Day: Intellisense for MasterPages

How ignorant can you sometimes feel? All the time while working with SharePoint 2010 MasterPages and PageLayouts in VisualStudio, for two years now, I have been cussing the lack of intellisense on those pages on a regural basis. I have even complained about this out loud and asked advice from others - never finding or getting any solution to this.

Then, only last Friday, I was helping out a guy who is relatively new to SharePoint branding and development etc. and had been trying out this and that in VisualStudio to help him get along - and avot! He had found the solution to the problem. Maybe it is old stuff to you already, but it was a life-saver for me!

In the Solution Explorer, right-click on the MasterPage/PageLayout file missing intellisense, select View Markup. That does it, pals!

Apr 24, 2012

Branding SharePoint - What, How, Why?

In our own SharePoint seminar Hyvät, pahat ja rumat (the good, the bad and the ugly) I gave a presentation on SharePoint Branding - what you can do and how you should do it. Many aspects of this topic I have covered in several posts in this blog from a quite technical perspective, jumping straight to how. Let's have a look at the what and why, and a bit more general how.

Why?

SharePoint out of the box is fully functional and ready to use from the UI perspective, too. But to be honest, it's not exactly pretty. Whereas the v4.master for team sites is maybe adoptable for a team site based intranet, the nightandday masterpage can really not be seen as anything else but an example of a publishing master. Neither one of them has the look and feel of the company implementing SharePoint, naturally. The best you can do without some sort of web development is use themes and change the logo, and save the site as template.

In most cases this is not enough. Even the intranet should look nice and reflect the company brand. Once I had made this branding solution to a company, the page all branded and looking nice, but when the customer representative first saw it, his first comment was: "That ribbon is the wrong color!" I changed the color of the ribbon row and he sighed: "Now it's feeling more homey." Despite what the IT guys and the developers might like to believe, branding is important, beyond the usability issues.

What?

SharePoint pages are HTML and CSS, just like any other web pages. It's got a whole lot of server side C# code and client side JavaScript in it, but as for the UI, it is (to be exact) XHTML (1.x) and CSS (2.1), and thus almost as customizable and flexible as web development in general. Almost. So why isn't any web developer capable of SharePoint branding? Because of the server environment, special functionalities and UI with the ribbon and webparts, and that server side code.

It is essential to understand the structure of SharePoint in order to understand what can be done, what not, and how to do it in a SharePoint way. You need to know about the SharePoint controls in order to know what to use and what to maybe ditch. You need to know that you can never ever delete the PlaceHolders from the masterpage (the what from where? - exactly! you need to know!). You need to know that there are limitations to the branding. E.g. webparts have a table-based HTML structure with a limited amount of unique IDs and as for the branding of web parts you are tied to this. You can go to an extent, but you may not be able realize all of the wild visions of the designer who knows nothing about the SharePoint limitations.

How?

Microsoft and several other instances promote SharePoint Designer a lot. But seriously: it is a good tool for e.g. external data connections, customizing list views on a specific page, creating a custom workflow etc. stuff for a single existing site, but it is not a branding tool when you want to have a managable branding solution that can easily be deployed in several site collections and not breaking with migration. For that, you really need a proper SharePoint branding solution made in a managable way in VisualStudio, deployed as a .wsp package, full with features.

A typical branding solution can contain:

Currently I still use XHTML and the CSS v2. There are a whole lot of IE7s still in use in the customer organizations, and even these web technologies create some problems with IE7 and require some specific CSS rules (instead of separate stylesheets, I prefer the * prefix to target IE7) in order to look like it should. HTML5 used in the way intended requires a whole lot of polyfills to work in older browsers, and CSS3 features are still partly browser tech dependent (i.e. webkit vs. moz) as is, so using those already means double work in many places, let alone targeting IE7, unless we simply decide the IE7 users be left with a less rich UI.

But, the future is in HTML5 and CSS3 plus JavaScript, so it's only a matter of time really. Mobile world is already there, more than the regular PC.

Some resources for browser compatibilities:

http://html5readiness.com/
http://mobilehtml5.org/
http://www.findmebyip.com/litmus/
http://www.quirksmode.org/m/table.html

Apr 16, 2012

A Consistent Breadcrumb Trail Experience

The breadcrumb trails in SharePoint 2010 can be a tricky thing for the designer creating a branding solution. I have written about this issue before, but have neglected to share my ultimate solution to it so far. A quick summary first:

In SharePoint 2010 the OOB Team site breadcrumb trail on the Browse Ribbon tab is formed by of two  separate PlaceHolders: PlaceHolderSiteName and PlaceHolderPageTitleInTitleArea. As for the Publishing sites, the OOB model is to only have the SiteName there. The full breadcrumb can of course be found in the "Folder" icon on the Ribbon. But as I have come to notice, customers are not happy about the lack of a proper always visible (except for the main page) breadcrumb trail. Maybe it is a matter of teaching new ways, but does the reason really matter? It is what people seem to like, and customers want, and it is doable. Really even in a quite simple way.

Combining the full breadcrumb (the same one used in MOSS 2007 too) and the PlaceHolderTitleInTitleArea, we can build a breadcrumb trail that is consistent througout the sites, independent of the site type. It provides a neat breadcrumb trail for Publiushing sites, but it also enables the additional menu functionality required for document libraries and lists. And the users never need to rethink their actions, breadcrumb is always in the same place.

This is how it works:

<asp:SiteMapPath
        id="ContentMap"
        SkipLinkText=""
        NodeStyle-CssClass="ms-sitemapdirectional"
        runat="server" RenderCurrentNodeAsLink="True" PathSeparator=" > " />
        <span> > </span>
        <asp:ContentPlaceHolder ID="PlaceHolderPageTitleInTitleArea" runat="server" />

The parameteres that you might want to change there are RenderCurrentNodeAsLink and the PathSeparator. Other possible parameters for the breadcrumb trail are (with example values):
  • RootNodeStyle-Font-Bold="true"
  • RootNodeStyle-Font-Names="Arial Black"
  • RootNodeStyle-Font-Italic="True"
  • RootNodeStyle-ForeColor="Green"
  • CurrentNodeStyle-ForeColor="Orange"
  • PathDirection="CurrentToRoot"
  • ShowToolTips="false"
But as you can see, most of the above are style-related, and thus better done by CSS than by using the parameters. 

The breadcrumb needs some styling anyway, in order to gain a consistent style. By default, it looks something like this:


But with some CSS styling, your breadcrumb might look e.g. like this:


The first part of the breadcrumb trail, the part that comes from the old SiteMapPath, you can manipulate simply by setting the style rules for links inside your breadcrumb container. The part that comes from the PlaceHolder uses these classes:
.ms-ltviewselectormenuheader .ms-viewselector a
and
.ms-ltviewselectormenuheader .ms-viewselectorhover a 
so you simply need to override their rules in your own CSS style sheet.

Mar 15, 2012

Boost Up Your SharePoint

Even though I am very much pro-wsp, that is, building (UI)stuff in SharePoint the "right way", in VisualStudio, and packaging it into a wsp with features, I acknowledge that there are cases and situations where it really is not in the customer's - the SharePoint holder's - best interest to do it the long and expensive way, but instead make a lightweight solution directly in the site.

This - tweaking, enhancing, boosting the existing environment - is what I talked about at Techdays Finland last week. The slideset (in Finnish) can be downloaded from the Techdays site, video will be available later on, and here is a summary in English.

The basic thing to understand is that SharePoint pages are built with html and css, just like other web pages. The frame of the page is the html - xhtml more specifically, unless html5 has already been implemented - of the Masterpage. This you cannot alter - nor any other existing html on the pages - but you can manipulate it with css, and you can add your own html on pages too. 

On a wiki page, the additional css and html are inserted straight to the page by editing the html of the page (you might want to convert it to xhtml first); no Web Parts are needed for this. You could even create your very own Text Layout inside the wiki page by using the One Column Text Layout and then creating your own divs (or table, if you wish) in the html editor. You can hide elements on the page, e.g. the left side navigation (see my earlier post on this) - use IE Developer Toolbar or Firebug etc. to find the elements - but you cannot add JavaScript on the page for SharePoint will rip it out.

(I did not show this own layout as a demo at Techdays - an hour is sooo short!)



Save your layout html (Save and Close, then return to edit mode) before inserting Web Parts in your own divs - otherwise SharePoint just might erase the whole html.

On these wiki page based sites such as Team Sites, you need to create a Web Part Page and use a Content Editor Web Part in order to be able to insert JavaScript on the site. This Web Part Page can be set as the home page of the site in Site Settings > Welcome Page (in Look & Feel category). Another suggested work-around is to add the Javascript references and functions to the page as a linked text file and then call them from the page html. I haven't explored this further myself.

On publishing pages any custom html, css or JavaScript needs to be inserted in a Content Editor Web Part. Then the contents can be edited in a similar way as the contents of a wiki page - except that SharePoint does a little less ripping, so JavaScript can be quite easily inserted too. In my session I demoed a couple different jQuery functionalities:
  • the tabbed or accordion UI (from jQuery UI)

With the jQuery UI, remember the Download tool for getting all the right bits and pieces, and themes too, without needing to copy everything manually!

These are only a couple examples. Exploring the jQuery site and the web more widely, you can find a whole lot of ideas and things to put on your site, and if you learn SharePoint Client Object Model, you can even use the SharePoint libraries and lists in custom functions, e.g. in a picture gallery as above.

Just remember: jQuery shoud be referred to only once per page, otherwise the whole thing goes berserk. See more about JavaScript and SharePoint in my earlier post on the topic. And check out the mobile comaptibility tables to see what the mobile devices support and what not! If you want to really make it happen for the mobile devices too, you might want to consider jQuery Mobile.

JavaScript you can add to pages as demonstrated above, or use it in Web Parts or application pages etc. created in VisualStudio, or add it to a site in an empty module and then delivere it as wsp solutions with features. With the css, you have the possibility to insert it on the page, deliver it in a UI solution or create something in between: an alternate stylesheet. With the alternate stylesheet you get the same css tweaks on every page of your site, or even site collection if you select to inherit the stylesheet  - and you can even manipulate the Web Apps page ribbon to an extent.

The Office Web Apps and Office Web Parts, such as Visio and Excel Web Parts, are more or less untouchables otherwise. You can do some little tricks to the toolbars with css, even with wsp-issued JavaScript, but that's pretty much it. The contents and their styles run down deep in the code, there's no changing e.g. the colors of the Excel chart in the Web Part. Simply does not happen.

The thing to remember with all these customizations is that they are more or less one-time-only. You can copy-paste your html, css, JavaScript etc. and store it in a text file to reuse it (and actually this is highly recommendable even if you only use them in that one site - it's better to edit the text file and then copy-paste it to the page again as it is than try to edit the html that SharePoint has already messed up), but still, it is not an easily maintained reusable content part like a Web Part. So think carefully where the line goes between tweaking and making it for good!

Mar 6, 2012

Tervetuloa TechDaysiin!

Sessioni TechDaysissa: SharePoint-sivujen ja Office-integroidun sisällön advanced muokkaaminen, pe klo 14:30


Tavataan Messukeskuksessa!

Feb 23, 2012

Using JavaScript in SharePoint Content

With JavaScript, you can boost up your SharePoint page content, take it from being text and images to something interactive and awesome, right? With jQuery it becomes even easier - someone else has already figured out the code, all you need is to copy-paste it to your site, right? More or less, yes. The potential is great, but, how should I put it? There's some quirks involved. (Anyone else having a dêja vu right here?)

Let us start at the beginning. The way to use JavaScript on a SharePoint page is to insert it in the HTML content of a Content Editor Web Part on the page. It works fine on publishing pages and web part pages, but if you try to insert the JavaScript code to the html of a wiki-page, say the home page of a team site, it won't fly. SharePoint edits the page html after you, and while it allows scripts in the html of CEWPs, it doesn't allow them in the wiki content. And it doesn't help to insert a CEWP on the wiki-page, for SharePoint, it does not function there.

We have got as far as understanding that JavaScript is ok in CEWPs. Let's say that you want to be using some jQuery and implement e.g.  three accordions on a single page. With jQuery you need to remember, that you are using a JavaScript library, that normally is referenced only once on a webpage. If you simply copy-paste the jQuery code bits and leave the jQuery reference in situ in all of them, you will run into problems. The browser gets confused and starts reacting funnily to the keyboard, e.g. refreshing a page with F5 might take you to a whole different page.

The thing to do, of course, is to have only one jQuery reference on the page, in the CEWP that the browser reads first, the rest of the CEWPs are able to to use this one reference after the first one makes sure the file gets loaded. Other approaches could be to insert the reference on the page in its own hidden CEWP, thus it is not attached to any single web part using it (and won't get removed if that specific web part gets deleted from the page). Or, if you are building your own master pages and know that you will need the jQuery library, you could insert it to the master pages as well. This might be risky, though, if the content editors creating the jQuery thing-a-ma-jiggies on the pages are not aware of the already existing jQuery reference.

As you go about the inserting some script in a CEWP, I highly recommend you to create a base text file of the scripts + styles + css/js references + the basic html, so that if anything goes wrong, you don't have to start from the scratch all over again. Maybe even include the contents of, say the accordion divs, in the file. When you need to update the content, update the text file and then copy-paste it to the CEWP all over again, deleting all the old stuff first. SharePoint reads the JavaScript when you save the page and inserts all the classes and whatnot that the script feeds to the HTML and for some reason, if you fiddle with the HTML content of the CEWP after SharePoint has fiddled with it, it is bound to break very easily.

One last tip: don't store your JavaScript files in a library that requires publishing and/or approval for the documents. This will only give you problems.

Despite all, have fun with JavaScript and SharePoint! They do work together after you tackle these small details.

Feb 10, 2012

Language Pack and corev4.css

One of the customers I've done a branding solution for very commonly uses monitors with the resolution of 1024x768. So the SharePoint site layout needed to be optimized for this 1024px width (actually, 1000px, for the scrollbar takes up the 24px or so). Things were tight, but ok, except for one tiny detail.

The topcontainer containing the organization logo, their intranet name and the social notification links broke to two rows in their environment, but not in ours. The cause of this was, I found out, the language specific corev4.css file. In the English (1033) one, the socialnotif width is 120px, but in the Finnish one (1035) it is double! So no wonder. This wasn't how I'd planned the layout!

Problem was of course solved easily as soon as I detected it. But note to self: never overlook the language pack - it changes more than just the language.

Feb 8, 2012

SharePoint Dialog Structure

I was working on our new website UI yesterday, and testing it on a site collection I had for some reason created as a Team Site. I know there are many who say this is the only correct way to do it, but I have never seen the point when the goal is a Publishing Site Collection. The publishing infrastucture works more flawlessly when the Site Collection is built on the Publishing Site template from the very beginning.

Yesterday I found one more reason to continue doing it the way I always have. A website is obviously built by using the publishing sites, publishing infrastructure, so within this test site of mine, I had activated the Publishing Infrastructure feature and created some Publishing sites to test the Page Layouts on. 

One of the things about websites and Foundation based intranet workspaces is that the latter are quite commonly scaling sites with no set width for the page content, whereas the websites and intranet publishing sites too are quite often fixed width sites. This more or less eliminates this problem I encountered yesterday, in most cases. So what was it, exactly?

To the point. When deploying the fixed width master pages to the Foundation based Site Collection, the dialog boxes, e.g. adding a new list item, acted funny, i.e. it used the fixed width of the general master page as the width for the content in the dialog box, while the box frame itself didn't seem to have any clue about the width of the contents. This problem does not exist with the scaling non-fixed width master pages. This problem also does not exist on fixed width sites in a Publishing Site Collection.

Of course I started to dig around a bit, and noticed that in a Foundation based Site Collection the dialog box is built using as many as two iFrames. And with this, if the content has a fixed width, the javascript detecting the needed frame size simply does not follow. Actually, I couldn't get it to follow completely properly (but getting a bit better result) even by changing the content width in dialogs to non-fixed, so some other publishing oriented css messes it up as well, but I didn't dig that far yesterday.

Yep, and the Publishing Site Collections? No iFrames, no problems.

Jan 19, 2012

Creating a Content Type for Custom PageLayouts

Even when you don't use any custom fields on your PageLayouts, and necessary if you do, it is worth its while to create a custom content type (or several, if you need to apply different fields to different PageLayouts) for your PageLayouts for several reasons:

  • custom content type enables grouping the PageLayouts in meaningful groups instead of the Custom group in the PageLayout menu
  • also, for content rollup with CQWP, with custom content type, it is possible to list only the pages that are of the specific content type
  • when using custom fields as well, it is possible to filter the content rollup by the custom field info

Creating the basic Content Type is a quick task. Add a new item to your SharePoint project, of the type Content Type:


Select then "Page Layout" as the base Content Type to inherit from, or one of your existing Content Types:


Edit the Elements.xml; change the Name, Group and Description to your liking.


If you want to create some custom fields for your content types, add the fields to the Elements.xml as Field-elements:


Generate GUIDs for the IDs of the fields.

Then add the field references to the Content Type FieldRefs. After that the Elements.xml should look something like this:


Now, to use this with your PageLayouts, first, set the Content Type of the PageLayout to your custom Content Type in the Elements.xml containing the PageLayout elements by setting the Content Type value and adding a PublishingAssociatedContentType-property with the ContentType ID to the file(s):


If you want to make it easier for the users to fill in the fields, add them to the PageLayout EditPanel:


FieldName gets the GUID ID you generated for the field. 

And maybe some information needs to be visible too, add those fields to the page html as well:


In edit mode, the page looks now like this: 


The Content owner is visible on page (and a bit stylized here):


(Page content from http://slipsum.com, my favorite Lorem Ipsum.)

Jan 18, 2012

Setting MasterPages to Sites Automatically

I have addressed this topic before in the article Automatize MasterPages in SiteDefinitions, but taking a little bit different viewpoint here, let's take a look at how to achieve this without custom Site Definitions. There are cases where custom Site Definitions are needed, of course, and in those cases, the feature stapling as described in the other article might be the way to go. Might be, I say, for it still isn't necessarily the best way, or needed, if the master pages are otherwise automatized throughout the Site Collection, as I will describe in this article.

For instructions on creating the basic custom UI solution, see Creating a Custom UI Solution for SharePoint.

With the masterpages done and other elements in order as well, it is time to deploy the solution. The solution contains a feature, and the activation of this feature will add the MasterPages and possible PageLayouts in the MasterPage Gallery of the SiteCollection, but unless we have a feature receiver to go with the feature, the rest is manual work.

To better understand the different MasterPages and their behavior on different types of sites, see About SharePoint 2010 MasterPages.

The first step for MasterPage automatization is to create a feature receiver that sets the MasterPages for the sites when feature is activated. Note, that if the feature is scoped as Web, it needs to be activated on each site separately. If it is scoped as Site, it is activated only once for the Site Collection and sets only the MasterPages of existing sites.

Add a feature receiver to the feature by right-clicking the feature > Add Event Receiver. Uncomment the FeatureActivated and FeatureDeactivated methods. For the FeatureActivated, insert the following code:


Note, that the MasterUrl sets the System Master and the CustomMasterUrl sets the Site Master. Foundation sites do not use the CustomMasterUrl at all, but it doesn't matter that it is set on those sites too.

For the deactivation method, copy-paste the same code, but change the MasterPages to e.g. v4.master and nightandday.master.

If we want to take this one step further, we can do some site identifying and set different MasterPages for different sites by their ID. E.g. the search site needs its own MasterPage, so we could add some code to the feature receiver so that it sets the search sites to use the custom search master, or if there is none, to keep using the default minimal.master:


You can check other site IDs e.g. in this article: Know the site template used for the SharePoint site.

Update your deactivation method likewise.

The feature receiver takes us as far as taking care of the existing sites. Next, let's take care of the new ones. Add an Event Receiver in your project:


Select Web Events, A site was provisioned:


Replace the default content of the method by the following code:


If you didn't use any ID-specific MasterPage settings in the feature receiver, you can disregard the if-else here too.

Creating a Custom UI Solution for SharePoint

To create a custom UI solution for SharePoint 2010, create a new project in VisualStudio2010, using the project template Empty SharePoint Project. Remebmer to set the Framework to 3.5!


Next steps are to the SharePoint SiteCollection you are using for testing, and to choose between Farm or Sandbox solution. I usually use the Farm Solution unless Sandboxing is required, because I prefer the Layouts folder for the stylesheets and images over the Style Library of an individual SiteCollection. Sandbox solution does not have access to the Layouts folder.

After the project has been created, add the mapping of the Layouts folder if you are creating a Farm solution:


or add a new module with the name StyleLibrary if you are creating a Sandbox solution:


Mapping the Layouts folder automatically creates a folder for your custom stylesheets etc. Inside this folder, create another one, Images.


The StyleLibrary module needs the same, so create a folder for your custom stylesheets, and one for the Images too. Also, delete the Sample.txt file from the module, it is not needed. 

Add a stylesheet to the UI.Assets folder, New Item > Style Sheet from the Web category:


If you are using the StyleLibrary, you need to check your Elements.xml now. The Module-node should look something like this:

Module Name="StyleLibrary" Url="style library"
File Path="StyleLibrary\Showcase.UI.Assets\SandboxSC.core.css" Url="StyleLibrary/Showcase.UI.Assets/SandboxSC.core.css"

When you add images in the Images folder, check your Elements.xml file if using the StyleLibrary. There should be a new File-element for each image, e.g.

File Path="StyleLibrary\Showcase.UI.Assets\Images\Logo.gif" Url="StyleLibrary/Showcase.UI.Assets/Images/Logo.gif"

Next let's add the MasterPages module. If you have installed the CKSDev tools, you can add a new CKSDev MasterPage (in this case, see more about using the CKSDev Starter Master Page), or add a new empty Module and name it MasterPages, in a similar way as the StyleLibrary module was added. Again, delete the Sample.txt file.

Add a starter MasterPage file to the module. You can use any OOB SharePoint MasterPage as a starting point (download a copy from the MasterPages Gallery), but I highly recommend to start with the a starter MasterPage from the Starter MasterPages by Randy Drisgill. There are starter files for publishing sites and foundation sites, pick the correct one for the correct purpose. 

To better understand the usage and inheritance of SharePoint 2010 MasterPages, see About SharePoint 2010 MasterPages.

After adding the first MasterPage, rename it if needed and then edit the Elements.xml file:


First thing to do with the newly added MasterPage is to create (or change) the custom CSS reference. In the starter MasterPages, this is ready for you:


When using the StyleLibrary, the reference would be like this:


Last thing before initial testing of the solution is to prepare our feature. Two things: rename it and set the scope. First rename the feature in the solution explorer, then double-click it to set the title and the scope:
  • Web, if the feature should be activated separately on each site - good for cases where not all sites need the same UI assets, or you want to activate the UI by using feature stapling with custom site templates
  • Site, if the feature should be used for the whole SiteCollection - only one activation required, for efficient use, create also a feature receiver and an event receiver for when sites are created

The base for the branding solution has now been laid.and the solution is ready to be tested. Right-click on the project name in the solution explorer and click Deploy. This both deploys the solution and activates the feature. When deploy is done, go to your site and set the MasterPage for the site - and start working with it! 

Since I do not use SharePoint Designer for any UI customizing, I need to deploy, re-deploy and so forth, the solution as I make changes. My method is to deploy the initial solution, as it is, and then start working with the sites in Firefox, using Firebug to try out the css when necessary before writing it in the css file. And of course the MasterPage needs a whole lot of html! The easiest way to apply changes to the SharePoint site after the initial deploy, is to use the Quick Deploy tool of the CKSDev tools.

When it is time to add PageLayouts, add a new module like with MasterPages. Download a copy of the most suitable OOB PageLayout from the MasterPages Gallery, and add the file to the module. Edit the Elements.xml; for one PageLayout should look something like this:


For information on creating a feature receiver and event receiver for a UI solution, see Setting MasterPages to Sites Automatically.

About SharePoint 2010 MasterPages

I seem to have dropped bits and pieces of information, here and there, on the MasterPages in SharePoint 2010 and where and how they are and ought to be used when creating a custom UI solution. Time for a summary, here's a few words about the MasterPage usage and inheritance.
  1. There are two different MasterPage settings: the site MasterPage and the system MasterPage
    • Site MasterPage is used by publishing sites
    • System MasterPage is used by foundation sites and e.g. list views also on publishing sites
  2. The two above can be the same, or they can be different, e.g. if the publishing sites have no or a custom left navigation (or the publishing site version of the left navigation), the list views and foundation sites need a master with the quicklaunch navigation
  3. If there is a special MasterPage for the TopLevelSite (e.g. intranet front page), which often is the case (when it is not sufficient to simply hide elements from a special front page PageLayout), set this one first, and then you will need to set the MasterPage separately for each second level site because of the inheritance behavior described below
  4. While all other sites are fine with these one or two masters, the search site needs its own, for by default it uses the minimal.master, so we need to have a custom MasterPage derived from the minimal.master in order to show all elements on the page as should be
  5. About the inheritance:
    • Publishing sites automatically inherit the MasterPage from its parent site
    • When the Publishing feature is turned on for a foundation site, it too inherits the (system) master of its parent site
  6. When activating the custom UI feature with a MasterPage-setting feature receiver, the MasterPages will be set for all existing foundation sites, but not the ones created after this
  7. The MasterPages are referenced in a feature receiver or event receiver as
    • Site Master : CustomMasterUrl
    • System Master: MasterUrl
As to how to create a custom UI solution, see Creating a Custom UI Solution for SharePoint
and for instructions on creating a feature receiver and event receiver for masterpages, see Setting MasterPages to Sites Automatically.

Jan 4, 2012

Building a Custom ContentQueryWebPart

Since I have just gone through building my first custom CQWP for a publishing site collection, step by step, thought I'd share some notes on it. It's basically really not too complicated, but it does have a few quirks to go with it.

ContentQueryWebPart uses two main xsl-files:
  • the ItemStyles.xsl for item templates
  • the contentquerymain.xsl for the outer templates
Most often what you would be interested in customizing, is the ItemStyles.xsl which is located in the Site Collection Style Library, in the XSL Style Sheets folder. This provides the templates for items in the query result, enabling you to e.g. add fields to show, alter the order of fields and add additional html and style classes to item templates. This, of course, requires knowledge of xsl, how deep depends on what you are trying to do.

The first thought might be "ok, I'll open the ItemStyles.xsl to SharePointDesigner and edit it". I say no, you don't. You open the ItemStyles.xsl to SharePoint Designer and copy all its content and paste it to an xsl file in VisualStudio. But wait! We're not that far along yet, so let's back up a bit.

Yes, the correct way to do this is to create a VisualStudio 2010 project and package it as a wsp solution package. So start by creating an Empty SharePoint (2010) Project (remember to check that your Framework is set to 3.5). 


Type a site to use as test site and select the solution type (either one is ok, sandbox or farm). Add a module (Add > New item) in the project:


Delete the Sample.txt file and add a new item to the module:


Note, the item added is xslt-file (from Data category), remember to change the file type to xsl, e.g. CustomItemStyles.xsl.

Open the Elements.xml file of the module and edit the module information by adding the Style Library as the Url for the module and XSL Style Sheets folder as the Url of the item:


Now it is time to locate the original ItemStyles.xsl and open it for editing in SharePointDesigner. There is no need to check it out since there is no need to edit it, simply copy the contents of the file and paste them to the xsl file just created in VisualStudio. VisualStudio will notify (as an error) that the named template OuterTemplate-etc. does not exist, but don't mind this. The OuterTemplates are defined in the contentquerymain.xsl, which will be available for the custom CQWP without needing to copy it to the project.

Now what we ought to do, is select one of the existing templates as the basis for the custom one - this saves a whole lot of work. So if you're not sure which is a good starting place, insert a CQWP on your site and try out the different OOB templates. Then locate the template you want to modify, copy the complete template tag and paste it on the xsl sheet as a new template tag. Modify it as you like - you can move the divs around and create your own (remember to assign a class for your div!), but be mindful to maintain the schema and general structure of the template!

Now, the item template being done, it is time to add the webpart in the project. The OOB CQWP does not know how to use the custom xsl and there is no way to implement it, so we need to create our custom CQWP as well. Add a SharePoint webpart item in the project:


You don't need the webpart's .cs-file, so you can delete that. Then open the browser again, add a new CQWP on a page and export the webpart without setting any properties. Once saved on your disc, open the webpart file and copy and paste its contents to the webpart file in VisualStudio, replacing the default content created by VS.

Change the title of your webpart:


Then locate the properties ItemXslLink and ItemStyle and set them to point to the custom xsl:


Yes, that's right: no slash between ~sitecollection and Style Library.

Furthermore, if you want to make things neat, you might want to change the category in which the webpart is found on the site. The deafult is Custom, but you can change it by opening the Elements.xml file of the webpart and typing your own group name:


Ok, now we're almost done. The last thing to deal with is the features. Adding the module created a feature and adding the webpart created another one. There is no need for two features, so you can delete the other one. The clue is to delete the right one. Double click on each feature to see its properties. The first one only contains the styles module, the second one shows both modules (although you need to add the styles module to the feature items). Delete the first one, and add the styles module to the other one. 

Also, you might want to rename the feature. One thing is to rename the feature in the feature properties and the other to rename the feature file in the solution explorer (right-click the feature > Rename). You might want to do both.


The final thing to do, is add a feature event receiver. Why? Because for some reason at least a publishing site collection otherwise refuses to let the custom CQWP use the custom xsl file, informing that it is not trusted. So this feature receiver corrects this problem by specifically assigning the sitecollection url for the webpart.

Right click your feature and add an Event Receiver to it. Open the event receiver for editing, uncomment the FeatureActivated method and add the following code to the method, changing the wp.File.Name value to your own webpart name.


(Thanks for the feature receiver goes to our coder, couldn't have come up with it myself!)

Note that you need to add the using statements for System.Linq and System.Text.

You're solution tree should now look like something this:



Now you are ready to package, deploy and test the webpart! 

Tip: If you need to do this more than once, which usually is the case, the easiest way to make it happen is to copy-paste the original xsl and webpart files to your disc drive (or such). Then you don't need to always do the same opening and copying all over again.

Dec 1, 2011

Design and Development in SharePoint Online vs. On-premises

And a little bit about planning the mobile sites as well. That was what I had a session about at the TechNet Helsinki 2011. You can find the presentation slides (.pdf) on the TechNet site (in Finnish) and the presentation video in Channel9 (also Finnish of course).

The important things to remember about SharePoint Online in sense of customizations, design, development, are that 1) there is no Farm Administrator role for the SP Online customer, only the SharePoint Online Administator, and 2) the things you can do with your SP Online site depend partly on the lisence you pay. So what it means, is that you are not able to install anything on the SharePoint server, nor change any server settings in SharePoint or IIS, and also that the license really does matter. Whereas of course, if you host your own SharePoint server, there are no such limitations. (See more about SharePoint Online licensing)

Customizations compared, in the browser your possibilities are equal with these two - and in a sense here lies the true power for SharePoint Online development: utilizing the power of the client! You can use e.g. JavaScript, including jQuery etc. in the browser, in Content Editor Web Part for example, but the real power comes with VisualStudio and the client object model.

With SharePoint Designer you can do a lot in both (including harm), but there already are some limitations to this in SP Online. The SP Online adminitrator has the most permissions to SPD, as well as the permission to grant or restrict the use of SPD (fortunately, by default, the admin is the only one who is allowed to use SPD). 

With VisualStudio (i.e. development tools and possibilities), you run into the most limitations. But don't let them fool you. There's a lot that can be done developmentwise with SharePoint Online too.
  1. The Sandbox model. It is a subset of the complete SharePoint develpment toolset. I doesn't allow you to deploy anything in the GAC, and it doesn't allow you to access any services. It can use a basic set of objects within the Site Collection. You can make your own web parts, access lists, handle events etc.
    Update (Dec. 8, 2011): As of this autumn, Business Connectivity Services (BCS) are available for developers in SharePoint Online (see more about SPO update and BCS & SPO)
  2. The client object model. This, since it is run on the client side, in many cases can pretty much cover the shortcomings of the Sandbox model when it comes to e.g. accessing external data and using web services. It includes .NET Framework Managed, JavaScript and Silverlight. 
So as a conclusion, combining both development models, you can have your SharePoint Online site customized pretty effectively. As for the SharePoint Designer, I generally don't recommend it as a tool for the things that can better be done in a controlled and managed way with development tools in SP Online anymore than on-premises. But it can be used by advanced power users for customizing list views, creating workflows, creating list templates in a more lightweight manner, possibly on top or in addition to what has been done by development tools, globally. And the latest addition to this is that from autumn 2011 on, Business Connectivity Services are available in SharePoint Online, and you can set them up in SPD unlike before.

For more information on both and the whole picture, see the TechNet Library article on SharePoint Online development.

So how to fit the mobile view into all this? What should you know and take into consideration when planning the mobile usage of your SharePoint site, whether it be Online or on-premises? There is a very good blog post on this subject by Mike Hacker, I won't go into as much detail here. But a couple thought on that subject here too.

First of all, you might want to evaluate the most probable mobile usage for your site. If it is all about team sites and document management, it is probably enough to enable mobile views in your SharePoint environment (enabled by default in SP Online) and make sure that all of the newly created list get mobile view activated as well (the default ones have this feature enabled by default but new ones don't).

If we are talking about a publishing site, or sites, the question of the mobile view, or mobile site, gets whole new angles. Should we force the complete web site to mobile users too (needs some adjustments on the server, so this is not supported in SP Online)? Or should we then create another css stylesheet for mobile users (which is probably the easiest way to make changes for the mobile users in terms of detecting the device, but then again doesn't give the mobile user a choice)? Or make a completely different set of masterpages? And what about our web parts? Are they mobile compatible?

Make it this way or that, my personal opinion is: give the users a choice. Don't force a mobile view on mobile users, thinking that you're doing them a favor by making browsing easier. Not all mobile users like mobile views. And even more so, there's a whole lot of mobile devices with approx 10" displays which is quite enough for a full scale web experience.  

With SharePoint Online - on on-premises with the default mobile view settings enabled - it depends a bit on the device which way it will show the site by deafult. As the user with the device, you can switch them either way by changing the ?Mobile= -parameter in the URL string. The zero is the full view, one is the mobile view. So e.g. http://url/?Mobile=1 would be the forces mobile version for the site, whereas http://url/?Mobile=0 would be the forced full version of the site.

Hmph. SharePoint Designer failed me (again) and the photographer was there to document the moment.