By: TwitterButtons.com

Recent blog posts

User login

Home | Blogs | Stephane Eyskens's blog

Customizing the master page of Office 365 public site

When you have an Office 365 environment, you can decide to create a public facing site, meaning that your visitors won't need to be authenticated to visit this site.

This public facing site will most of the time show information about your company, describe your services etc...

By default, the public facing site looks more or less like this

If you have enough permissions, you'll be able to amend the logo, the company name and a few other information.

However, if you want to go further in terms of customization, you'll quickly be brought to customize the master page and this is where things become more complicated.

When opening your public facing site with SharePoint Designer, you'll notice that your default page points to root.master that is deployed at the root of the site collection.

If you try to modify root.master, you will encounter the following error:

no matter which change you're trying to apply. This is because the file becomes customized and therefore falls under the rules of the web.config of the corresponding web application which does not allow the use of the class whose the master page derives from.

So, here are some tracks demonstrating how you can achieve some customization. Note that I'm only going to focus on the plumbing since my design skills are incredibly poor. Here are the steps I made in order to make something work (door is now opened to make something nice)

1) Take a copy of minimal.master that's located under _catalogs/masterpage
2) Get rid of everything you don't need. In my case, to ease the process, I removed almost everything and ended up with the following:

<%@ Master Language="C#" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" 
  Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities"
  Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %> 
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
  Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="wssuc" TagName="Welcome" src="~/_controltemplates/Welcome.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="MUISelector" src="~/_controltemplates/MUISelector.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="<%$Resources:wss,language_value%>" xmlns:o="urn:schemas-microsoft-com:office:office" 
  runat="server" dir="<%$Resources:wss,multipages_direction_dir_value%>" __expr-val-dir="ltr">
<head runat="server">
<link rel="stylesheet" href="/css/mystyles.css"/>
<SharePoint:RobotsMetaTag runat="server"></SharePoint:RobotsMetaTag>
</head>
<body onload="javascript:if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();">
	<form runat="server" onsubmit="if (typeof(_spFormOnSubmitWrapper) != 'undefined') {return _spFormOnSubmitWrapper();} else {return true;}">
	<asp:ScriptManager
          id="ScriptManager"
          runat="server"
          EnablePageMethods="false"
          EnablePartialRendering="true"
          EnableScriptGlobalization="false"
          EnableScriptLocalization="true" />
	<WebPartPages:SPWebPartManager id="m" runat="Server"/>
	<SharePoint:FormDigest runat="server"/>		
	   <table>
		<tr>
		 <td>
		 	<div id="leftcomponents" class="leftcolumn">
			 	<asp:ContentPlaceHolder id="PlaceHolderLeft" runat="server" />
		 	</div>
		 </td>
		 <td>
		 	<div id="maincontent" class="centralcolumn">
				<asp:ContentPlaceHolder id="PlaceHolderMain" runat="server" />
			</div>
		 </td>
	       </tr>
	    </table>	
	</form>
</body>
</html>

Once done, you can change the master page pointer from your default page (or just create a new page) so that our custom master page is launched. Here is a very basic code for default.aspx:

<%@ Page language="C#" MasterPageFile="~site/365.master"    
  Inherits=
"Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"
  meta:progid="SharePoint.WebPartPage.Document"  %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
  Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities"
  Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
  Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceHolderId="PlaceHolderLeft" runat="server">
Left zone
</asp:Content>
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
Central zone	
</asp:Content>

which results in the following page:

As stated earlier, web design is not my main strength :) but here you've got a basic squeleton that's up & running with Office 365.

What about dynamic data in your master pages? This can be achieved by out of the box webparts or custom webparts deployed with Sandboxed solutions. If I develop a very basic SandBoxed Solution that does this:

