SharePoint 2013 | Aplicar entorno (Chrome) de SharePoint en una SharePoint App

Escenario

Cuando programamos una SharePoint App “autohosted” tenemos que tener en cuenta que al instalarla se pierde el entorno de SharePoint porque lo que se hace es una especie de redirección desde SharePoint al sitio donde se ubica la App que publicamos. Por lo tanto, nuestra aplicación se verá como una web independiente de SharePoint y puede que no nos interese que sea así, sino que la aplicación esté dentro del entorno y del contexto de SharePoint 2013 manteniendo cabecera y menú.

 

Solución

Una vez hayamos creado el proyecto con la SharePoint App, tendremos una página default.aspx que por defecto está establecida como la página inicial del proyecto y que no contiene nada, salvo el nombre del sitio de SharePoint al que está asociada y que se inyecta desde el Code Behind.

SharePoint-App-Default-PageSharePoint-App-HostSharePoint-App-Project

 

Para lograr mi objetivo tenía que buscar la forma de insertar los scripts de SharePoint 2013 dentro de la página de mi aplicación y… buscando un poco en Bing (jejeje….) di con esta página de la MSDN que, aunque está un poco desactualizada, explican bien el concepto de lo que quiero y también incluyen el código que necesito para lograrlo. Pero como no es exactamente igual que como pone ahí porque hay algunas cosas que no son necesarias, quería explicarlo a mi manera.

En primer lugar, tenemos diferentes opciones, casi iguales, para incluir el Chrome de SharePoint 2013 dentro de nuestra App. Aquí exponen dos de ellos y yo me decanté por el más sencillo que es el segundo, denominado declarativo en el artículo.

   1:  <head runat="server">
   2:      <title>Santiago Porras Rodríguez - My SharePoint App with Chrome control</title>
   3:      <script src="http://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript">     </script>
   4:      <script src="../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
   5:      <script type="text/javascript">
   6:          var hostweburl;
   7:   
   8:          // Load the SharePoint resources.
   9:          $(document).ready(function () {
  10:              // Get the URI decoded app web URL.
  11:              hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
  12:              // The SharePoint js files URL are in the form: web_url/_layouts/15/resource.js
  13:              var scriptbase = hostweburl + "/_layouts/15/";
  14:              // Load the js file and continue to the success handler.
  15:              $.getScript(scriptbase + "SP.UI.Controls.js")
  16:          });
  17:   
  18:          // Function to retrieve a query string value. For production purposes you may want to use a library to handle the query string.
  19:          function getQueryStringParameter(paramToRetrieve) {
  20:              var params = document.URL.split("?")[1].split("&");
  21:              var strParams = "";
  22:              for (var i = 0; i < params.length; i = i + 1) {
  23:                  var singleParam = params[i].split("=");
  24:                  if (singleParam[0] == paramToRetrieve)
  25:                      return singleParam[1];
  26:              }
  27:          }
  28:      </script>
  29:  </head>
  30:  <body>
  31:      <!-- Chrome control placeholder options are declared inline.  -->
  32:      <div id="chrome_ctrl_container"
  33:          data-ms-control="SP.UI.Controls.Navigation"
  34:          data-ms-options='{  
  35:                  "appHelpPageUrl" : "Help.html",
  36:                  "appIconUrl" : "/Images/MyIcon.png",
  37:                  "appTitle" : "My SharePoint App with Chrome control",
  38:                  "settingsLinks" : [
  39:                      {
  40:                          "linkUrl" : "Account.html",
  41:                          "displayName" : "Account settings"
  42:                      },
  43:                      {
  44:                          "linkUrl" : "Contact.html",
  45:                          "displayName" : "Contact us"
  46:                      }
  47:                  ]
  48:               }'>
  49:      </div>
  50:   
  51:      <!-- The chrome control also makes the SharePoint Website style sheet available to your page. -->
  52:      <h1 class="ms-accentText">Main content</h1>
  53:      <h2 class="ms-accentText">The chrome control</h2>
  54:      <div id="MainContent">
  55:          <form id="form1" runat="server">
  56:              <div>
  57:                  Awesome!!! I'm into SharePoint 2013 Chrome!!!
  58:              </div>
  59:          </form>
  60:      </div>
  61:  </body>

 

