Branding SharePoint with Device Channels and Design Packages

Exclusive offer: get 50% off this eBook here
SharePoint 2013 WCM Advanced Cookbook

SharePoint 2013 WCM Advanced Cookbook — Save 50%

Over 110 recipes to engineer web content and master SharePoint 2013 with this book and ebook

$32.99    $16.50
by John Chapman | January 2014 | Cookbooks Enterprise Articles

In this article by John Chapman, author of the book SharePoint 2013 WCM Advanced Cookbook, we will cover packaging out-of-the-box branding elements and targeting the branding for specific devices. We will cover the following recipes:

  • Creating a device channel for mobile devices
  • Applying a master page to a device channel
  • Creating and exporting a design package
  • Importing and applying a design package
  • Importing a design package to all site collections with PowerShell
  • Listing the device channel master pages

(For more resources related to this topic, see here.)

With the 2013 release of SharePoint, Microsoft has added two new capabilities that assist with full-scale branding of SharePoint sites: device channels and design packages. A device channel uses the user agent of the web browser sending the incoming web request to determine which master page to render the content pages with. A common use of the device channels is to detect tablets and smartphones to use a more touch-friendly interface design. For instance, a device channel can be configured to look for an iPad in the following user agent to identify the iPad devices:

Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X)
AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0
Mobile/11B554a Safari/9537.53

Any portion of the user agent can be used for a device channel. It is important to be specific, but not too specific. Using iPad would apply to all the devices that specify iPad in their user agent, whereas iPad; U; CPU OS 7_0 would only apply to iPads running on iOS Version 7.0.

A design package is a SharePoint solution, packaged as a WSP file containing branding customizations, such as master pages and cascading style sheets. This provides a simple method of exporting a site design from one site and applying it to another. A design package will only contain items that are not default to SharePoint. Default items, such as the included master pages, will be referenced, but are not included as part of the package.

Prior to SharePoint 2013, packaged design solutions could only be created manually or with Visual Studio. Design packages allow any site collection administrator to create and apply packaged designs. This allows the site collection administrators to obtain packaged designs (from third parties, and so on) and apply them, without having to manually upload and configure each piece of the design.

Creating a device channel for mobile devices

One of the most common scenarios for using device channels is to identify the tablet and smartphone browsers. Applying a mobile-specific master page, when appropriate, can provide the users with a design that is more touch friendly and is laid out in a specific manner for smaller screens. In this recipe, we are going to create a device channel that will identify Android, iOS, BlackBerry, WebOS, and Windows mobile devices. There are hundreds of mobile-specific browsers that we can detect with the user agent. However, for this recipe we are going to keep it simple.

Getting ready

In order to view and modify the device channels for a SharePoint site, the SharePoint Server Publishing Infrastructure site collection feature and SharePoint Server Publishing site feature must be activated.

How to do it...

Follow these steps to create a device channel for mobile devices:

  1. Navigate to the site in your preferred web browser.
  2. Select Site settings from the Settings menu.
  3. Select Device Channels from the Look and Feel section.

    You can also navigate to the Device Channels page from the Design Manager page.

  4. Select New Item.
  5. Provide a Name, Description, and Alias for the device channel.

    The Alias field specified will be used when specifying which master page to use with the device channel in the device channel mappings file. We will learn about this in the next recipe, Applying a master page to a device channel.

  6. Specify the Device Inclusion Rules to be included in the device channel.

    Android

    iPad

    iPod

    iPhone

    BlackBerry

    IEMobile

    WebOS

  7. When using multiple device inclusion rules, place each string on a new line to match the user agent. Device Inclusion Rules are simply strings that are looked for in the user agent of incoming web requests.

  8. Mark the Active checkbox and click on Save.

How it works...

Device channels are created and stored in the /DeviceChannels SharePoint list in the root site of a site collection. When an incoming browser request is received, SharePoint checks whether the incoming user agent matches any of the Device Inclusion Rules before selecting the master page to use.

Many web browsers have developer tools that allow changing the user agent reported by the browser. Switching the user agent is one way in which we can test to ensure our device channels are working correctly. Internet Explorer 11, for instance, includes this option in the Emulation section of the F12 Developer Tools.

There's more...

A device channel may also be created with PowerShell or with code using the server-side object model.

Creating a device channel for mobile devices using PowerShell

