<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkcFSXk8eCp7ImA9WhFSFEw.&quot;"><id>tag:blogger.com,1999:blog-4126985520350746834</id><updated>2013-06-16T20:13:38.770+01:00</updated><category term="Personal" /><category term="Coding" /><category term="WCM" /><category term="Continuous Integration" /><category term="jQuery" /><category term="master pages" /><category term="debugging" /><category term="speaking" /><category term="workflow" /><category term="page layouts" /><category term="JSLink" /><category term="security" /><category term="lists" /><category term="deployment" /><category term="SharePoint" /><category term="AJAX" /><category term="SP2013" /><category term="content deployment" /><category term="ghosting" /><category term="codeplex" /><category term="Search" /><category term="help" /><category term="Content Search web part" /><category term="TechEd" /><category term="customizing" /><category term="Virtual Server" /><category term="CAS policy" /><category term="site definitions" /><category term="user group" /><category term="CustomAction" /><category term="SP2010" /><category term="feature-stapling" /><category term="Content Deployment Wizard" /><category term="webparts" /><category term="feature receiver" /><category term="site columns" /><category term="configuration" /><category term="features" /><category term="central admin" /><category term="DelegateControl" /><category term="MOSS" /><category term="content migration API" /><category term="VSeWSS" /><category term="Virtual Machine Manager" /><category term="content query web part" /><category term="content types" /><category term="InfoPath" /><title>Chris O'Brien</title><subtitle type="html">The nuts and bolts of SharePoint.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.sharepointnutsandbolts.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.sharepointnutsandbolts.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4126985520350746834/posts/default?start-index=2&amp;max-results=1&amp;redirect=false&amp;v=2" /><author><name>Chris O'Brien</name><uri>http://www.blogger.com/profile/10022906552670607366</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_DPonmXhJQ4g/SiFZBcX_Q1I/AAAAAAAAAa0/14b7VTN0FZM/s1600-R/28f5735.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>164</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>1</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ChrisObrien" /><feedburner:info uri="chrisobrien" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0cERXo6eSp7ImA9WhBaGEs.&quot;"><id>tag:blogger.com,1999:blog-4126985520350746834.post-7504597529243022986</id><published>2013-05-29T22:19:00.001+01:00</published><updated>2013-05-30T00:10:04.411+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-30T00:10:04.411+01:00</app:edited><title>SP2013 host web apps: provisioning files (e.g. master pages) to the host web</title><content type="html">&lt;p&gt;
Here in early summer 2013, it’s a slightly strange time in SharePoint development land. The message is that sandbox solutions are “deprecated” in SharePoint 2013 (however you choose to interpret that) and that we should build apps where possible – however, apps currently cannot do many of the things that sandboxed solutions can. One key difference between apps and sandboxed solutions, of course, is that when you provision fields/content types/files etc. in your app they are created in the app web – not the “host web”. For many requirements, this “isolated space” idea works fine. However, when you really want your artifacts to exist in the day-to-day areas of SharePoint that users go to (i.e. the team/project/My sites that become known as host webs in the app world) then you need a different approach.&lt;/p&gt;
&lt;p&gt;
If you’re no longer comfortable using the sandbox, then what can we do? Well, one option to consider is that apps CAN sometimes “provision to the host web”. They can do this if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The app requests (and is granted) “Full Control” permission of the host web      &lt;ul&gt;
&lt;li&gt;Note this means it &lt;strong&gt;cannot&lt;/strong&gt; be sold via the Office/SharePoint Store (see &lt;a href="http://msdn.microsoft.com/en-us/library/jj938162.aspx" target="_blank"&gt;Validation checklist for apps for Office and SharePoint&lt;/a&gt;). But it can be deployed internally through the organization’s App Catalog.. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CSOM code is used for provisioning, rather than standard Feature XML &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All of a sudden, apps can now be used as the vehicle for deploying “regular” SharePoint functionality – perhaps components that are used in typical collaboration solutions. The code/solution in this article is taken from my “Deep-dive on SharePoint-hosted apps” talk at the SharePoint Evolutions Conference, and this article is the first in a series of short posts on such “host web apps” (within my wider series on SP2013 apps). But first..&lt;/p&gt;
&lt;h3&gt;
Should you do this? Deciding between host web apps/sandbox/farm..&lt;/h3&gt;
&lt;p&gt;
I think this approach has a place – especially if you are paranoid about the life expectancy of sandboxed solutions, or someone is insisting that the app model is used. However, my feeling is that we are effectively exploiting a loophole here. I’m sure Microsoft did not particularly intend apps to be used in this way (as evidenced by difficult CSOM-based deployment model), but, possibly because of other concerns, they have robust mechanisms in place such that it isn’t proactively blocked. Me? Well, personally I feel that if the client requirements steer you towards working in the host web, then apps aren’t the right vehicle – if you’re cloud-focused, then I believe you should be using a design centred around the sandbox. Despite the &amp;quot;deprecated” tag I think Microsoft will have to extend the app model before they can really remove this option. In other words, I think we should understand that we are in a transition period and new development approaches will become available – but I won’t feel bad about using the best tool for the job right now.&lt;/p&gt;
&lt;p&gt;
&lt;font color="#ff0000"&gt;&lt;font color="#333333"&gt;I should add that this might not apply to product development – an area which I currently do not have to worry about. My friend &lt;a target="_blank" href="http://www.elumenotion.com/Blog/default.aspx"&gt;Doug Ware&lt;/a&gt; is building an app based around the host web, and has dug far deeper into this than me. We’ve previously debated this topic in our blog posts – you can my version (which links to his posts) at &lt;/font&gt;&lt;/font&gt;&lt;a href="http://www.sharepointnutsandbolts.com/2012/09/sharepoint-apps-working-with-app-web.html"&gt;SharePoint apps: working with the app web, and why you should&lt;/a&gt;. You’ll see that I’m effectively softening my position &lt;em&gt;slightly&lt;/em&gt; in this post.&lt;/p&gt;
&lt;h3&gt;
How to: provision a master page (or any file) to the host web&lt;/h3&gt;
&lt;p&gt;
In this example, I’m choosing to provision a master page – but the approach works for other file types too. Arguably the best approach is to provision the file, initially at least, to the app web. This works because later on we’ll need to fetch the file contents from somewhere, rather than declare the entire file contents directly in a JavaScript variable (not very practical). So, we add the file to our app and use a Module element to provision it into the app web. I found that provisioning with a .txt extension was best at this stage (more on this later):&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://lh4.ggpht.com/-J2YjbNesCWs/UaZwyhVH3LI/AAAAAAAACPE/jgdxOIrRY7Y/s1600-h/Provisioningtoappwebinitially4.png"&gt;&lt;img title="Provisioning to app web initially" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Provisioning to app web initially" src="http://lh4.ggpht.com/-TbOgdGbx79o/UaZwzc1kh5I/AAAAAAAACPM/_Bq2eRyd300/Provisioningtoappwebinitially_thumb2.png?imgmax=800" width="327" height="287" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;The code&lt;/h4&gt;
&lt;p&gt;
Then we need a wodge of CSOM code – specifically JSOM in my case. I’m using a SharePoint-hosted app, where the code executes on page load of the app default page. In the code we have to pull a few tricks – firstly we make a jQuery GET request to the .txt file in the app web, in order to obtain the contents. N.B. This was the reason we provisioned it with a .txt extension at first – for some file types (e.g. .master, .aspx) you might find that the file contents are not what you expect. This can happen because the page could not be executed/parsed properly by SharePoint, i.e. a runtime error occurred because you effectively browsed the master page/page layout/whatever &lt;em&gt;directly&lt;/em&gt;. This undesired behavior goes away if you are simply requesting a .txt file.&lt;/p&gt;
&lt;p&gt;
Then we use JSOM to open a connection to the host web. We do this by &lt;em&gt;passing a relative URL to the host web&lt;/em&gt; to the SP.ClientContext constructor, instead of asking for SP.ClientContext.get_current(), which would give us context in the app web where our page is running.&lt;/p&gt;
&lt;p&gt;
Our JSOM code then uploads to the host web (via a method which can be re-used to provision any file to any path in the host web), and just for good luck we go ahead and set the master on the host web. The code below has no external dependencies, and should work fine if you paste it into your app:&lt;/p&gt;
&lt;p&gt;
&lt;noscript&gt;&lt;div class="codeSampleNote"&gt;** N.B. My newer code samples do not show in RSS Readers - &lt;a href="http://www.sharepointnutsandbolts.com/2013/05/sp2013-host-web-apps-provisioning-files.html"&gt;click here for full article&lt;/a&gt; **&lt;/div&gt;&lt;/noscript&gt;

