Intro to SharePoint 2013 Design Manager

The Design Manager is a new tool in SharePoint 2013.  It’s available when you use the Publishing Portal site template or activate the Publishing Infrastructure feature at the site collection level.  This tool’s purpose is to give users a new and easy way to brand SharePoint.  The goal was to allow designers to create the look and feel for a SharePoint site using the tools they are most comfortable with like Dreamweaver or
Visual Studio.

Here’s a quick tour of the Design Manager in SharePoint 2013.

Welcome

The Welcome page gives you a quick intro message and some links to learn more information, import a finished design package or pick one of the new looks provided out of the box.

Design Manager - Welcome

Manage Device Channels

A new concept in SharePoint 2013, the Device Channels allow you to target areas of content on your pages for specific devices.  By using something called the user agent, SharePoint know what device you are using and can use that information to perform different tasks.  In this case it will use that information to show areas of content you have targeted towards a specific device.  An example could be that you know one device allows for Flash content, but others don’t.  Put that content in a Device Channel so that it only renders on the device where it will work.  This page allows you to create new or edit existing channels.

Design Manager - Manage Device Channels

Upload Design Files

This page is pretty straight forward.  There is some info letting you know that you can map a network drive to the master page gallery and use it through Windows Explorer.  WebDAV is now enabled for the master page gallery as a new feature, which makes this possible, unlike in previous versions.

Design Manager - Upload Design Files

Edit Master Pages

This is the page you will use the most.  After you have uploaded your source files you will come here to convert the HTML page to your new master page through the conversion wizard.  By clicking on the “Convert an HTML file to a SharePoint master page link” you will be prompted with a series of screen that allow you to select the HTML file you want to convert.  After the conversion is done you can perform other actions like publishing a major version from the list.  If there were any issues with the conversion the status will indicate that you need to review your file.  The ellipses have replaced the down arrow icon used in previous versions of SharePoint.  Click on it to see other options available with your file.

The ability to create a master page from scratch has also gotten easier with SharePoint 2013.  By clicking on the “Create a minimal master page” link, you can create a bare-bones master page.  This is also a good way to see what you should be doing in your html files to create place holders for the SharePoint specific elements like the navigation bar and main content area.

Design Manager - Edit Master Pages

Edit Display Templates

Display templates are new in SharePoint 2013 and are a huge topic for discussion.  For this article I will just say that they are used for formatting search related web parts and search results.  From this page you can copy an existing one and modify it to suit your needs.  We’ll dive into this deeper in another post.

Design Manager - Edit Display Templates

Edit Page Layouts

Page layouts are still around in SharePoint 2013.  The new feature provided by the Design Manager is that you can use an HTML page like you did with the master page.  There are some SharePoint specific lines of code that you need to have you page render correctly.  We’ll cover that later.  The quickest way to see that code is to use the “Create a page layout” link.  Give your new page a name, pick a master page to associate it with and click Create.  Once the new file is created you can click on the ellipse and download a copy to your local drive.  When you open up the file to edit you will see all of the code that was added to your page layout file to correctly render it in SharePoint 2013.

If you already have your page layouts created you can upload or save them directly to the master page gallery and SharePoint will convert them.  Once converted they will appear on this page.  Be sure to put your page layouts in the same folder as your master page so that you can easily find them later.

Design Manager - Edit Page Layouts

Publish and Apply Design

From the publish and apply design page you are given a link to go and finally apply the brand you have created.  Then hope everyone likes it Smile

Design Manager - Publish and Apply Design

Create Design Package

The ability to move your design between environments is made easier with the create design package page.  Simply enter a package name and whether to include search configuration with it and click Create.  The create process will take all of your files and package them up nicely in a wsp file1.  Once it is ready you are provided with a link to download the file.  Notice that the file is also saved into the solutions store at the site collection level.  This makes it easy to move it to Office 365.

1 Something to note about this feature is that it is going to package up all of the design files you have added.  This may not be optimal for your environment so the packaging may need to be done outside of the UI.

Design Manager - Create Design Package

Hopefully this gets you excited about the new functionality available in SharePoint 2013 Design Manager! 

Add Options to a Select with SPServices and jQuery

Recently I was tasked with do a project that had some strict guidelines on what I could do for development on a site. Using best practices I would have typically create a solution in Visual Studio and deployed items to the SharePoint farm. In this case I was only allowed to use scripting and SharePoint Designer to accomplish my tasks. With the help of the CQWP, ItemStyle.xsl, jQuery and SPServices, I was able to provide all of the functionality requested.

