Impostare o Reimpostare da PowerShell la proprietà ‘RichText Mode’

Scenario:

Dobbiamo aggiungere ad una raccolta documenti una colonna custom di tipo testo ma con la proprietà : Richtext abilitata, per inserire tag HTML. Dopo averla creata e aggiunta al nostro sito decidiamo di aggiungerla ad una raccolta documenti.

La procedura su come creare la colonna custom e aggiungerla alla raccolta documenti è fuori argomento, passiamo oltre e arriviamo al punto : la colonna che ho aggiunto non presenta la proprietà di ‘Richtext’ abilitata ed inoltre se entro nella modifica della colonna (nella raccolta documenti dove è stata aggiunta) non posso riattivarla….come fare a riattivarla? Tra le soluzioni che ho trovato (adattando una soluzione per un altro problema) la migliore per me, rimane lo script in PowerShell che consente di reimpostare la proprietà a ‘True’. Di seguito lo script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

Function RepairListRichTextColumns($webURL, $listName, $columnGUID)
{
    #Get web, list and column objects
    $web = Get-SPWeb $webURL
    $list = $web.Lists[$listName]
    $column = $list.Fields[[Guid]$columnGUID]       
    write-host "Schema="  $column.SchemaXml
    $column.RichText=$true
    $column.Update()
    write-host "Schema="  $column.SchemaXml
    $web.Dispose()
}
$webURL= "http://UrlDelSito/"
$listName = "Nome Della Lista"
$columnGUID = "GUID della colonna"
RepairListRichTextColumns -webURL $webURL -listName $listName -columnGUID $columnGUID
Annunci
Pubblicato in Senza categoria, Tips & Trick | Lascia un commento

REST Api : Come recuperare le informazioni utente con il metodo “SiteUserInfoList”.

Come riportato in un articolo precedente, tra le maggiori novità introdotte con SharePoint 2013 c’è il supporto alle operazioni REST che restituiscono dati nel formato Odata (Open Data Protocoll).

Le soluzioni basate su REST usano lo standard HTTP con i verbi: GET,PUT,POST,DELETE permettendoci quindi di sviluppare una vera e propria libreria per i metodi CRUD.

La funzione che prenderemo in considerazione in questo caso ci consente di recuperare le informazioni (User Properties) dell’utente corrente o più in generale di un dato utente , passando come argomento l’ID.  Le applicazioni pratiche sono tante, ad esempio potremmo creare una piccola rubrica da visualizzare nella “Home Page”. Il metodo in esame è compatibile con le piattaforme : “Shaepoint Online”, “SharePoint 2013” e “SharePoint 2013 Foundation”.

Passiamo ai ‘fatti’ ma prima una  premessa : la soluzione è a titolo di esempio.

Pagina ASPX.

Apriamo con “SharePoint Designer” la pagina dove vogliamo mostrare le informazioni e in corrispondenza dell’elemento “PlaceHolder” con ID=’PlaceHolderAdditionalPageHead’ aggiungiamo i riferimenti ai file javascript seguenti:

  • /_layouts/15/MicrosoftAjax.js
  • /_layouts/15/sp.runtime.js
  • /_layouts/15/sp.js
  • /_layouts/15/sp.requestexecutor.js
  • /Style Library/jquery-1.9.1.min.js
  • /Style Library/RESTUser.js

I primi 4 file sono standard, “jquery-1.9.1.min.js” si trova disponibile  in rete ed infine “RESTUser.js” è il file che aggiungeremo per eseguire tutto il codice di interesse. Per concludere, aggiungiamo in un punto qualunque della pagina questo elemento HTML di tipo DIV con ID=’infoUser’.

In questo div, mostreremo il risultato.

File Javascript : RESTUser.

Aggiungiamo quindi nella ‘Style Library’ un file con esenstensione ‘JS’ e copiamo all’interno il codice seguente:

'use strict';
var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var idUser = 0;

// Questa codice viene eseguito quando DOM è pronto e crea un oggetto contesto necessario per utilizzare il modello a oggetti di SharePoint
$(document).ready(function () {
    getUserId();
});
// Con questa funzione recuperiamo l'ID dell'utente corrente
function getUserId() {    
    context.load(user);
    context.executeQueryAsync(onGetUserIdSuccess, onGetUserIdFail);
}
// Questa funzione viene eseguita se la chiamata sopra indicata ha esito positivo e prosegue con la chiamata alla funzione che recupera le informazioni utente tramite chiamata REST.

function onGetUserIdSuccess() {
    idUser = user.get_id();   
    getinfo(idUser); //recupero le Info con l'ID passato
    
}
// Questa funzione viene eseguita se la chiamata precedente ha esito negativo
function onGetUserIdFail(sender, args) {
    alert('Failed to get user ID. Error:' + args.get_message());
}