public class SandBoxedLeftNavWp : WebPart
    {
        protected override void Render(HtmlTextWriter writer)
        {
            StringBuilder HtmlMenuBody = new StringBuilder();
            SPListItemCollection Pages = SPContext.Current.Web.Lists["Web Pages"].Items;
            foreach (SPListItem Page in Pages)
            {
                HtmlMenuBody.AppendFormat("{0}<br>", Page["Title"]);
            }            
            writer.Write(HtmlMenuBody.ToString());
        }       
    }

Meaning building a list showing all the items of the web pages list...let's keep things easy...
and if now, I modify my left contentplaceholder shown earlier in my master page and I replace it by this:

<div id="leftcomponents" class="leftcolumn">
			 	<asp:ContentPlaceHolder id="PlaceHolderLeft" runat="server">

  <WebPartPages:SPUserCodeWebPart runat="server"
   Description="My WebPart"
   Title="SandBoxedLeftNavWp"
   ChromeType="None"
   AssemblyFullName="LeftNavSandBoxWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e62d3f794cb305fc"
   SolutionId="efd9ec76-af15-4d22-a5bf-8ae43a121afb"
   ID="g_9e6fccc9_ebfd_4abe_a942_49dcc43674b4"
   TypeFullName="LeftNavSandBoxWebPart.SandBoxedLeftNavWp.SandBoxedLeftNavWp"
   __MarkupType="vsattributemarkup" __WebPartId="{9E6FCCC9-EBFD-4ABE-A942-49DCC43674B4}"
   WebPart="true"
   __designer:IsClosed="false"
   partorder="2">
 </WebPartPages:SPUserCodeWebPart>
</asp:ContentPlaceHolder>

where I encapsulate my custom webpart, I'll get a dynamic menu incorporated inside my masterpage:

Of course, this technique has a major drawback since Sandboxed solutions consume resource points and if you expect a lot of visitors, your resource quota might be quickly reached. In those situations, you might prefer using client code using Javascript and/or jQuery to consume our good old lists.asmx.

So, as you probably notice, at the time of writing, this is not so easy to customize the public facing site of Office 365 since this requires a lot of efforts but this is yet possible!

Happy coding!

Comments

How do you make that copy?

It's nice article and exactly what I'm looking for, but how did you make a copy of this file? Are you using E subscription? I am with P1 and I don't even see "All Files" option in the "Site Objects" menu in SPD. Also I can't open any master file because "Masterfile editing is disabled ....". I could not reach the site content in any other way than SPD (Pages -> open page. but that dialog does not allow me neither to copy files, nor to open master files)?

SharePoint Designer

Hi,

Yes it works with P1 as well. Are you sure that you have enough permissions to do what you want to do?

Best Regards

Public site customization and license agreement

Hi,
if you see the license agreement (http://www.microsoft.com/download/en/details.aspx?id=13602) you can see:
Customizations with SharePoint Designer 2010: SharePoint Designer 2010 provides tools for the rich customization of SharePoint sites—without having to do any coding. Reporting tools, data integration, and application templates are also available from SharePoint Designer 2010.
• SharePoint Online only supports SharePoint Designer 2010.
• Backup and restore is no longer a feature offered in SharePoint Designer 2010.
• SharePoint Designer 2010 cannot be used to edit the public website. This site can only be edited with the built-in Site Designer tool.

I know that you can customized the publicc site master page from technical point of view, but it isn't allowed by Microsoft and you going out of Office 365 Support...

Igor

Hi...... How to link to Member Login

Hi... I have used a custom master page and my own navigation bar on my public facing site by copying minimal.master.......now i want to be able to link to the admin part where the content on the page ie

asp:ContentPlaceHolder ID="IWS_WH_CPH_Content" runat="server" asp:ContentPlaceHolder

could be edited....... by any user who has the level of permission......... im getting an error if i link to that page now...

Thanks in advance,

Thendral

Yes, it worked

Yes, it worked.

It seems we charge to change the ID of the abode holder to Place Holder Main to get it to work. That's what SPD does back we change the adept folio application that option. I assumption it should ask for that back you manually adapt the url too. Its a acceptable affair the placeholders can be mapped so we can use the centralized masters design portfolio.

Thanks.