Provisioning Custom Master Page To The Host Web From SharePoint Hosted App

Introduction

In this article, we will see how files can be provisioned to the host Web from an app (SharePoint hosted app in this case). A custom master page will be provisioned to the Host Web and the master page will be setup as the default Master page.

Please follow the steps, mentioned below.

Steps

  1. Open Visual Studio and create a new SharePoint app project.



  2. Select the Host for the app as “SharePoint-Hosted”.

  3. Once the project is created, you will find the structure, mentioned below.



  4. Add a module to the project, named Masterpages.

  5. Inside the module, you will see Sample.txt. Rename the file to customMasterpage.txt.



  6. Copy the code of your Custom Master Page to this file customMasterpage.txt (You can take a copy of the seattle.master from SharePoint Designer).

  7. Add the code, mentioned below, to App.js file.
    1.  'use strict';  
    2.   
    3. var hostWebUrl;  
    4. var appWebUrl;  
    5. var hostWebContext;  
    6. var destinationServerRelativeUrl;  
    7. var destinationFileName;  
    8. var appWebContext;  
    9.   
    10.   
    11. $(document).ready(function () {  
    12.     hostWebUrl = decodeURIComponent($.getUrlVar("SPHostUrl"));  
    13.     appWebUrl = decodeURIComponent($.getUrlVar("SPAppWebUrl"));  
    14.   
    15.     appWebContext = new SP.ClientContext.get_current();  
    16.       
    17.     hostWebContext = new SP.AppContextSite(appWebContext, hostWebUrl);  
    18.   
    19.     readFromAppWebAndProvisionToHost(appWebUrl + '/Masterpages/customMasterpage.txt''_catalogs/masterpage', customMasterpage.master');  
    20.           
    21. });  
    22.   
    23.   
    24. function readFromAppWebAndProvisionToHost(appPageUrl, hostWebServerRelativeUrl, hostWebFileName) {  
    25.   
    26.     destinationServerRelativeUrl = hostWebServerRelativeUrl;  
    27.     destinationFileName = hostWebFileName;  
    28.   
    29.     var req = $.ajax({  
    30.         url: appPageUrl,  
    31.         type: "GET",  
    32.         cache: false  
    33.     }).done(function (fileContents) {  
    34.         if (fileContents != undefined && fileContents.length > 0) {  
    35.             uploadFileToHostWebViaCSOM(destinationServerRelativeUrl, destinationFileName, fileContents);  
    36.         }  
    37.         else {  
    38.             alert('Failed to read file from app web, so not uploading to host web..');  
    39.         }  
    40.     }).fail(function (jqXHR, textStatus) {  
    41.         alert("Request for page in app web failed: " + textStatus);  
    42.     });  
    43. }  
    44.   
    45. function uploadFileToHostWebViaCSOM(serverRelativeUrl, filename, contents) {  
    46.   
    47.     var createInfo = new SP.FileCreationInformation();  
    48.     createInfo.set_content(new SP.Base64EncodedByteArray());  
    49.     for (var i = 0; i < contents.length; i++) {  
    50.         createInfo.get_content().append(contents.charCodeAt(i));  
    51.     }  
    52.   
    53.     createInfo.set_overwrite(true);  
    54.     createInfo.set_url(filename);  
    55.     var files = hostWebContext.get_web().getFolderByServerRelativeUrl(serverRelativeUrl).get_files();  
    56.     appWebContext.load(files);  
    57.     files.add(createInfo);  
    58.   
    59.     appWebContext.executeQueryAsync(  
    60.             Function.createDelegate(thisfunction () {  
    61.                 $('#message').append('<br /><div>File provisioned in host web successfully: ' + serverRelativeUrl + '/' + filename + '</div>');  
    62.                 setMaster('/' + serverRelativeUrl + '/' + filename);  
    63.             }),  
    64.             Function.createDelegate(thisfunction (sender, args) {  
    65.                 alert('Failed to provision file into host web. Error:' + args.get_message());  
    66.             }));  
    67.           
    68. }  
    69.   
    70. // set master page on host web..  
    71. function setMaster(masterUrl) {  
    72.     var hostWeb = hostWebContext.get_web();  
    73.     hostWeb.set_masterUrl(masterUrl);  
    74.     hostWeb.update();  
    75.   
    76.     appWebContext.load(hostWeb);  
    77.     appWebContext.executeQueryAsync(  
    78.             Function.createDelegate(thisfunction(){  
    79.                 $('#message').append('<br /><div>Master page updated successfully..</div>');  
    80.             }),  
    81.             Function.createDelegate(thisfunction (sender, args) {  
    82.                 alert('Failed to update master page on host web. Error:' + args.get_message());  
    83.             }));  
    84. }  
    85.   
    86.   
    87.   
    88. jQuery.extend({  
    89.     getUrlVars: function () {  
    90.         var vars = [], hash;  
    91.         var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');  
    92.         for (var i = 0; i < hashes.length; i++) {  
    93.             hash = hashes[i].split('=');  
    94.             vars.push(hash[0]);  
    95.             vars[hash[0]] = hash[1];  
    96.         }  
    97.         return vars;  
    98.     },  
    99.     getUrlVar: function (name) {  
    100.         return jQuery.getUrlVars()[name];  
    101.     }  
    102. });
  8. Go to AppManifest.xml -Permissions tab. We need to give the permission to the app to access the Host Web. Select “SiteCollection” Permission Level to ”Full Control”.

  9. Deploy the solution and trust the app.

  10. The Custom Master page will be uploaded and set to the site.