function getinfo(id) {
    //Eseguo il metodo 'SiteUserInfoList' compatibile con tutte le //versioni, anche la Foundation 
    jQuery.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/SiteUserInfoList/Items(" + id + ")?$select=Title,Name,EMail",
        type: "GET",                
        headers: {
            "accept": "application/json;odata=verbose",
        },
        success: function (data) {
            ShowData(data);
        },
        error: function (err) {
            alert(JSON.stringify(err));
        }
    });
}

//Per concludere, la funzione che mostra le info recuperate
 function ShowData(data) {     
var html = [];     html.push("<table>");     
var results = data.d.results;     
html.push("<tr>");      
html.push("<td>");      
html.push("Benvenuto,<strong>" +data.d.Title+"</strong>");      
html.push("</td>");     
html.push("</tr>");  
html.push("<tr>");   
html.push("<td>");      
html.push("Email:" +data.d.EMail);      
html.push("</td>");     
html.push("</tr>");                
html.push("</table>");     
$('#infoUser').html(html.join('')); }

 

A video vedremo al posto del div, le informazioni riportate nella tabella HTML:

Benvenuto, Amministratore
Email : amm@email.it

Buon lavoro!

Pubblicato in Senza categoria | Lascia un commento

Custom Action – Modificare il menu contestuale (ECB) di una lista Sharepoint

Come ci può suggerire il titolo  con questo articolo vedremo come sia possibile modificare o estendere l’interfaccia utente (UI) di SharePoint. Diciamo subito che  la personalizzazione dei menu, del ribbons, delle pagine e dei controlli in generale è un passaggio quasi obbligatorio per chi lavora con la piattaforma SharePoint e gli scenari possibili sono tanti, per cui caliamoci in un esempio concreto dandoci queste ‘specifiche’ :

Supponiamo di avere due liste personalizzate con le quali si vuole gestire l’anagrafica degli ordini con il classico modello ‘master-details’. Per prima cosa aggiungiamo due liste ‘custom’ : ‘Ordini testata’ e ‘Ordini dettaglio’ rispettivamente così composte:

5

6

 

 

 

 

 

 

 

 

 

Non soffermiamoci sulla struttura e sottoliniamo solo la presenza del campo di LookUp nella lista di dettaglio ‘Ordine numero’.
La personalizzazione ci deve permettere di ottenere questa funzionalità:
Selezionando un ordine nella lista ‘Testata’ si deve visualizzare il ‘Dettaglio’ corrispondente della lista ‘Dettaglio’.
Questi i macro-step da realizzare:

  1. Sviluppare con Visual Studio una Feature che modifichi l’ ‘Edit Control Block’ (ECB) della lista ‘Testata’ per indirizzare l’utente in una pagina intermedia.
  2. Aggiungere una vista sull’elenco ‘Dettaglio’ con un filtro sul campo ‘Ordine numero’, il cui valore è passato tramite query string.
  3. Aggiungere con SharePoint Designer una pagina “aspx” e un file ‘.jasvascript’ che conterrà del codice che fa uso del ‘Client-Object Modell’.

Iniziamo aggiungendo delle risorse che ci serviranno più avanti.

  1. Aggiungiamo la pagina ‘RecuperaNumeroOrdine.aspx’ in ‘SitePages’.
  2. Aggiungiamo una ‘Style Library’ e aggiungiamo un file di tipo ‘Javascript’ che chiameremo ad esempio :MyFunction.js, inizialmente vuoto.
  3. Procuriamoci il file : jquery-1.9.1.min.js da qui Jquery e aggiungiamo anche questo alla libreria.

Step 1: Custom Action sulla lista ‘Ordini Testata’.
Premessa : Esistono diversi modi per modificare l’ECB della lista, in questo esercizio svilupperemo una soluzione ‘Sandbox’ che conterrà una Feature per installare la personalizzazione. Nello specifico la personalizzazione non è altro che un file ‘XML’ contenente appunto l’elemento ‘Custom Action’. Questo elemento con tutti gli attributi è descritto bene qui : Custom Action – MSDN.
Nel caso in esame non utilizzeremo tutti gli attributi, ma è sempre bene conoscere l’elemento che si utilizza nella sua completezza e in questo la documentazione in linea è molto precisa. Fine Premessa.
Per configurare la “custom action” partiamo con il crere un nuovo progetto in Visual Studio, selezionando : SharePoint 2013 -> Progetto vuoto.
Diamogli un nome significativo, come ad esempio : CustomActionsOrdini e selezioniamo come tipo di distribuzione ‘Sandbox Solution’.
Fatto questo, aggiungiamo alla soluzione  un elemento seguendo queste indicazioni : tasto destro sul nome del progetto -> Aggiungi -> Nuovo Elemento.
Selezioniamo un elemento di tipo : Modulo e diamogli un nome del tipo :TestataCustomActions.
Visual Studio aggiungerà in automatico due file:
-Elements.xml
-Sample.txt

A questo punto la “solution” sarà questa:

4

 

 

 

 

 

 

