CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: masterpage

AppLoader Concept for SharePoint apps

In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.

The problem we are trying to solve

SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).

One of the biggest shortcomings of that model is the need to add app parts on all pages where it is needed. Let’s say, we want to have some app parts present on every single page in our whole SharePoint tenancy, to provide a consistent look and feel (e.g. navigation, notifications). Traditionally, on premises, we have added user controls in our customized master page. In SharePoint Online that is impossible. The complicated workaround is to add those client web parts (app parts) on every page, be it manually or by automating it (powershell or app). It will require updating all pages. Nevertheless, it will not work on Out-of-the-box application pages (pages from layouts folder). It becomes even more unacceptable when you realize that your app must be added as an app instance on every single site (SPWeb) in your tenancy. 

Towards a solution

Allright, we don’t want to have thousands of app instances of the same app. What we can do is to use Tenant scoped apps (Tenant Apps). Then we’ll need only one app instance. But wait, app parts from a tenant app are only available in the parent site (HostWeb), meaning – App Catalog. That’s not good. So what Martin found in the SharePoint internal javascript code is using of _layouts/15/TenantAppInfo.ashx, a http handler that provides information about all Tenant Apps and their custom actions.That’s how the idea of the AppLoader was born.

Vesa Juvonen

After we had created a working Proof-of-Concept of the AppLoader concept, I met Vesa Juvonen at the SharePoint Conference in Las Vegas and introduced this idea to him (although I didn’t call it AppLoader). He liked it although he pointed out that this TenantAppInfo.ashx is an internal utility only in SharePoint and it is not supported by Microsoft. That’s correct. There is even almost no information about it on the Internet. But I got a feeling of Microsoft that they are willing to hear feedback and improve the product. Vesa encouraged me also to blog about it. So now I am telling about this idea. I hope to hear feedback about it. Unfortunately I cannot share the source code of the working Proof-of-Concept solution.

AppLoader Concept in colors

The AppLoader Concept is quite simple. Look at this picture:

apploader-concept

 

The solution contains a custom Master Page (blue) that references a javascript file called apploader.js (red). This file initializes the whole process. Tenant Apps (green) are the apps that an administrator has installed in the App Catalog and deployed to the whole tenancy. TenantAppInfo.ashx (black) is a handy but officially unsupported OOB service utility (http handler) that returns a json-formatted list of all Tenant Apps (green). AppLoader (red) receives the app list (black) and renders it on the Page (blue) inside new iframes (red). The page a user has navigated to can be any page (wiki page, publishing page, application page, really any page).

To summarize the colors in the diagram: red is our javascript code, green are all the tenant apps and their content, black is the utility and its output, blue is a sharepoint page and its underlying component (master page).

The steps in the AppLoader process:

  1. Make an ajax request to TenantAppInfo.ashx using XHR (XmlHttpRequest)
  2. Receive the app list
  3. For every app information, render app part, or inject css and javascript references. 

 

Reading what to render on the page

You probably have already have tried to navigate to _layouts/15/TenanAppInfo.ashx while reading this post, I know you are curious. Then you’ve noticed that there is no information about app parts. So you may ask: how do we know what app parts to render and where to put them in the page, and how do we know what resources (css and javascript files) to inject on the page. Well there is no information about it in the apps list. But if you have an app with custom actions you’ll see that they are listed in this json-formatted list we receive from the TenantAppInfo.ashx. So the solution is the brilliant idea of my colleage Martin to define custom actions in the app. CustomActions contain a ActionUrl. The ActionUrl points to the url to render (app part page) or to inject (javascript or css file). The apploader.js reads the ActionUrl in the Custom Actions for every app information and takes action upon it (rendering an app part iframe, or injecting a javascript or css file). That’s it. 

Usage and Limitations

This bright idea takes advantages from a huge SharePoint API (that contains a lot of good but not supported parts) to make using of apps in Client Application Model solutions more pragmatic and still provide a consistent design and behavior. By consistent design I mean same parts like additional navigation, notifications etc in the whole Intranet. The AppLoader renders and injects whatever you have rolled out to your whole tenancy (Tenant Scoped Apps) and that on every page (!). It also improves the perceived performance of the page load, because it renders app parts (iframes) after the main page has been loaded preventing freezing of the page. 

There are of course some limitations in the AppLoader Concept. Today we cannot rely on the TenanAppInfo.ashx API (because it is not supported and future updates can break solutions). We have to define our own custom actions in the apps. That means we can only use our own apps, it will hardly work with the apps installed from the Office Store. On the other hand, your customer will not want to have generic apps from the Office Store to be a part of every page on their intranet.

Erik Swensson’s book about Sharepoint Branding

Erik Swensson'b book about Sharepoint 2010 brandingToday Erik Swensson’s book Practical SharePoint 2010 Branding and Customization came to our company. I am looking forward to read it. It’s about time to see alternatives to Randy’s starters.