&lt;script src="https://gist.github.com/chrisobriensp/5666875.js"&gt;&lt;/script&gt;   
&lt;h4&gt;Running the app&lt;/h4&gt;

&lt;p&gt;
Once our app is built and we add it to a site, the person adding has to accept the Full Control permission request:&lt;/p&gt;


&lt;p&gt;
&amp;#160; &lt;a href="http://lh4.ggpht.com/-xRe1Glfxk8k/UaZw0DJNMHI/AAAAAAAACPU/Gs7vnCaMxxs/s1600-h/Fullcontrolapppermissionrequirement4.png"&gt;&lt;img title="Full control app permission requirement" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Full control app permission requirement" src="http://lh4.ggpht.com/-vfovYEYrwEk/UaZw01PefaI/AAAAAAAACPc/ZCCkHOaolNE/Fullcontrolapppermissionrequirement_.png?imgmax=800" width="653" height="314" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;
And, since the model here is that our JSOM code executes when the page is loaded, our master page is indeed provisioned when the user navigates to the app. My sample code presents show some simple UI to confirm this:&lt;/p&gt;


&lt;p&gt;
&lt;a href="http://lh6.ggpht.com/-IzLRNRA5Eps/UaZw1oLhNEI/AAAAAAAACPk/CV3m_0jpYoA/s1600-h/FileprovisioningsuccessUI4.png"&gt;&lt;img title="File provisioning success UI" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="File provisioning success UI" src="http://lh3.ggpht.com/-S4GB_KyX5M4/UaZw2aNXamI/AAAAAAAACPs/8NF_iid3O1A/FileprovisioningsuccessUI_thumb2.png?imgmax=800" width="804" height="366" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
The result&lt;/h3&gt;