Eliminiamo il secondo file e apriamo il primo, che conterrà la nostra Custom Action.
All’interno di ‘Elements.xml’ copiamo il codice seguente:

<?xml version="1.0" encoding="utf-8"?>
 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
 <CustomAction
  Location="EditControlBlock"
  RegistrationType="List"
  RegistrationId="{499BA418-228E-499C-A322-943BF6B6BC86}"
   GroupId="GestioneOrdini"
  Id="MS.CustomOrdini"
  Title="Dettaglio dell' ordine"
  Rights="ViewListItems,EditListItems"
  Description="Visualizza il dettaglio dell'ordine."
  >
     <UrlAction Url="/SitePages/RecuperaNumeroOrdine.aspx?ItemId={ItemId}&amp;ListId={ListId}" />
   </CustomAction>
 </Elements>

Vediamo  nel dettaglio le proprietà che abbiamo utilizzato

  • Location-> indica l’oggetto da modificare, in questo caso appunto l’ECB
  • RegistrationType-> la custom action può essere attivata su un oggetto specifico, una lista specifica o un content type specifico. Nel caso in esame voglio modificare l’ECB solo di una specifica lista, quindi questa proprietà combinata alla successiva, fa in modo che la modifica si attivi solo per la lista ‘Ordini Testata’.
  • RegistrationId-> indico la lista specificando il GUID. Per ricavare il valore si può, ad esempio, aprire la lista con SharePoint Designer e tra le proprietà visibili c’è anche l’ID.
  • Id->identificativo univico.
  • Title->Testo da visualizzare nel menu
  • Description->Descrizione visibile passando il mouse sull’opzione del menu.
  • Rights->Indica quali permessi siano necessari per visulizzare l’opzione. E’ una proprietà molto importante perché ci permette di condizionare la personalizzazione in maniera coerente rispetto i permessi che ha l’utente.
  • UrlAction-> Questo elemento è un ‘child’, può essere presente solo uno di questo elemento nella custom action. Nell’esempio in esame ho indicato la pagina : RecuperaNumeroOrdine.aspx che sarà spiegata nel dettaglio più avanti. L’aspetto da sottolineare è il seguente : la query string contiene queste informazioni:
    • ItemId={ItemId}
    • ListId={ListId}

La prima variabile conterrà l’ID delle’elemento nella lista ed il secondo conterrà l’ID della lista. Con queste due informazioni posso recuperare l’elemento dalla lista e accedere a tutti i valori; anticipo che è quello che faremo nella pagina :RecuperaNumeroOrdine.aspx

Installiamo e attiviamo la feature, facendo il ‘Deploy’ da Visual Studio e verifichiamo la personalizzazione! Se ha funzionato vedremo questo:

2

 

 

 

 

Completiamo la prova cliccando sul link, in questo momento dovremo solo visualizzare la pagina che abbiamo aggiunto all’inizio.

3

 

 

Step 2: Vista sull’elenco di dettaglio.
Aggiungiamo una vista sulla lista di dettaglio, includendo tutti i campi personali e con queste caratteristiche:
Filtro
Filtro

 

 

 

Come filtro abbiamo aggiunto la variabile : {Param1} che vedremo dopo a cosa serve.

Group by
GB

 

 

 

 

Totali
Totali

 

 

Salviamo la vista e proviamola inserendo nella URL alla fine dell’indirizzo un espressione per il filtro valido cioè : Param1=AB100 (avendo inserito un dettaglio su questo ordine):

Dtt

 

 

 

 

 

Riepiloghiamo.
Abbiamo le due liste collegate tra loro tramite il campo di ‘LookUp’ ‘Ordine numero’.
Abbiamo modificato l’ECB della lista ‘Ordine Testata’ per andare in una pagina intermedia.
Abbiamo aggiunto una Vista sulla liste ‘Ordine Dettaglio’ che mi consente di filtrare sul campo ‘Ordine numero’, passando un valore in query string.
A questo punto potrebbe sorgere un dubbio : perché non  uso l’ActionUrl per andare direttamente nella vista passando il valore del numero di ordine? Rivediamo l’ActionUrl:
/SitePages/RecuperaNumeroOrdine.aspx?ItemId={ItemId}&amp;ListId={ListId}
Il motivo è il seguente : nella query string non posso accedere a qualunque campo della lista sono ‘limitato’ ad alcuni attributi. Il compito della pagina intermedia è quindi quella di accedere alla lista ‘Ordini Testata’ recuperando la riga dell’ordine dalla lista ‘Testata’ (in base al valore di ‘ItemId’) e con un redirect ‘client-side’ passare alla nostra vista aggiungendo nella query string il valore del campo ‘Ordine numero’.

Ci manca questo ultimo pezzo…procediamo!

Step 3: Funzioni client-side e pagina intermedia.
Apriamo il sito con “SharePoint Designer”  e iniziamo con modificare la pagina ‘aspx’ :RecuperaNumeroOrdine.aspx.