El funcionamiento es el siguiente:

  • Se carga la librería Javascript de Ajax desde el CDN de Microsoft.
  • Se carga jQuery. Yo lo he cargado localmente al proyecto pero podemos sustituirlo por el que se encuentra en el CDN de Microsoft.
  • En el bloque de Javascript que viene a continuación se encuentran dos partes bien diferenciadas:
    • Cuando se haya cargado la página, se establece la dirección del Host de SharePoint 2013 (hostweburl) y se intenta cargar la librería Javascript SP.UI.Controls.js que es la que nos interesa para nuestro caso.
    • La función getQueryStringParameter que es llamada desde el punto anterior, nos sirve para obtener la dirección del servidor de SharePoint.
  • En el código HTML tenemos que realizar varios cambios:
    • Crear un divisor al que asignaremos un id, por ejemplo “chrome_ctrl-container” y en el que tenemos que incrustar las propiedades que están establecidas en el ejemplo.
    • Crear un divisor con id “MainContent” en el que incluimos el contenido de nuestra App (más que nada para tenerlo organizado, cosa que os puede salvar de muchos problemas)
    • Además, como opcional, podemos añadir Título y subtítulo en la página tal y como se muestra en el ejemplo.

Si ahora ejecutamos nuevamente la aplicación, el resultado es bien diferente, más agradable y, como estamos trabajando en SharePoint, mucho más lógico mantener el entorno (Chrome). Me he permitido el lujo de añadir un icono a la aplicación para darle algo de vida.

 

No obstante, hay otra forma muy similar de incluir el Chrome de SharePoint en nuestra App y que consiste en modificar levemente esta solución poniendo las propiedades del container dentro del bloque javascript. Esta opción que es la que finalmente he implementado en mi proyecto, nos permite separar más la lógica seguida para incluir el Chrome de SharePoint.

   1:  <head runat="server">
   2:      <title>Santiago Porras Rodríguez - My SharePoint App with Chrome control</title>
   3:      <script src="http://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript">     </script>
   4:      <script src="../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
   5:      <script type="text/javascript">
   6:          var hostweburl;
   7:   
   8:          // Load the SharePoint resources.
   9:          $(document).ready(function () {
  10:              // Get the URI decoded app web URL.
  11:              hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
  12:              // The SharePoint js files URL are in the form: web_url/_layouts/15/resource.js
  13:              var scriptbase = hostweburl + "/_layouts/15/";
  14:              // Load the js file and continue to the success handler.
  15:              $.getScript(scriptbase + "SP.UI.Controls.js", function () {
  16:                  var chromeOptions = {
  17:                      siteUrl: hostweburl,
  18:                      userName: '',
  19:                      siteTitle: "Tracking map site",
  20:                      appTitle: "Tracking map",
  21:                      appIconUrl: "/Images/siteLogo.png"
  22:                  };
  23:                  var nav = new SP.UI.Controls.Navigation("chrome_ctrl_container", chromeOptions);
  24:                  nav.setVisible(true);
  25:              });
  26:          });
  27:   
  28:          // Function to retrieve a query string value. For production purposes you may want to use a library to handle the query string.
  29:          function getQueryStringParameter(paramToRetrieve) {
  30:              var params = document.URL.split("?")[1].split("&");
  31:              var strParams = "";
  32:              for (var i = 0; i < params.length; i = i + 1) {
  33:                  var singleParam = params[i].split("=");
  34:                  if (singleParam[0] == paramToRetrieve)
  35:                      return singleParam[1];
  36:              }
  37:          }
  38:      </script>
  39:  </head>
  40:  <body>
  41:      <!-- Chrome control placeholder options are declared inline.  -->
  42:      <div id="chrome_ctrl_container"></div>
  43:   
  44:      <!-- The chrome control also makes the SharePoint Website style sheet available to your page. -->
  45:      <h1 class="ms-accentText">Main content</h1>
  46:      <h2 class="ms-accentText">The chrome control</h2>
  47:      <div id="MainContent">
  48:          <form id="form1" runat="server">
  49:              <div>
  50:                  Awesome!!! I'm into SharePoint 2013 Chrome!!!
  51:              </div>
  52:          </form>
  53:      </div>
  54:  </body>

El resultado final es el mismo que en la opción anterior como podréis comprobar

 

Finalmente, quería recordaros que para quitar la palabra “Dev” que me aparece a mi y que se corresponde con el nombre del sitio de SharePoint al que está vinculado la aplicación, tendréis que ir al archivo de Code Behind de la página, es decir a default.aspx.cs donde deberéis eliminar la línea siguiente:

   1: Response.Write(clientContext.Web.Title);

 

También podéis eliminar el resto si no vais a usar el contexto de SharePoint.