Add TreeView to Site

For all of who use Randy Drisgill’s starter masters, it won’t help if you go to Site Actions TreView and just enable it, because the DelegateControl is in a hidden panel.

To really restore the original treeview you have to copy this xml from v4.master:

<Sharepoint:UIVersionedContent runat="server" UIVersion="4">
	<ContentTemplate>
		<Sharepoint:SPNavigationManager
		id="TreeViewNavigationManagerV4"
		runat="server"
		ContainedControl="TreeView"
		CssClass="s4-treeView"
		>
		  <SharePoint:SPLinkButton runat="server" 
			NavigateUrl="~site/_layouts/viewlsts.aspx" 
			id="idNavLinkSiteHierarchyV4" 
			Text="<%$Resources:wss,treeview_header%>" 
			accesskey="<%$Resources:wss,quiklnch_allcontent_AK%>" 
			CssClass="s4-qlheader" />
			  <div class="ms-treeviewouter">
				<SharePoint:DelegateControl runat="server" ControlId="TreeViewAndDataSource">
				  <Template_Controls>
					<SharePoint:SPHierarchyDataSourceControl
					 runat="server"
					 id="TreeViewDataSourceV4"
					 RootContextObject="Web"
					 IncludeDiscussionFolders="true"
					/>
					<SharePoint:SPRememberScroll runat="server" 
						id="TreeViewRememberScrollV4" 
						onscroll="javascript:_spRecordScrollPositions(this);" 
						style="overflow: auto;height: 400px;width: 155px; ">
					  <Sharepoint:SPTreeView
						id="WebTreeViewV4"
						runat="server"
						ShowLines="false"
						DataSourceId="TreeViewDataSourceV4"
						ExpandDepth="0"
						SelectedNodeStyle-CssClass="ms-tvselected"
						NodeStyle-CssClass="ms-navitem"
						SkipLinkText=""
						NodeIndent="12"
						ExpandImageUrl="/_layouts/images/tvclosed.png"
						ExpandImageUrlRtl="/_layouts/images/tvclosedrtl.png"
						CollapseImageUrl="/_layouts/images/tvopen.png"
						CollapseImageUrlRtl="/_layouts/images/tvopenrtl.png"
						NoExpandImageUrl="/_layouts/images/tvblank.gif"
					  >
					  </Sharepoint:SPTreeView>
					</Sharepoint:SPRememberScroll>
				  </Template_Controls>
				</SharePoint:DelegateControl>
			  </div>
		</Sharepoint:SPNavigationManager>
	</ContentTemplate>
</SharePoint:UIVersionedContent>

and paste it before:

<asp:ContentPlaceHolder id="PlaceHolderQuickLaunchBottom" runat="server">

And of course we must remove the delegatecontrol duplicate from the hidden panel:

	<!-- Usually shows the tree view but do not remove because of issue with changing views in the ribbon in publishing sites -->
	<SharePoint:DelegateControl runat="server" ControlId="TreeViewAndDataSource"></SharePoint:DelegateControl>

s4-die

s4-die is a funny stuff. Now I realized the purpose of it. Everything that has to be hidden, Microsoft wraps in an element with class=”s4-die”. In corev4.css it is defined with display:none. Not so bad. Another approach is to create a invisible panel like Randy Drisgill has done. But with s4-die you don’t need to move your stuff around, just add the class s4-die.

 

 

master page for html5 and css3

A great work: v5.master. I am recommending to try it.

The problem are some javascript bugs in the IE 9 when you run IE mode 9 that are necessary to enable html5 and css3 support. You can’t “save” a list item:

The reason why it doesn’t work in IE, but in Chrome, Firefox, is that IE invokes some functionality that it doesn’t invoke in other browsers.

Next: Enable Save button in IE9

Custom PlaceHolder

You want some custom content in your site and it is different from page to page. Well, I wrote how to achieve this with delegate controls. Another approach is to use PlaceHolders. Maybe you can use some existing placeholders. There are so many unused placeholders in v4.master. Like PlaceHolderLeftActions. If you use starter master pages from Randy Drisgill, you must move these from invisible panel.

To create custom placeholder is very easy:

Just copy an existing placeholder in the master page and name it som appropriate like:

<asp:ContentPlaceHolder 
       id="PlaceHolderLeftNavBarContoso" 
       runat="server" />

In your custom page layout, or application page, just add asp:Content and put your html there:

<asp:Content 
        ContentPlaceHolderID="PlaceHolderLeftNavBarContoso" 
        runat="server">
           Hello World
        </asp:Content>

Create your own search box