In corrispondenza del TAG : PlaceHolderAdditionalPageHead; aggiungiamo i riferimenti alle risorse che dovremmo già aver aggiunto in precedenza e inseriamo la chiamata alla funzione client-side ‘ RecuperaNumOrdine()’ che vedremo più avanti:

<asp:Content ContentPlaceHolderId="PlaceHolderAdditionalPageHead" runat="server">
 <meta name="CollaborationServer" content="SharePoint Team Web Site" />
 <SharePoint:ScriptBlock runat="server">
 var navBarHelpOverrideKey = &quot;WSSEndUser&quot;; </SharePoint:ScriptBlock>
 <SharePoint:RssLink runat="server"/>
  <script type="text/javascript" src="../Style Library/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.js"></script>
 <script type="text/javascript" src="../Style Library/MyFunction.js"></script>
 <!--Chiamo la funzione-->
 <script type="text/javascript">
 $(document).ready(function () {
     RecuperaNumOrdine();
 });
 </script>
 </asp:Content>

Passiamo quindi al contenuto del file Javascript e apriamo il file ‘MyFunction.js’. Quello che ci serve è accedere tramite il ‘client-object modell’ alla lista e all’elemento specifico della lista per recuperare l’ordine e accedere finalmente alla proprietà che ci interessa:
Funzione JS principale:RecuperaNumOrdine.

//Definizioni variabili
var titleList="Ordini Testata";
var idItem="";
var itemID;
//Definizioni variabili:Fine

function RecuperaNumOrdine(){
 try {
 //recuperiamo dalla query string la ID della lista e dell'elemento in lista
 idItem=getUrlVars()["ItemId"];
 //
 var ctx = new SP.ClientContext.get_current();
 var list = ctx.get_web().get_lists().getByTitle(titleList);
var query = "<View><ViewFields><FieldRef Name='ID'/></ViewFields></View>";
 var camlQuery = new SP.CamlQuery();
 //Query CAML per recuperare l'elemento
 camlQuery.set_viewXml(
 '<View><Query><Where>' +
 '<Eq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>' + 
idItem+ '</Value></Eq>' +
 '</Where></Query></View>'
 );
 itemID= list.getItems(camlQuery);
 ctx.load(itemID, 'Include(ID,Numero_x0020_Ordine)');
 ctx.executeQueryAsync(Function.createDelegate(this, this.queryDettaglio), 
Function.createDelegate(this, this.error));
} catch (e) {
 alert('OPS!Si è verificato un errore :-(. ' +'\n'+e.get_message());
 }
 }

In questa funzione, ci sono da evidenziare un paio di aspetti:

  • ctx.get_web().get_lists().getByTitle(titleList) -> accediamo alla lista in base al titolo.
  • camlQuery.set_viewXml -> impostiamo la query che rispetta la sintassi CAML per filtrare sulla colonna di sistema “ID” che rappresenta la chiave nella lista.
  • ctx.load(itemID, ‘Include(ID,Numero_x0020_Ordine)’) -> con questo passaggio stiamo chiedendo di farci restituire solo i campi specificati. Questo passaggio è fondamentale per l’aspetto delle prestazioni. Riducendo il numero di campi che ci facciamo restituire, diminuisce il “peso” della struttura del file  XML restituito e aumentano quindi le prestazioni.

Funzione per recuperare il parametro dalla Query String.

function getUrlVars() {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;


}

Funzioni: “queryDettaglio” ed “error”.

function queryDettaglio() {
	var NumeroOrdine;
    try {       
        NumeroOrdine= itemID.getItemAtIndex(0).get_item('Numero_x0020_Ordine')
		//Con il numero di ordine passao alla lista del dettaglio 
		//con la vista parametrizzata
       window.location.replace('/Lists/Ordini%20Dettaglio/Dettaglio.aspx?Param1='
+NumeroOrdine);

    } catch (e) {
       alert('OPS!Si è verificato un errore :-(. ' +'\n'+e.get_message());
    }
}
//
function error(sender, args) {

    alert('OPS!Si è verificato un errore :-(. ' + args.get_message()
 + '\n' + args.get_stackTrace());

}

La funzione “queryDettaglio” viene eseguita solo se la richiesta ‘client-side’ va a buon fine e accedendo al primo elemento nell’oggetto ‘itemID’ (abbiamo filtrato sulla chiave) e da qui prendiamo il valore del campo che ci interessa.

Finalmente con una banale istruzione ‘window.location.replace..’ andiamo nella lista eseguendo la vista che accetta il filtro in query string.

Alla prossima!

Pubblicato in Personalizzare la UI di Sharepoint | Contrassegnato , | Lascia un commento

Workflow Manager – Attivazione in ambiente Multifarm