&lt;p&gt;
Now when we go back to the host web, we see that our master page has indeed been provisioned to the Master Page Gallery:&lt;/p&gt;


&lt;p&gt;
&lt;a href="http://lh4.ggpht.com/-1NidK5o__HA/UaZw4JbZynI/AAAAAAAACQE/lPFBOXpiFEA/s1600-h/Masterpageprovisioned4.png"&gt;&lt;img title="Master page provisioned" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Master page provisioned" src="http://lh5.ggpht.com/-4zxm1YeREUA/UaZw43IjHPI/AAAAAAAACQM/CvW_6q-5pTU/Masterpageprovisioned_thumb2.png?imgmax=800" width="739" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;
..and because we set it to be the default master page, any branding changes in this master page (such as a red bar in my case) have been applied to the site:&lt;/p&gt;


&lt;p&gt;
&lt;a href="http://lh6.ggpht.com/-ESt_ZyWsy4g/UaZw2_yQqaI/AAAAAAAACP0/Ag3ToUA_4zA/s1600-h/Masterpagechanged4.png"&gt;&lt;img title="Master page changed" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Master page changed" src="http://lh3.ggpht.com/-3SUtuLPzG34/UaZw3gpmRuI/AAAAAAAACP8/COfiT443LV0/Masterpagechanged_thumb2.png?imgmax=800" width="847" height="261" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, if you really want to avoid sandboxed solutions or proactively want to use apps, then you can see that these CSOM techniques can be useful. In future posts, I'll follow up with further code for other common scenarios.&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/ChrisObrien/~4/_YiDUzZzJYU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.sharepointnutsandbolts.com/feeds/7504597529243022986/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4126985520350746834&amp;postID=7504597529243022986" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4126985520350746834/posts/default/7504597529243022986?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4126985520350746834/posts/default/7504597529243022986?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ChrisObrien/~3/_YiDUzZzJYU/sp2013-host-web-apps-provisioning-files.html" title="SP2013 host web apps: provisioning files (e.g. master pages) to the host web" /><author><name>Chris O'Brien</name><uri>http://www.blogger.com/profile/10022906552670607366</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_DPonmXhJQ4g/SiFZBcX_Q1I/AAAAAAAAAa0/14b7VTN0FZM/s1600-R/28f5735.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-TbOgdGbx79o/UaZwzc1kh5I/AAAAAAAACPM/_Bq2eRyd300/s72-c/Provisioningtoappwebinitially_thumb2.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.sharepointnutsandbolts.com/2013/05/sp2013-host-web-apps-provisioning-files.html</feedburner:origLink></entry></feed>