Follow these steps to create a device channel for mobile devices using PowerShell:

  1. Get the site using the Get-SPWeb Cmdlet.

    $web = Get-SPWeb http://sharepoint/site

  2. Get the DeviceChannels list.

    $list = $web.Lists["Device Channels"]

  3. Add a new SPListItem item to the Items collection of the list.

    $item = $list.Items.Add()

  4. Assign the values to each of the properties on the SPListItem item.

    $item["Name"] = "PowerShell" $item["Alias"] = "PowerShell" $item["Description"] = "PowerShell Channel" $item["Device Inclusion Rules"] = "Android`niPad`niPod`niPhone`nBlackBerry
    `nIEMobile`nWebOS"
    $item["Active"] = $true

    When a line break is required within a string, in PowerShell, an escape character can be used. Escape characters in PowerShell use the tilde character. For example, a new line is represented by `n.

  5. Call the Update method on the list to update the Items collection.

    $item.Update()

  6. Use the Dispose method to discard the SPWeb object.

    $web.Dispose()

Creating a device channel for mobile devices with code using the server-side object model

Follow these steps to create a device channel for mobile devices with code using the server-side object model:

  1. Open the site collection containing the site in a using statement.

    using (var site = new SPSite("http://sharepoint/site"))

  2. Open the site in a using statement.

    using (var web = site.OpenWeb())

  3. Get the DeviceChannels list.

    var list = web.Lists["Device Channels"];

  4. Add a new SPListItem item to the Items collection of the list.

    var item = list.Items.Add();

  5. Assign the values to each of the properties on the SPListItem item.

    item["Name"] = "Code"; item["Alias"] = "Code "; item["Description"] = "Code Channel"; item["Device Inclusion Rules"] = "Android\niPad\niPod\niPhone\nBlackBerry
    \nIEMobile\nWebOS"; item["Active"] = true;

    When a line break is required within a string in C#, an escape character can be used. Escape characters in C# use the backslash character. For example, a new line is represented by \n.

  6. Call the Update method on the list to update the Items collection.

    item.Update();

See also

Applying a master page to a device channel

Once a device channel has been created, it can be configured to use as a different site master page rather than the default site master page. For instance, browsers targeted by a mobile device channel could display the content using the oslo master page whereas all other browsers could display the same content using the seattle master page.

The System Master Page is configured for all device channels and cannot be configured for individual device channels.

How to do it...

Follow these steps to apply a master page to a device channel:

  1. Navigate to the site in your preferred web browser.
  2. Select Site settings from the Settings menu.
  3. Select Master page from the Look and Feel section.
  4. Specify which Site Master Page to use for each device channel.

  5. Click on Save.

How it works...

The master page to device channel mappings are stored in the _catalogs/masterpages/__DeviceChannelMappings.aspx file as XML within the root site of a site collection. For each incoming browser web request, this file is used by SharePoint to determine which master page to use with the content returned to the browser.

There's more...

A device channel mapping may also be configured with PowerShell or with code using the server-side object model. In this recipe, these two methods are similar. However, the .NET reflection methods used are slightly different. When an object is instantiated with reflection in PowerShell, its public properties and methods become available to the command line. However, when an object is instantiated with reflection in the .NET code, each property and method needs to be searched for before being able to access them.

The methods that provide the functionality to configure the device channel mappings are not publicly exposed in the SharePoint assemblies. As a result, we will use the .NET reflection to instantiate the objects required. It is important to note that non-public classes in the SharePoint assemblies can change between SharePoint versions and updates without notice. Using reflection tools, such as .NET Reflector (http://www.red-gate.com/products/dotnet-development/reflector/) and dotPeek (http://www.jetbrains.com/decompiler/), we can browse the assemblies to adjust the references accordingly.

Applying a master page to a device channel using PowerShell

Follow these steps to apply a master page to a device channel using PowerShell:

  1. Load the Microsoft.SharePoint.dll and Microsoft.SharePoint.Publishing.dll assemblies into the PowerShell session.

    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.Publishing.dll")

    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.dll")

  2. Get the object types for the parameters that will be used when getting the class constructor for the MasterPageMappingsFile object and later instantiating the object.

    $typeWeb = [Microsoft.SharePoint.SPWeb] $typeBool = [System.Boolean]
    $typeMappingFile =
    [System.Type]::GetType("Microsoft.SharePoint.Publishing.Mobile.
    MasterPageMappingsFile, Microsoft.SharePoint.Publishing,
    Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e942
    9c")

  3. Create an array of the object types.

    $consMappingFileParams = ($typeWeb, $typeBool, $typeWeb)

  4. Get the class constructor for the MasterPageMappingsFile object.

    $consMappingFile = $typeMappingFile.GetConstructor($consMappingFileParams)

  5. Create an array of the parameters required to instantiate the MasterPageMappingsFile object.

    $mappingFileParams =
    [System.Array]::CreateInstance([System.Object], 3)
    $mappingFileParams[0] = (Get-SPSite
    http://sharepoint/sitecollection).RootWeb
    $mappingFileParams[1] = $false
    $mappingFileParams[2] = $null

    When invoking a constructor to create an instance of a .NET object in PowerShell, we have to create a System.Object array rather than using a PowerShell array. Even though the base class for a PowerShell array is System.Object[], when calling the Invoke method on the class constructor, it will see it as a PSObject object instead. The same goes for the SPWeb object we are passing as the first parameter. .NET will see the object as a PSObject object instead of a SPWeb object if we use Get-SPWeb. However, if we get the SPWeb object from the SPSite object, it will not get treated as a PSObject object.

  6. Invoke the class constructor to create an instance of the MasterPageMappingsFile object.

    $mappingFile = $consMappingFile.Invoke($mappingFileParams)

  7. Set the MasterPageUrl property for the device channel on the MasterPageMappingsFile object.

    $mappingFile["PowerShell"].MasterPageUrl = "/_catalogs/masterpage/oslo.master"

  8. Save the changes using the UpdateSingleChannel method.

    $mappingFile.UpdateSingleChannel("PowerShell")

Applying a master page to a device channel with code using the server-side object model

Follow these steps to apply a master page to a device channel with code using the server-side object model:

A reference to the Microsoft.SharePoint.Publishing.dll assembly is required for this recipe.

  1. Get the site collection in a using statement.

    using (var site = new SPSite("http://sharepoint/sitecollection"))

  2. Get the root site of the site collection in a using statement.

    using (var web = site.RootWeb)

  3. Get the object type that will be used when getting the class constructor for the MasterPageMappingsFile object and later instantiating the object.

    MasterPageMappingsFile object and later instantiating the object.
    var typeMappingFile =
    Type.GetType("Microsoft.SharePoint.Publishing.Mobile.
    MasterPageMappingsFile, Microsoft.SharePoint.Publishing,
    Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e942
    9c");

  4. Get the class constructor for the MasterPageMappingsFile object.

    var consMappingFile =
    typeMappingFile.GetConstructor(new Type[] { typeof(SPWeb),
    typeof(bool), typeof(SPWeb) });

  5. Invoke the constructor to create an instance of the MasterPageMappingsFile object.

    var mappingFile = consMappingFile.Invoke(new object[] { web, false, null });

  6. Get the mappings field of the MasterPageMappingsFile object, and cast the field as an IDictionary.

    var mappings = (IDictionary)typeMappingFile.GetField("mappings",
    BindingFlags.Instance | BindingFlags.NonPublic).
    GetValue(mappingFile);

  7. Set the MasterPageUrl property for the device channel on the mappings field.

    mappings["PowerShell"].GetType().GetProperty("MasterPageUrl",
    BindingFlags.Instance |
    BindingFlags.Public).SetValue(mappings["PowerShell"],
    "/_catalogs/masterpage/seattle.master", null);

  8. Set the mappings field of the MasterPageMappingsFile object.

    typeMappingFile.GetField("mappings", BindingFlags.Instance |
    BindingFlags.NonPublic).SetValue(mappingFile, mappings);

  9. Get the UpdateSingleChannel method from the type of the MasterPageMappingsFile object.

    var updateMethod = typeMappingFile.GetMethod("UpdateSingleChann
    el",
    BindingFlags.Instance | BindingFlags.Public, null, new Type[]
    { typeof(string) }, null);

  10. Save the changes by invoking the UpdateSingleChannel method.

    updateMethod.Invoke(mappingFile, new object[] { "Code" });

See also

SharePoint 2013 WCM Advanced Cookbook Over 110 recipes to engineer web content and master SharePoint 2013 with this book and ebook
Published: January 2014
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

Creating and exporting a design package

Design packages in SharePoint 2013 allow us to package our customized branding from one SharePoint site and apply it to another. Design packages can include:

  • Device channels
  • Design files stored in _catalogs/masterpage/
  • Master pages
  • Display templates
  • Page layouts

When a design package is created, it will only include the preceding elements that were customized or added. It will not include the items that come by default with SharePoint. In this recipe, we will cover how to create a design package from a site that is already customized.

How to do it...

Follow these steps to create and export a design package:

  1. Navigate to the site in your preferred web browser.
  2. Select Site settings from the Settings menu.
  3. Select Design Manager from the Look and Feel section.

  4. There are eight steps present on the left-hand side of the page to manage every aspect of the SharePoint site design customizations that will be included in the design package. Perform each step to verify that the elements are being included in the site design package.

  5. Select the final step 8. Create Design Package as shown in the previous screenshot.
  6. Provide a Design Name.
  7. Select Create. Creating the design package may take some time depending on the amount of customizations being included and the server resources.
  8. Once complete, click on the link to download the design package.

How it works...

When creating a design package, each site design customization is reviewed in the wizard steps. These design customizations include master pages, page layouts, device channels, and design files (cascading style sheets, images, JavaScript, and so on). The design customizations are then packaged in a SharePoint solution file (WSP). These SharePoint solutions are sandboxed solutions that allow the site collection administrators to upload and deploy them rather than requiring a farm administrator.

There's more...

A design package may also be exported with PowerShell or with code using the server-side object model.

Creating and exporting a design package using PowerShell

Follow these steps to create and export a design package using PowerShell:

  1. Load the Microsoft.SharePoint.dll and Microsoft.SharePoint.Publishing.dll assemblies into the PowerShell session.

    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.Publishing.dll")
    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.dll")

  2. Get the site collection using the Get-SPSite Cmdlet.

    $site = Get-SPSite http://sharepoint/sitecollection

  3. Create the design package using the Export method of Microsoft.SharePoint.Publishing.DesignPackage.

    $package =
    [Microsoft.SharePoint.Publishing.DesignPackage]::Export($site,
    "My PowerShell Design", $false)

  4. Get the filename using the specified format and design the package details.

    $fileName = "{0}-{1}.{2}.wsp" –f ($package.PackageName,
    $package.MajorVersion, $package.MinorVersion)

  5. Get the SPFile object representing the design package WSP file from the RootWeb property of the SPSite object.

    fileBinary = $site.RootWeb.GetFile("/_catalogs/solutions/" +
    $fileName).OpenBinary()

  6. Use System.IO.FileStream to save the contents of the SPFile object to the local filesystem.

    $fileName, [System.IO.FileMode]::OpenOrCreate,
    [System.IO.FileAccess]::Write)
    $fileStream.Write($fileBinary, 0, $fileBinary.Length)
    $fileStream.Close()

  7. Use the Dispose method to discard the SPSite object.

    $site.Dispose()

Creating and exporting a design package with code using the server-side object model

Follow these steps to create and export a design package with code using the server-side object model:

A reference to the Microsoft.SharePoint.Publishing.dll assembly is required for this recipe.

  1. Get the site collection in a using statement.

    using (var site = new SPSite("http://sharepoint/sitecollection"))

  2. Get the root site of the site collection in a using statement.

    using (var web = site.RootWeb)

  3. Create the design package using the Export method of Microsoft.SharePoint.Publishing.DesignPackage.

    var package = DesignPackage.Export(site, "My Code Design", false);

  4. Get the filename using the specified format and design the package details.

    var fileName = string.Format(CultureInfo.InvariantCulture,
    "{0}-{1}.{2}.wsp", package.PackageName, package.MajorVersion,
    package.MinorVersion);

  5. Get the SPFile object representing the design package WSP file from the RootWeb property of the SPSite object.

    var fileBinary = web.GetFile("/_catalogs/solutions" + filename).OpenBinary();

  6. Use System.IO.FileStream to save the contents of the SPFile object to the local filesystem.

    var fileStream = new FileStream("C:\\" + fileName, FileMode.OpenOrCreate, FileAccess.Write); fileStream.Write(fileBinary, 0, fileBinary.Length); fileStream.Close();

See also

Importing and applying a design package

With SharePoint 2013, a user only needs to be a site collection administrator to apply a packaged design rather than be a farm administrator. This offloads the burden of applying site collection level designs from farm administrators and makes it simpler for site collection administrators to obtain packaged designs from third parties and apply them.

How to do it...

Follow these steps to import and apply a design package:

  1. Navigate to the site in your preferred web browser.
  2. Select Site settings from the Settings menu.
  3. Select Import Design Package from the Look and Feel section.

  4. Select the design package to import.
  5. Select Import.

How it works...

Importing a design package adds the SharePoint solution file (WSP) to the Solutions Gallery of the site collection and applies the customizations it contains. These SharePoint solutions are sandboxed solutions that allow the site collection administrators to upload and deploy them rather than requiring a farm administrator.

There's more...

A design package may also be imported and applied with PowerShell or with code using the server-side object model.

Importing and applying a design package using PowerShell

Follow these steps to import and apply a design package using PowerShell:

  1. Load the Microsoft.SharePoint.dll and Microsoft.SharePoint.Publishing.dll assemblies into the PowerShell session.

    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.Publishing.dll")
    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.
    SharePoint.dll")

  2. Get the site collection using the Get-SPSite Cmdlet.

    $site = Get-SPSite http://sharepoint/sitecollection

  3. Specify the path to the design package WSP file and get the file name from the path.

    $filePath = "C:\My PowerShell Design-1.0.wsp" $fileName = [System.IO.Path]::GetFileName($filePath)

  4. Create a DesignPackageInfo object to represent the design package we are about to upload. In the constructor, specify the major and minor version of the design package.

    $package = New-Object
    Microsoft.SharePoint.Publishing.DesignPackageInfo($fileName,
    [Guid]::Empty, 1, 0)

  5. Create a temporary folder in the RootWeb site to upload the design package to:

    $tempFolderName = "temp_designupload_" + ([Guid]::NewGuid).ToString() $tempFolder = $site.RootWeb.RootFolder.SubFolders.Add($tempFolderName)

  6. Use the OpenRead method of System.IO.File to read the contents of the design package WSP file and add the file to the Files collection of the temporary folder.

    $fileBinary = [System.IO.File]::OpenRead($filePath) $file = $tempFolder.Files.Add($fileName, $fileBinary, $true) $fileBinary.Close()

  7. Use the Install method of Microsoft.SharePoint.Publishing.DesignPackage to add the design package to the Solutions Gallery and apply the customizations in the design package to the site collection.

    [Microsoft.SharePoint.Publishing.DesignPackage]::Install($site,
    $package, $file.Url)

  8. Delete the temporary folder.

    $tempFolder.Delete()

  9. Use the Dispose method to discard the SPSite object.

    $site.Dispose()

Importing and applying a design package with code using the server-side object model

Follow these steps to import and apply a design package with code using the server-side object model:

A reference to the Microsoft.SharePoint.Publishing.dll assembly is required for this recipe.

  1. Get the site collection in a using statement.

    using (var site = new SPSite("http://sharepoint/sitecollection"))

  2. Get the root site of the site collection in a using statement.

    using (var web = site.RootWeb)

  3. Specify the path to the design package WSP file and get the file name from the path.

    var filePath = "C:\My Code Design-1.0.wsp"; var fileName = Path.GetFileName(filePath);

  4. Create a DesignPackageInfo object to represent the design package we are about to upload. In the constructor, specify the major and minor versions of the design package.

    var package = new DesignPackageInfo(fileName, Guid.Empty, 1, 0);

  5. Create a temporary folder in the RootWeb site to upload the design package to.

    var tempFolderName = "temp_designupload_" + Guid.NewGuid().ToString(); var tempFolder = web.RootFolder.SubFolders.Add(tempFolderName);

  6. Use the OpenRead method of System.IO.File to read the contents of the design package WSP file and add the file to the Files collection of the temporary folder.

    var fileBinary = File.OpenRead(filePath); var file = tempFolder.Files.Add(fileName, fileBinary, true); var fileBinary.Close();

  7. Use the Install method of Microsoft.SharePoint.Publishing.DesignPackage to add the design package to the Solutions Gallery and apply the customizations in the design package to the site collection.

    DesignPackage.Install(site, package, file.Url);

  8. Delete the temporary folder.

    tempFolder.Delete();

See also

SharePoint 2013 WCM Advanced Cookbook Over 110 recipes to engineer web content and master SharePoint 2013 with this book and ebook
Published: January 2014
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

Importing a design package to all site collections with PowerShell

Applying a design package to a large number of site collections can be a tedious task. To expedite the process, we can use PowerShell. In this recipe, we are going to use a PowerShell script (PS1) to upload and apply a design package to each content site collection in each web application on the local SharePoint farm.

How to do it...

Follow these steps to import a design package to all site collections with PowerShell:

  1. Open your preferred text editor to create the PS1 script file.
  2. Load the Microsoft.SharePoint.dll and Microsoft.SharePoint.Publishing.dll assemblies into the PowerShell session.

    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.Publishing.dll")
    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.dll")

  3. Specify the path to the design package WSP file and get the filename from the path.

    $filePath = "C:\My PowerShell Design-1.0.wsp" $fileName = [System.IO.Path]::GetFileName($filePath)

  4. Create a DesignPackageInfo object to represent the design package we are about to upload. In the constructor, specify the major and minor versions of the design package.

    $package = New-Object
    Microsoft.SharePoint.Publishing.DesignPackageInfo($fileName,
    [Guid]::Empty, 1, 0)

  5. Create a temporary folder name to upload the design package in each site collection.

    $tempFolderName = "temp_designupload_" + ([Guid]::NewGuid).ToString()

  6. Use the OpenRead method of System.IO.File to read the contents of the design package WSP file and add the file to the Files collection of the temporary folder.

    $fileBinary = [System.IO.File]::OpenRead($filePath)

  7. Use a foreach loop to iterate through each content SPWebApplication on the local SharePoint farm using the Get-SPWebApplication Cmdlet.

    foreach($webApp in (Get-SPWebApplication))

  8. Use a foreach loop to iterate through each SPSite Cmdlet in the Sites property of the SPWebApplication object.

    foreach($site in $webApp.Sites)

  9. Verify the CompatibilityLevel property of the SPSite object to ensure it is in SharePoint 2013 (Version 15) mode and not in SharePoint 2010 (Version 14) mode.

    if ($site.CompatibilityLevel –eq 15)

  10. Using the following command, create a temporary folder in the RootWeb site to upload the design package:

    $tempFolder = $site.RootWeb.RootFolder.SubFolders.Add($tempFolderName)

  11. Add the file to the Files collection of the temporary folder.

    $file = $tempFolder.Files.Add($fileName, $fileBinary, $true)

  12. Use the Install method of Microsoft.SharePoint.Publishing.DesignPackage to add the design package to the Solutions Gallery and apply the customizations in the design package to the site collection.

    [Microsoft.SharePoint.Publishing.DesignPackage]::Install($site,
    $package, $file.Url)

  13. Delete the temporary folder.

    $tempFolder.Delete()

  14. After the foreach loops are completed, close the design package WSP file.

    $fileBinary.Close()

  15. Use the Dispose method to discard the SPSite object.

    $site.Dispose()

  16. Save the file as a PS1 file, for example, importdesignpackage.ps1.
  17. Execute the script in the PowerShell session.

    ./importdesignpackage.ps1

How it works...

PowerShell provides a scripting environment that can simplify repetitive administrative tasks. Using PowerShell, we are able to use a combination of the Cmdlets provided and the .NET code to iterate through each site collection in each web application to import and apply our design package.

In this recipe, we used the Get-SPWebApplication Cmdlet to retrieve all of the content web applications on the local SharePoint farm. We then iterated through each site collection in the Sites property of each web application. For each site collection, we uploaded the design package to a temporary folder. Lastly, we installed the design package to each site collection from the temporary folder.

There's more...

This recipe may also be accomplished with code using the server-side object model.

A reference to the Microsoft.SharePoint.Publishing.dll assembly is required for this recipe.

Follow these steps to import and apply a design package to all site collections using the server-side object model:

  1. Specify the path to the design package WSP file and get the filename from the path.

    var filePath = "C:\My Code Design-1.0.wsp"; var fileName = Path.GetFileName(filePath);

  2. Create a DesignPackageInfo object to represent the design package we are about to upload. In the constructor, specify the major and minor versions of the design package.

    var package = new DesignPackageInfo(fileName, Guid.Empty, 1, 0);

  3. Create a temporary folder name to upload the design package in each site collection.

    var tempFolderName = "temp_designupload_" + Guid.NewGuid().ToString();

  4. Use the OpenRead method of System.IO.File to read the contents of the design package WSP file and add the file to the Files collection of the temporary folder.

    var fileBinary = File.OpenRead(filePath);

  5. Use a foreach loop to iterate through each content SPWebApplication on the local SharePoint farm.

    foreach(var webApp in SPWebService.ContentService.WebApplications)

  6. Use a foreach loop to iterate through each SPSite in the Sites property of the SPWebApplication object.

    foreach(SPSite site in webApp.Sites)

  7. Verify the CompatibilityLevel property of the SPSite object to ensure it is in SharePoint 2013 (Version 15) mode and not in SharePoint 2010 (Version 14) mode.

    if (site.CompatibilityLevel == 15)

  8. Create a temporary folder in the RootWeb site to upload the design package to.

    var tempFolder = site.RootWeb.RootFolder.SubFolders.Add(tempFolderName);

  9. Add the file to the Files collection of the temporary folder.

    var file = tempFolder.Files.Add(fileName, fileBinary, true);

  10. Use the Install method of DesignPackage to add the design package to the Solutions Gallery and apply the customizations in the design package to the site collection.

    DesignPackage.Install(site, package, file.Url);

  11. Delete the temporary folder.

    tempFolder.Delete();

  12. Discard the SPSite object using the Dispose method.

    site.Dispose();

  13. After the foreach loops are completed, close the design package WSP file.

    fileBinary.Close();

See also

Listing the device channel master pages

Identifying the master pages used by each device channel for each site in a SharePoint farm can be cumbersome. Using PowerShell, the administrators are able to quickly iterate through each site to accomplish this. In this recipe, we are going to use a PowerShell script (PS1) to output the device channels and master pages configured for each site in a site collection.

How to do it...

Follow these steps to list the device channel master page configurations for each site in a site collection with PowerShell:

  1. Open your preferred text editor to create the PS1 script file.
  2. Load the Microsoft.SharePoint.dll and Microsoft.SharePoint.Publishing.dll assemblies into the PowerShell session.

    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.Publishing.dll")

    [Reflection.Assembly]::LoadFrom("C:\Program Files\Common
    Files\microsoft shared\Web Server
    Extensions\15\ISAPI\Microsoft.SharePoint.dll")

  3. Get the site collection using the Get-SPSite Cmdlet.

    $site = Get-SPSite http://sharepoint/sitecollection

  4. Get the object types for the parameters that will be used when getting the class constructor for the MasterPageMappingsFile object and later instantiating the object.

    $typeWeb = [Microsoft.SharePoint.SPWeb]
    $typeBool = [System.Boolean]
    $typeMappingFile =
    [System.Type]::GetType("Microsoft.SharePoint.Publishing.Mobile.
    MasterPageMappingsFile,
    Microsoft.SharePoint.Publishing, Version=15.0.0.0,
    Culture=neutral,
    PublicKeyToken=71e9bce111e9429c")

  5. Create an array of the object types.

    $consMappingFileParams = ($typeWeb, $typeBool, $typeWeb)

  6. Get the class constructor for the MasterPageMappingsFile object.

    $consMappingFile = $typeMappingFile.GetConstructor($consMappingFileParams)

  7. Create an array of the default parameters required to instantiate the MasterPageMappingsFile object.

    $mappingFileParams = [System.Array]::CreateInstance([System.Object], 3) $mappingFileParams[1] = $false $mappingFileParams[2] = $null

  8. Use a foreach loop to iterate through each SPWeb in the AllWebs property of the SPSite object.

    foreach ($web in $site.AllWebs)

  9. Add the SPWeb object to the parameters array and invoke the constructor to create an instance of the MasterPageMappingsFile object.

    $mappingFileParams[0] = [Microsoft.SharePoint.SPWeb] $web $mappingFile = $consMappingFile.Invoke($mappingFileParams)

  10. Output the master page settings for the default channel.

    Write-Host "" Write-Host "Site: " $web.Url Write-Host "Device Channel: Default" Write-Host "Master Page: " $web.CustomMasterUrl

  11. Use a foreach loop for each device channel key in the Keys collection of the mapping file.

    foreach ($key in $mappingFile.Keys)

  12. Output the master page settings for the device channel.

    Write-Host "" Write-Host "Site: " $web.Url Write-Host "Device Channel: " $key Write-Host "Master Page: " $mappingFile[$key].MasterPageUrl

  13. Use the Dispose method to discard the SPWeb object.

    $web.Dispose()

  14. Use the Dispose method to discard the SPSite object.

    $site.Dispose()

  15. Save the file as a PS1 file, for example, getdevicechannels.ps1.
  16. Execute the script in the PowerShell session.

    ./getdevicechannels.ps1


How it works...

Using .NET reflection we are able to interact with the private methods and classes in the SharePoint assemblies that provide the mapping information of the device channel. In this recipe, we used .NET reflection to instantiate the MasterPageMappingsFile object for each site in the AllWebs property of the site collection we obtained with the Get-SPSite Cmdlet. From the MasterPageMappingsFile object, we were able to output the master page configured for each device channel. In addition, we output the default master page configured for each site.

There's more...

This recipe may also be accomplished with code using the server-side object model.

A reference to the Microsoft.SharePoint.Publishing.dll assembly is required for this recipe.

Follow these steps to list the device channel master page configurations for each site in a site collection using the server-side object model:

  1. Get the site collection with a using statement.

    using (var site = new SPSite("http://sharepoint/sitecollection"))

  2. Get the object type that will be used when getting the class constructor for the MasterPageMappingsFile object and later instantiating the object.

    MasterPageMappingsFile object and later instantiating the object.
    var typeMappingFile =
    Type.GetType("Microsoft.SharePoint.Publishing.Mobile.
    MasterPageMappingsFile,
    Microsoft.SharePoint.Publishing, Version=15.0.0.0,
    Culture=neutral, PublicKeyToken=71e9bce111e9429c");

  3. Get the class constructor for the MasterPageMappingsFile object.

    var consMappingFile = typeMappingFile.GetConstructor(new Type[]
    {typeof(SPWeb), typeof(bool), typeof(SPWeb)});

  4. Use a foreach loop to iterate through each site in the AllWebs property of the site collection.

    foreach (var web in site.AllWebs)

  5. Ensure that the site exists.

    if (web.Exists)

  6. Invoke the constructor to create an instance of the MasterPageMappingsFile object.

    var mappingFile = consMappingFile.Invoke(new object[] { web, false, null });

  7. Output the master page settings for the default channel.

    Console.WriteLine(""); Console.WriteLine("Site: " + web.Url); Console.WriteLine("Device Channel: Default"); Console.WriteLine("Master Page: " + web.CustomMasterUrl);

  8. Get the mappings field from the mapping file and cast the object as an IDictionary.

    var mappings =
    (IDictionary)typeMappingFile.GetField("mappings",
    BindingFlags.Instance |
    BindingFlags.NonPublic).GetValue(mappingFile);

  9. Use a foreach loop for each device channel key in the Keys collection of the mappings dictionary.

    foreach (var key in mappings.Keys)

  10. Get the master page URL from the mappings dictionary.

    var mappingObject = mappings[key];
    var masterUrl =
    (string)mappingObject.GetType().GetProperty("MasterPageUrl",
    BindingFlags.Instance |
    BindingFlags.Public).GetValue(mappingObject, null);

  11. Output the master page settings for the device channel.

    Console.WriteLine(""); Console.WriteLine("Site: " + web.Url); Console.WriteLine("Device Channel: " + key); Console.WriteLine("Master Page: " + masterUrl);

  12. Use the Dispose method to discard the SPWeb object.

    web.Dispose();

See also

Summary

In this article we covered how to create a device channel for mobile devices, applying a master page to a device channel, creating and exporting a design package, importing and applying a design package, importing a design package to all site collections with PowerShell, and listing the device channel master pages.

Resources for Article:


Further resources on this subject:


About the Author :


John Chapman

John Chapman  is a software developer and designer, living in the Denver area, who specializes in SharePoint and .NET. Having worked in the higher education and telecommunications industries, he is now working as a software engineer for Sitrion, formerly NewsGator. He is working on the Social Sites product. Social Sites is the premier enterprise social software for Microsoft SharePoint.

John holds a B.S. and M.S. in Graphic Information Technology from Arizona State University. For more information about John Chapman, visit  http://www.sharepointjohn.com.

Books From Packt


 Microsoft SharePoint 2010 Developer’s Compendium: The Best of Packt for Extending SharePoint
Microsoft SharePoint 2010 Developer’s Compendium: The Best of Packt for Extending SharePoint

 SharePoint Designer Tutorial: Working with SharePoint Websites
SharePoint Designer Tutorial: Working with SharePoint Websites

 Microsoft SharePoint for Business Executives: Q&A Handbook
Microsoft SharePoint for Business Executives: Q&A Handbook

 Microsoft SharePoint 2010 End User Guide: Business Performance Enhancement
Microsoft SharePoint 2010 End User Guide: Business Performance Enhancement

 Microsoft SharePoint 2010 Administration Cookbook
Microsoft SharePoint 2010 Administration Cookbook

Learning Search-driven Application Development with SharePoint 2013
Learning Search-driven Application Development with SharePoint 2013

Microsoft SharePoint 2010 and Windows PowerShell 2.0: Expert Cookbook
Microsoft SharePoint 2010 and Windows PowerShell 2.0: Expert Cookbook

 Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook
Microsoft SharePoint 2010 Development with Visual Studio 2010 Expert Cookbook


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software