Come molti già sapranno, con la piattaforma SharePoint 2013 il motore di gestione dei WorkFlow è stato completamente riprogettato. Il servizio è stato portato fuori dalla piattaforma SharePoint; comportandosi di fatto come un ‘Web Services’ che su protocollo HTTP o HTTPS gestisce le richieste che arrivano dai Server SharePoint che di fatto rappresentano i Client. Una immagine presa da questo link: https://technet.microsoft.com/it-it/library/jj227177.aspx

WkManager2013

rende l’idea sulla nuova piattaforma. Premesso questo, l’aspetto da sottolineare è la seguente : Il motore ‘Workflow Manager’ progettato per la infrastruttura in Cloud è pensato per essere MultiTenant. Trasferendo l’affermazione in ambiente ‘OnPremises’ posso condividere il servizio di ‘Workflow Manager’ tra più Farm di SharePoint; nel classico scenario : Farm di sviluppo, Farm di quality e Farm di produzione; utilizzando un server dedicato per i servizi condivisi come tra l’altro  le “Office Web Apps”.

Gli articoli ufficiali a partire da questo link :

https://technet.microsoft.com/it-IT/library/jj658588.aspx

sono abbastanza completi; in breve per sommi capi i punti principali sono :

1. Installo il WorkFlow Manager sul server  usando la ‘Web Plattform’.

2.Aggiorno il servizio e solo dopo lo configuro; compilando una Form che mi guida passo-passo alla configurazione del servizi; come chiaramente descritto anche nella documentazione.

3.Installo il solo componente ‘Workflow Client’ sui server SharePoint; di preciso sui server con ruolo di Front End; ragionando con una topologia di Farm a 3 livelli.

4.Registro il server SharePoint eseguendo un banale script PowerShell sul server dove sto installando il client :

Register-SPWorkflowService -SPSite “http://myserver/mysitecollection&#8221; -WorkflowHostUri “http://workflow.example.com:12291&#8221; -AllowOAuthHttp

Fatto questo potrò creare un Workflow sulla Piattaforma 2013.

Il problema?

Se ripeto l’operazione su una seconda Farm SharePoint, già durante l’esecuzione dello Script visualizzo un messaggio :

An existing scope named “SharePoint” already exists in the workflow server..

Cosa è successo ? Che se provo a registrare un seconda Farm con lo stesso PowerShell, funzionerà sulla nuova Farm ma non funziona più nella precedente. Il motivo? Il servizio è pensato MutliTenant ma devo dividere le registrazioni utilizzando un attributo nel PowerShell : Scope.

Ecco la versione che evita di sovrascrivere la registrazione per la Farm precedente:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue Register-SPWorkFlowService -SPSite ‘http://WebApplication:xxxx’   -WorkflowHostUri ‘http://serverWorkFlowManager:12291‘ -ScopeName InserireUnoScopeName -AllowOAuthHttp -Force

Specificando uno ‘Scope’ diverso separo le registrazioni e tutto funziona!!

Buon Lavoro!

Pubblicato in Configurazione Sharepoint 2013, Workflow Manager | Contrassegnato | 1 commento

Personalizzare la Master Page con :Gestione Progettazione (Design Manager)

Con Sharepoint 2013 sono state introdotte delle novità anche nella parte di personalizzazione della Master Page.
In aggiunta alla possibilità già presente nelle versioni precedenti, di lavorare con file .master; oggi si è aggiunta l’opzione di lavorare con un file in formato .html e di ottenere, con dei passaggi che mostrerò nell’articolo, la pagina .master equivalente.
Per fare ciò utilizzeremo la nuova feature : Gestione Progettazione (Design Manager).
Partiamo subito con un elenco delle caratteristiche (che io ritengo) principali mettendo a confronto questi due approcci :

Design Manager Custom Master Page
Richiede la Feature di Pubblicazione SI NO
Hai solo conoscenza di HTML e al CSS SI NO
Hai conoscenza sul modello di personalizzazione precedenti alla versione 2013 SI SI
Vuoi sfruttare la Feature di “Download Minimo” (MDS) delle pagine. NO SI
Lavori con la versione :Sharepoint OnPremises e O365 SI SI

La prima caratteristica che ho messo in risalto è forse la più importante o quantomeno la più limitante, essendo richiesta la caratteristica di ‘Pubblicazione’ non potremo usare questo sistema con una Farm Foundation.
Fatta questa doverosa premessa, vediamo una panoramica su questo strumento interessante.
Per prima cosa dobbiamo avere attivato la caratteristica ‘Pubblicazione Sharepoint’. Appena attivata la caratteristica avremo modo di vedere che nelle impostazioni del sito, per la sezione “Aspetto” sono visibili queste nuove opzioni:
• Pagina Master
• Modelli di sito e layout di pagina
Per prima cosa dimentichiamo l’approccio, forse noto a tutti, di partire da una copia della Master Page ‘V4’ e di personalizzarla con Sharepoint Designer, anche perché come avranno notato tutti, in Sharepoint Designer non è più disponibile il tab ‘Progettazione’. Al di là delle considerazioni personali su questa novità, l’approccio nella personalizzazione con ‘Gestione Progettazione’ è quello di ‘portare fuori’ dall’ambiente Sharepoint (e quindi S. Designer) questo tipo di attività e di lavorare con il file HTML puro e semplice. Successivamente utilizzando le opzioni della ‘Gestione Progettazione’ sarà possibile trasformare il file HTML in una pagina Master Page di Sharepoint e di modificarla aggiungendo i controlli classici ( come la casella di ricerca).