It is very simple. Create a new module: SearchArea. Delete Sample.txt and Elements.xml. Create a new file: SearchArea.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control
      Id="ContosoSearchAreaBox"
      Sequence="15"
      ControlClass="Microsoft.SharePoint.Portal.WebControls.SearchBoxEx" 
      ControlAssembly="Microsoft.Office.Server.Search, Version=14.0.0.0, 
			Culture=neutral, PublicKeyToken=71e9bce111e9429c">
    <Property Name="GoImageUrl">/_layouts/images/Contoso/searchbutton.png</Property>
    <Property Name="GoImageUrlRTL">/_layouts/images/Contoso/searchbutton.png</Property>
    <Property Name="GoImageActiveUrl">/_layouts/images/Contoso/searchbutton.png</Property>
    <Property Name="GoImageActiveUrlRTL">/_layouts/images/Contoso/searchbutton.png</Property>
    <Property Name="DropDownMode">HideDD_useDefaultScope</Property>
    <Property Name="FrameType">None</Property>
    <Property Name="UseSiteDefaults">false</Property>
  </Control>
</Elements>

Next add your searcharea module to a site scoped feature.

In the masterpage locate this:

<SharePoint:DelegateControl runat="server" 
       ControlId="SmallSearchInputBox" Version="4" />

and replace with your brand new search area:

<SharePoint:DelegateControl runat="server" 
       ControlId="ContosoSearchInputBox" Version="4" />

Now you have full control over the appearence and behavior of the search button. Create your own search button, or google it, style the input with css and add javascript if needed.

Create own delegate control

In this post I’ll show how to create a simple (but own) delegate control.
A short intro and links on delegate controls can be found on sharepointoverflow.

Take a look on master page. There are already many delegate controls. The delegate control with id AdditionalPageHead can be used for adding your script or jQuery library.:

<SharePoint:DelegateControl 
    runat="server" 
    ControlId="AdditionalPageHead" 
    AllowMultipleControls="true"/>

You can also override existing controls like searchbox. But what if you want to add some content in the master page where no delegate controls are present. Of course, you can add it directly to the master page. Perhaps not on all webs? You can use placeholders to manage it. But do you want to update all the page layouts?

So the solution is to use delegate controls, for adding multiple pieces of content or overriding using Sequence. In this example I’ll add some new content to the quicklaunch bottom area:

<SharePoint:UIVersionedContent 
	UIVersion="4" runat="server" 
	id="PlaceHolderQuickLaunchBottomV4">
	<ContentTemplate>

Now we’ll create a brand new delegate control. Just add it after ContentTemplate:

<SharePoint:DelegateControl runat="server" 
     ControlId="AdditionalQuickLaunchArea" 
     AllowMultipleControls="true"/>

In your Visual Studio project add a mapped folder for CONTROLTEMPLATES and add a new user control: MyText.

Just write some text in the user control.

Add a new empty element:

Reference to your user control in the elements.xml file:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control Id="AdditionalQuickLaunchArea" 
           ControlSrc="~/_CONTROLTEMPLATES/MyText.ascx" 
           Sequence="1000" />
</Elements>

Now deploy to your site and see the difference:

This is just a simple tutorial which shows how to start developing a custom delegate control, only for demonstration purpose only. No formatting or good solution design have been payed attention.

Here is the original s4-leftpanel section from v4 without v3 ui versioned controls:

Read more of this post

Custom favicon

It is easy to use a custom favicon, put a ico image into a mapped folder Images and then locate this line in your master page:

<SharePoint:SPShortcutIcon runat="server" IconUrl="/_layouts/images/favicon.ico" />

And replace it with your ico:

<SharePoint:SPShortcutIcon runat="server" IconUrl="/_layouts/images/CONTOSO/favicon.ico" />

Videokurs om Web Content Management

På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.

Discovering SharePoint

And having fun doing it

Bram de Jager talking Office 365, SharePoint and Azure

My view and thoughts on Productivity and more.

My programming life

and everything in between

SharePoint Development Lab by @avishnyakov

It is a good place to share some SharePoint stories and development practices.

SharePoint Dragons

Nikander & Margriet on SharePoint

RealActivity - Real-time and trustworthy

Blog site of founder, RealActivty - Paul J. Swider

Mai Omar Desouki - Avid SharePointer

Egyptian & Vodafoner - Senior SharePoint Consultant

Cameron Dwyer | Office 365, SharePoint, Outlook, OnePlace Solutions

Office 365, SharePoint, OnePlace Solutions & Life's Other Little Wonders

paul.tavares

Me and My doings!

Share SharePoint Points!!

By Mohit Vashishtha

Jimmy Janlén "Den Scrummande Konsulten"

Erfarenheter, synpunkter och raljerande om Scrum från Jimmy Janlén

SPJoel

SharePoint for everyone

SharePointRyan

Ryan Dennis is a SharePoint Solution Architect with a passion for SharePoint and PowerShell

SharePoint 2020

The Vision for a Future of Clarity

Aharoni in Unicode, ya mama

Treacle tarts for great justice

... And All That JS

JavaScript, Web Apps and SharePoint

blksthl

Mostly what I know about SharePoint - CommunicoCuspis