For this particular task I needed to add options to a select control from a list. The fields I needed from my list included the Title and a Managed Metadata column. The Managed Metadata column was not multi-select in this case, but it could be accomplished as well with a little bit of different parse to get a value for the options. To accomplish this task I added a HTML form web part and put the following code into the Source Editor.

<!-- Show a progress image -->
<img id="progressbar" src="/_layouts/Images/CRPERSPC.GIF" />

<!-- Place holder for dropdown -->
<div id="office_wrapper">
	<select id="office_dropdown"></select>
</div>

<!-- References to jQuery and SPServices files -->
<script type="text/javascript" src="/Style%20Library/Scripts/jquery-1.7.2.min.js" language="javascript"></script>
<script type="text/javascript" src="/Style%20Library/Scripts/jquery.SPServices-0.7.1a.min.js" language="javascript"></script>

<!-- Script to get list items -->
<script language="javascript" type="text/javascript">

	// Get list items from the list by GUID (This can be easily found by looking at the list setting
	// and grabbing the ID from the URL in the browser.  Replace the %2D with dashes.)
	// In this example we will grab from a list in a different site collection
	$().SPServices({
		operation: "GetListItems",
		webURL: "http://mywebsite/sites/MyListSource/",
		async: false,
		listName: "{Enter List GUID here}",
		CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='MyTerms' /></ViewFields>",
		completefunc: function (xData, Status) {
			// To see the raw output from the response for debugging you can uncomment below
			//alert(xData.responseXML.xml);
			if (Status == "success") {
			
				// Perform the action for each row returned
				$(xData.responseXML).SPFilterNode("z:row").each(function() {
				
					// Append the html into the place holder for the dropdown. I set the option value to the term
					// in a Managed Metadata column and the visible text to the Title column
					$("#office_dropdown").append("<option value='" + $(this).attr("ows_MyTerms").split('#')[1] + "'>" + $(this).attr("ows_Title") + "</option>")
				});
			}
			// You can add a case for failure as well. Maybe logging or some sort of notification
			
			// Hide the progress bar image once the request is done
			$("#progressbar").hide();
		}
	});
	
	// Set the onchange event for the new dropdown
	$("#office_dropdown").change(function() { checkSelected(); });
	
	// Run the onchange event to perform any default actions necessary
	checkSelected();
	 
	function checkSelected() {
		// You could use the value of the dropdown in another SPServices request
		// here or just perform some other code
	}
</script>

<!-- You could add some styling here -->
<style>
	#office_wrapper {
		padding: 10px 12px 10px 0px;
	}
</style>

Now I have a select control with options added and an onchange event tied to it. For my task I was actually making another call with SPServices in the onchange event to get more information.

There are quite a few things here that I would do differently if I have access to deploy a farm solution, but this accomplishes everything I needed. By exporting the web part I was able to add it into the web part gallery on other site collections and reuse it. It is able to go across site collections since I set the “webURL” parameter which is very useful.

Hope this helps you get some cool designs in place for your site!

New Book – Deploying Cloud-Based Microsoft® SharePoint® 2010 Solutions

I helped write a chapter on planning for SharePoint Online in this new book.  The book is available on O’Reilly’s web site.  Here is the direct link.  It is in their Rough Cuts format right now until it is complete around the beginning of October.  This book is great for companies and developers that are looking to utilize SharePoint Online as a solution.  Phil Wicklund is the main author and other contributors are Eric Hanes, Brian Nielsen and Faraz Khan.  Go check it out!

Here are the details

Title:
Deploying Cloud-Based Microsoft® SharePoint® 2010 Solutions
By:
Phil Wicklund
Publisher:
Microsoft Press
Formats:
  • Print
  • Safari Books Online
  • Rough Cut
Print:
September 2011 (est.)
Rough Cut:
August 2011
Pages:
400 (est.)
Print ISBN:
978-0-7356-6210-0 | ISBN 10:  0-7356-6210-X
Rough Cut ISBN:
978-0-7356-6399-2 | ISBN 10:  0-7356-6399-8

PowerShell To Update All Sub-Site’s Master Page To Parent Master Page in SharePoint 2010

Here are some helpful PowerShell scripts you can use to list the Title, URL and WebTemplate for each sub-site in a site collection. I modified this to clean up each SPWeb object and it is based on this script from Geoff Varosky.

$site = Get-SPSite YourSiteCollectionURL
foreach ($web in $site.AllWebs) { 
	$web | Select-Object -Property Title,Url,WebTemplate
	$web.Dispose()
}
$site.Dispose()