Vediamo come “step-by-step” è possibile personalizzare da zero la Master Page.

Step 1: Scegliamo un modello di layout.
Partire da zero va bene, da uno è meglio! Sono ormai disponibili diversi template basati su HTML5 & CSS3 e quindi personalmente ne scelgo uno da qui ( a puro scopo di illustrazione):
http://keen.github.io/dashboards/layouts/
Il cui sorgente si trova in :
https://github.com/keen/dashboards
Cliccando su ‘Download ZIP’ nella parte destra:

Immagine1

Scompattiamo l’archivio e navighiamo nelle cartelle fino a “Layouts” dove troviamo la cartella ‘Hero-Sidebar’ con il file ‘index.htm’.
Portiamolo fuori e prendiamo anche la cartella :assests.
Copiando file e cartella in un altro percorso dovremmo avere una situazione del genere:

Immagine2

Apriamo il file ‘index.htm’ con il nostro editor e aggiorniamo i riferimenti ai file delle risorse:

Immagine3

Aggiungiamo nella cartella :assets/img/ il nostro file ‘logo’ che useremo più avanti.

Step 2: Trasferiamo il file nella Master Page Gallery
Questo step ci fa entrare nel merito del nuovo metodo : interagisco con Sharepoint fuori da Sharepoint.
Dalle ‘Impostazioni’ selezioniamo ‘Gestione Progettazione’ e nella pagina che visualizzeremo, selezionare ‘Carica file di progettazione’ (terza voce).

Immagine4

Nella pagina delle impostazioni è visibile l’URL della master page che useremo per connettere un’unità di rete (procedura standard dipendente dal S.O. in uso) che punti alla cartella ‘catalogs\masterpage’.

Immagine5

Dopo aver connesso l’unità di rete procediamo con:
1. La creazione di una cartella nella root che conterrà file e risorse personalizzate (CMP V1).
2. Il trasferimento di tutti i file con le cartelle.
Completato il trasferimento dei nostri file passiamo al prossimo step.
Riepilogando:
La possibilità di mappare come unità di rete la cartella ‘masterPage’ di Sharepoint ci consente di lavorare con un qualunque editor, direttamente sul file ‘HTML’ senza dover conoscere per forza ‘Sharepoint Designer’.
Step 3: Convertire il file HTML in una Master Page.

Questo step è fondamentale e server per creare la “Master Page” di Sharepoint a partire dal file HTML.
Per prima cosa assicuriamoci di avere un backup dei nostri file, che nelle fasi successivi subiranno un po’ di modifiche.
Per la conversione torniamo alla ‘Gestione Progettazione’ e selezioniamo ‘Modifica Master Page’ :

Immagine6

Come si può intuire, clicchiamo sul link ‘Converti un file HTML in una….’ nella finestra di dialogo navighiamo fino alla nostra cartella e selezioniamo il file (index.html):
Notare che il file è nello stato ‘Bozza’; selezionarlo e cliccare su ‘Inserisci’.
Sharepoint farà una verifica sul formato del file e ci avviserà nel caso di problemi.

Immagine7

In caso di errori saranno segnalati e dopo aver apportato le eventuali modifiche, il file sarà convertito:

Immagine8

Clicchiamo sul nome del file per vedere l’anteprima.

Immagine9

Il file è ancora nello stato di Bozza, quindi non è visibile a tutti ma va bene così dato che prima di potere utilizzare la Master Page devono essere fatti un po’ di adeguamenti. Nella parte bassa della pagina è visibile un ‘div’ giallo che rappresenta l’area utilizzata dalle ‘Page Layout’ dovrà sarà “renderizzato” il contenuto.

Step 4: Modificare il file HTML per modificare la Master Page.
Apriamo il file ‘Index.HTML’ che si trova nella ‘Galleria delle Master Page’ :
Noteremo subito dei blocchi di commento aggiunti da Sharepoint; intorno a questi troviamo il nostro codice intatto. Apportiamo delle modifiche per portare nella parte centrale della pagina il ‘Div Giallo’; perché è lì che andranno i contenuti dei Page Layout.
Facendo riferimento a questo file, apriamo il file e selezioniamo il codice contenuto nel div con la classe : “col-sm-9”

Immagine10

Tagliamo il codice (CTRL+X) ed incolliamolo in un nuovo file (CTRL+V) con estensione ‘HTML’. Se l’editor ha aggiunto i tag standard ‘HTML’,”; etc. Cancelliamolo e lasciamo il nostro codice.
Tornando alla ‘Index.html’ e cerchiamo di spostare il ‘Div Giallo’ nel nostro ‘Div class=”col-ms9″‘.
Il ‘Div’ in oggetto.

Immagine11

Riepilogando:
Con questi passaggi abbiamo visto come operando solo sul file HTML, usando l’editor preferito, senza conoscenza dell’ambiente Sharepoint; otteniamo la Master Page equivalente.
Step 5: Usiamo i “Frammenti di codice” (Snippet)
Anche se lavoriamo sul file HTML, sappiamo bene che nella Master Page di Sharepoint esistono una serie di controlli che non possono mancare, come : la casella di ricerca. Per utilizzare lo strumento, dall’anteprima della master page, cliccare su ‘Frammenti di codice’ (Snippet):

Da qui si accede ad una pagina dove è possibile aggiungere i controlli standard come ad esempio il controllo per visualizzare il logo. Per prima cosa selezioniamo nel Ribbon in alto e come esempio selezioniamo il controllo : Logo del Sito.

Immagine12

La pagina si aggiornerà per mostrare la casella delle proprietà di questo controllo dove potremo impostare una serie di attributi. Nella gruppo:
Personalizzazione – Logo sito (SPSimpleSiteLink)
Espandiamo la sezione ‘Navigation’ e in corrispondenza dell’attributo ‘NavigateURL’ inseriamo : “~sitecollection/”

Immagine13

Nel gruppo:
Personalizzazione – Logo sito (SiteLogoImage)
Espandiamo la sezione ‘Misc’ e in corrispondenza dell’attributo ‘LogoImageUrlField’ sostituiamo il valore presente con quello che punta all’immagine che nel primo step abbiamo ‘caricato’ nella cartella ‘assets’, nel mio caso:

Immagine14

Quando abbiamo terminato di modificare anche altri attributi come ad esempio la ‘classe’, andiamo in fondo alla pagina e clicchiamo su ‘Aggiorna’. Con questa operazione avremo la versione aggiornata del sorgente HTML da copiare nel nostro file :

Immagine15

Copiamo il codice nel punto giusto nel nostro file HTML.
Riepilogando:
Da questa pagina è quindi possibile selezionare e aggiungere i controlli standard di una master page:

Immagine15

Proseguendo con questa sezione, possiamo aggiungere tutti i controlli standard di una Master Page, in modalità ‘visuale’ e semplice. Al termine delle modifiche al nostro file non ci rimane che da :

1.Pubblicare il file, diversamente in stato di bozza non sarebbe visibile agli utenti.

Immagine17

2.Impostarla come master page di default:
Impostazioni sito -> Aspetto -> Pagina Master
Nella pagina di configurazione, scegliamo se usare la nostra master page come modello solo per le pagine del sito che aggiungiamo nella raccolta su cui è attiva la caratteristica di pubblicazione:

Immagine18

O se usarla anche per le pagine di sistema.
(In questo caso lascio la default).
Ora se aggiungiamo una pagina della raccolta ‘Pagine’ e scegliamo ad esempio il modello di Pagina ‘Pagina di benvenuto’ :

Immagine19

Vedremo che per questa pagina sarà applicata la nostra Master Page!

Pubblicato in Personalizzare la UI di Sharepoint | Contrassegnato , , | Lascia un commento

Installazione di Sharepoint 2013 :The specified user is a local account . Local account should only be used in stand alone mode

Quando installiamo “Sharepoint” su una macchina di sviluppo / valutazione, il più delle volte useremo una macchina non in dominio con utenti locali.

Nella prima fase del Wizard di configurazione, ci verranno richieste delle informazioni per creare il database di configurazione.

Inserendo un account locale, ad esempio : spADD ci troveremo di fronte al messaggio di errore:

“The specified user is a local account . Local account should only be used in stand alone mode”

La soluzione?

Creare al di fuori del ‘Wizard’ il database di configurazione!

Apriamo la shell di Sharepoint : “Sharepoint 2013 Management Shell”

Digitiamo il  comando:

New-SpConfigurationDatabase

e completiamo la procedura con le informazioni richieste a video.

blog2

NOTA 1 :Assicuriamoci prima che l’account utilizzato abbia i permessi sull’istanza SQL Server per creare i database:

  • Securityadmin
  • DbCreator

NOTA 2: L’operazione richiede un po’ di tempo.

Al termine dell’operazione chiudete la Shell e rilanciate “Sharepoint 2013 Products Configuration Wizard”.

Questa volta il Wizard rilevando il database di Configurazione di Sharepoint, vi chiederà se

blog3

 

 

 

 

 

Lasciare la opzione ‘Non Disconnettere’ e proseguire nella configurazione.

Buon Lavoro!

 

Pubblicato in Tips & Trick | Contrassegnato | Lascia un commento

Il Client Side Object Model (CSOM) e Javascript