Once I was able to verify all of the WebTemplates in use in my site collection I created a script to update all sub-sites to inherit the parent Site Master Page, System Master Page and Alternate CSS URL. Something that the script does is assign a value to the corresponding properties before setting the AllProperties inherit setting. When I attempted to just set the inherit setting it would update in the UI, but SharePoint didn’t know the actual value to apply for the master pages and css url so that is why I set each property to the parent site’s value first. If anyone knows of a better way then I’m always open to learning! You should also note that I’m filtering out any of the various search templates because I have a different master page I’m assigning to those.

Start-SPAssignment -Global
$site = Get-SPSite YourSiteCollectionURL
$topWeb = Get-SPWeb $site.Url
$site | Get-SPWeb -limit all | ForEach-Object {if (($_.WebTemplate -ne "SRCHCEN") -and ($_.WebTemplate -ne "SRCHCENTERLITE") -and ($_.WebTemplate -ne "SRCHCENTERFAST")) {$_.CustomMasterUrl = $topWeb.CustomMasterUrl;$_.AllProperties["__InheritsCustomMasterUrl"] = "True";$_.MasterUrl = $topWeb.MasterUrl;$_.AllProperties["__InheritsMasterUrl"] = "True";$_.AlternateCssUrl = $topWeb.AlternateCssUrl;$_.AllProperties["__InheritsAlternateCssUrl"] = "True";$_.Update();}}
Stop-SPAssignment -Global

Be sure you test this out in your dev environments first and be aware that there can be performance issues associated with running this against large production sites. The script is created to bring back every sub-site so you may not notice anything in a dev environment with only a few sites. PowerShell will also warn you that you are returning more than the default limit for Get-SPWeb.

Hope this is helpful!

Custom Activity for SharePoint Designer 2010 Workflow – Get Email Body

I had a requirement to get information out of an email body that was saved in an email enabled list. The customer preferred not to go with 3rd party software at the present time due to budget and time constraints. I was able to create a simple custom activity for SharePoint Designer 2010 using Visual Studio 2010.

The activity takes in the Encoded Absolute URL for the Current Item and uses that to read the file saved in a document library into a string variable in SharePoint Designer. From there you can perform other tasks like parsing out information from the variable.

Here is what the code looks like:

using System;
using System.ComponentModel;
using System.Workflow.ComponentModel;
using System.IO;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;

namespace StringActivities
{
	public partial class ParseEmail : Activity
	{
		public ParseEmail()
		{
			InitializeComponent();
		}

		public static DependencyProperty EncodedURLProperty = DependencyProperty.Register("EncodedURL", typeof(string), typeof(ParseEmail));
		public static DependencyProperty EmailBodyProperty = DependencyProperty.Register("EmailBody", typeof(string), typeof(ParseEmail));

		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public string EncodedURL
		{
			get
			{
				return (string)base.GetValue(EncodedURLProperty);
			}
			set
			{
				base.SetValue(EncodedURLProperty, value);
			}
		}

		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public string EmailBody
		{
			get
			{
				return (string)base.GetValue(EmailBodyProperty);
			}
			set
			{
				base.SetValue(EmailBodyProperty, value);
			}
		}

		protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
		{
			SPSecurity.RunWithElevatedPrivileges(delegate()
			{
				string content = string.Empty;
				
				using (SPSite oSite = new SPSite(EncodedURL))
				{
					 using (SPWeb oWeb = oSite.OpenWeb())
					 {
						  SPFile file = oWeb.GetFile(EncodedURL);
						  using (StreamReader reader = new StreamReader(file.OpenBinaryStream()))
						  {
								content = reader.ReadToEnd();
						  }
					 }
				}

				this.EmailBody = content;
			});

			return ActivityExecutionStatus.Closed;
		}

		protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
		{
			try
			{
				((ISharePointService)executionContext.GetService(typeof(ISharePointService))).LogToHistoryList(
					 base.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowError, 0,
					 TimeSpan.MinValue, string.Empty,
					 string.Format("Error occured when performing ParseEmail with URL " + this.EncodedURL + ": {0}", exception.Message), string.Empty);

			}
			catch (Exception ex)
			{ }
			return base.HandleFault(executionContext, exception);
		}
	}
}

Always be sure to test out the code in a development environment before using it in a production environment.

Hope this helps you get a start on some SharePoint 2010 Workflows!

Here’s a link to download a WSP file that includes the Get Email Body action and 2 others you might find useful.

– Update – 8/29/11 –
Note that the SPSecurity object is referenced so that requires that the solution be globally deployed.