Con SharePoint 2010 è stato introdotto il “Client Side Object Model” come opzione per accedere al “core” di SharePoint. Con SharePoint 2013 il CSOM è stato esteso dando la possibilità agli sviluppatori di accedere anche a servizi come: Enterprise Search; BCS; Social, Manage Metada e molto altro.

Senza dilungarci troppo; può essere utile focalizzarci sulla possibilità di utilizzare il CSOM con un linguaggio “C#” (si parla di “Managed” client object model) o con Javascript o con Silverlight. Quando si fa uso del linguaggio C#; uso le librerie contenute nelle due DLL

1.Microsoft.Sharepoint.Client.dll

2.Microsoft.Sharepoint.ClientRuntime.dll

localizzate nella cartella ISAPI del Front-End; quando utilizzo il Client-Side, faccio uso della libreria Javascript : sp.js; disponibile nella cartella ‘LAYOUTS’ del Front-End.

Il primo dubbio che quindi ci dovrebbe venire è : quando uso Javascript e quando C#?, semplice , Dipende! Dipende dal modello di Hosting della mia SharePoint APP, che ricordiamo essere:

  1. SharePoint Hosted : dove non potendo usare codice server side, c’è poco da fare, uso Javascript.
  2. Provider-Hosted : si possono usare codice server-side e quindi direi che siamo liberi di scegliere.
  3. Autohosted : idem.

Fatta una premessa, doverosa, vediamo come posso implementare i classici metodi CRUD utilizzando la versione Javascript; dove rispetto al caso “managed” con il C# c’è una leggera complessità in più dipendente dal fatto che le chiamate per ‘eseguire’ le operazioni avvengono in modo ‘asincrono’. Come visibile negli esempi il metodo ‘executeQueryAsync’ definisce due ‘delegate’; uno per gestire il caso ‘operazione corretta’ ed un altro per gestire il caso ‘errore’.

Metodi CRUD con il CSOM e Javascript.

Esempio: CRUD su una lista di tipo  ‘Contatti’.

var elencoContatti;

 function AggiungiContatto(cognome,nome,telefono) {
var ctx = new SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(“Contacts”);
ctx.load(list);
var listItemCreationInfo = new SP.ListItemCreationInformation();
var contatto = list.addItem(listItemCreationInfo);
contatto.set_item(“Title”, cognome);
contatto.set_item(“FirstName”, nome);
contatto.set_item(“WorkPhone”,telefono);
contatto.update();
ctx.executeQueryAsync(success, error);
}

    success = function () {
leggiContatti();
}

error = function (sender, args) {
alert(args.get_message());
}

function leggiContatti () {
var ctx = new SP.ClientContext.get_current();
var query = “<View><Query><OrderBy><FieldRef Name=’Title’/><FieldRef Name=’FirstName’/></OrderBy></Query><ViewFields><FieldRef Name=’ID’/><FieldRef Name=’Title’/><FieldRef Name=’FirstName’/><FieldRef Name=’WorkPhone’/></ViewFields></View>”;
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml(query);
var list = ctx.get_web().get_lists().getByTitle(“Contacts”);
ctx.load(list);
elencoContatti= list.getItems(camlQuery);
ctx.load(elencoContatti, ‘Include(ID,Title,FirstName,WorkPhone)’);
ctx.executeQueryAsync(mostraContatti, error);
},

function mostraContatti(){

var html = [];
html.push(“<table><thead><tr><th>ID</th><th>Nome</th><th>Cognome</th><th>Title</th></tr></thead>”);

var _elencoContatti= elencoContatti.getEnumerator();

while (_elencoContatti.moveNext()) {
var listItem = _elencoContatti.get_current();
html.push(“<tr>”);
html.push(“<td>”);
html.push(listItem.get_item(“ID”));
html.push(“</td>”);
html.push(“<td>”);
html.push(listItem.get_item(“FirstName”));
html.push(“</td>”);
html.push(“<td>”);
html.push(listItem.get_item(“Title”));
html.push(“</td>”);
html.push(“<td>”);
html.push(listItem.get_item(“WorkPhone”));
html.push(“</td>”);
html.push(“</tr>”);
}

html.push(“</table>”);

//Mostro in un Div con ID = displayDiv la tabella HTML
$(‘#displayDiv’).html(html.join(”));
}

function aggiornaContatto() (id, cognome, nome, telefono) {
var ctx = new SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(“Contacts”);
ctx.load(list);
var listItem = list.getItemById(id);
listItem.set_item(“Title”, lname);
A  listItem.set_item(“FirstName”, fname);
listItem.set_item(“WorkPhone”, wphone);
listItem.update();
ctx.executeQueryAsync(success, error);
}

function eliminaContatto (id) {
var ctx = new SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(“Contacts”);
ctx.load(list);
var listItem = list.getItemById(id);
listItem.deleteObject();
ctx.executeQueryAsync(success, error);
}

Pubblicato in Articoli, Sharepoint APP | Contrassegnato , , | Lascia un commento