Office 365: introduzione allo sviluppo – add-in commands Parte 1 (Outlook)

 

Introduzione

Nel precedente post di introduzione allo sviluppo per O365 abbiamo visto come creare un add-in di tipo Task pane per Excel. Questo tipo di add-in, come anche il Content pane, permette di creare uno spazio (un pannello laterale o un’area all’interno del documento) dentro il quale viene mostrata e gestita l’interfaccia utente della nostra “applicazione” Office 365.

Il nuovo modello di sviluppo per O365 inoltre, permette anche di personalizzare la UI standard di Office aggiungendo elementi al ribbon (tab, bottoni e drop-down) o nuove voci al menù contestuale, che possiamo utilizzare come entry points per alcune funzionalità dell’add-in, per mostrare uno o più task pane o anche per eseguire procedure JavaScript che non necessitano di un’interfaccia utente specifica.

Al momento i commands sono in GA (General Availability) solo per Outlook, mentre per Word, Excel e PowerPoint sono disponibili in Developer Preview. In ogni caso i concetti espressi sono i medesimi per tutti i client citati, per i quali è comunque previsto il rilascio in GA entro aprile 2016.
Tuttavia per certi elementi occorre fare delle distinzioni sui valori di alcune proprietà, in quanto Outlook, per sua natura, prevede degli scenari di utilizzo un po’ diversi dagli altri tipi di applicazioni Office. Per questo motivo in questa prima parte tratteremo nello specifico la definizione dei commands per Outlook, mentre nel successivo post vedremo nel dettaglio l’implementazione per Word, Excel e PowerPoint

Definizione dei commands

Gli add-in commands vengono definiti attraverso l’elemento VersionOverrides direttamente all’interno del file manifest dell’applicazione. Questo elemento deve essere inserito come child di OfficeApp, deve avere obbligatoriamente gli attributi xmlns e xsi:type, e funge da elemento root per tutta la definizione dei nostri commands.
L’attributo xmlns, nel caso di Outlook, deve essere impostato a “http://schemmicrosoft.com/office/mailappversionoverrides” mentre xsi:type  deve valere “VersionOverridesV1_0”

 <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">

VersionOverrides contiene a sua volta 2 elementi obbligatori: Hosts e Resources, oltre a 2 elementi opzionali: Description e Requirements che permettono di impostare rispettivamente la descrizione dell’add-in e la versione minima richiesta di Office.js.

Andiamo ora ad analizzare nel dettaglio gli elementi principali

Hosts

L’elemento Hosts è quello in cui vengono effettivamente definiti tutti i comandi. Al suo interno abbiamo uno o più elementi Host, uno per ogni tipo di Office host per il quale vogliamo rendere disponibili i commands.

L’attributo che definisce il tipo di host è xsi:type e i valori consentiti sono “MailHost” per Outlook, “Workbook” per Excel, “Document” per Word e “Presentation” per PowerPoint.

Naturalmente, dato che in questo caso stiamo parlando di Outlook, avremo un solo elemento Host di tipo MailHost

 <Hosts>
   <Host xsi:type="Workbook">
     <!-- qui vanno le informazioni per i comandi Outlook-->
   </Host>
 </Hosts>

Ogni elemento Host contiene le impostazioni dei comandi per uno specifico form factor.

Al momento è possibile definire solo l’elemento DesktopFormFactor, che permette di personalizzare i comandi per gli add-in che girano nelle applicazioni Windows desktop e in quelle web (Office Online), ma in futuro saranno aggiunti anche gli altri tipi come TabletFormFactor e PhoneFormFactor

DesktopFormFactor

In questo elemento possiamo definire, mediante l’attributo resid dell’elemento FunctionFile, la URL del file html che contiene il “Code Behind” con i metodi da eseguire quando viene richiamato il comando ExecuteFunction alla pressione ad esempio di un bottone. Il valore di questo attributo in realtà rappresenta l’identificativo della risorsa nella quale si trova l’effettiva url del file. (vedi paragrafo Resources in fondo al post)

(Una cosa fondamentale da ricordare è che nel codice JavaScript deve essere sempre richiamato il metodo Office.initialize)

 <FunctionFile resid="residFunctionFileUrl" />

Codice JavaScript

 <script>
     (function () {
         Office.initialize = function (reason) {
            // Qui può essere aggiunto eventuale codice di inizializzazione
         };
     })();
 </script>

Ad esempio se imposto il valore di FunctionFile a “residFunctionFileUrl”, dovrà essere presente nelle risorse un elemento di tipo Url con id=”residFunctionFileUrl” e DefaultValue=”https://[indirizzo del file html]” (ma vedremo la parte relativa alle risorse in modo dettagliato più avanti nel post).

Aggiungendo poi uno o più elementi di tipo ExtensionPoint, possiamo creare i controlli personalizzati nell’interfaccia utente standard di Office.

L’attributo xsi:type dell’ExtensionPoint serve per definire quale “area” della UI stiamo andando a personalizzare.

Nel caso di Outlook i valori consentiti sono:

- CustomPane  : attiva un pannello orizzontale disponibile solo per la vista relativa alla lettura di una mail

- MessageReadCommandSurface : definisce i bottoni nel ribbon della vista relativa alla lettura di una mail

- MessageComposeCommandSurface : definisce i bottoni nel ribbon della vista relativa alla composizione di un nuovo messaggio

- AppointmentOrganizerCommandSurface : definisce i bottoni nel ribbon dell’organizzazione di un meeting

- AppointmentAttendeeCommandSurface : definisce i bottoni nel ribbon di partecipazione ad un meeting

All’interno dell’ExtensionPoint vengono definiti i controlli veri e propri, e qui dobbiamo fare una distinzione tra il CustomPane ed i vari “CommandSurface” .

CustomPane

Il CustomPane viene visualizzato come un pannello orizzontale che si attiva quando una o più condizioni vengono soddisfatte.

Tali condizioni devono essere definite come una collection di elementi di tipo Rule all’interno dell’ExtensionPoint stesso

 <Rule xsi:type="RuleCollection" Mode="Or">
  <Rule xsi:type="ItemIs" ItemType="Message"/>
  <Rule xsi:type="ItemHasAttachment"/>
  <Rule xsi:type="ItemHasKnownEntity" EntityType="Address"/>
 </Rule>

Oltre alle regole è necessario definire anche un elemento di tipo SourceLocation dove specificare il resid della risorsa contenente l’url del file con il codice dell’add-in (allo stesso modo dell’elemento FunctionFile visto in precedenza)

Oltre a questi 2 elementi possiamo definire anche l’altezza minima richiesta del pannello tramite RequestedHeight, o indicare se desideriamo che l’elemento selezionato non venga evidenziato tramite
DisableEntityHighlighting

 <RequestedHeight>100</RequestedHeight> 
 <SourceLocation resid="residTaskpaneUrl"/>
Command Surface

Con tutti gli altri tipi di ExtensionPoint, come MessageReadCommandSurface, MessageComposeCommandSurface, AppointmentOrganizerCommandSurface e AppointmentAttendeeCommandSurface, possiamo invece aggiungere controlli ai tab standard del ribbon, oppure crearne di personalizzati.

I controlli devono essere raggruppati in elementi di tipo Group identificati in modo univoco tramite l’attributo id. Questi gruppi, come anticipato, possono trovarsi in uno dei tab standard (utilizzando l’elemento OfficeTab), oppure in un nuovo tab (utilizzando invece l’elemento CustomTab)

Per ogni gruppo dobbiamo specificare uno o più elementi di tipo Control per definire i controlli che compongono il gruppo stesso, oltre alla Label da visualizzare come “titolo”.

I controlli a disposizione sono di 2 tipi: bottoni e menù. Entrambe i tipi vengono definiti grazie all’attributo xsi:type che va impostato rispettivamente a “Button” o “Menu”.

Per il Button gli elementi obbligatori sono:

- Label

- SuperTip

- Icon

- Action

dove Action serve ad indicare che tipo di “azione” deve essere compiuta attraverso il bottone. Se l’attributo xsi:type è impostato a “ExecuteAction”, allora verrà invocato un metodo del codice JavaScript contenuto nel file impostato nell’elemento FunctionFile (vedi sopra). Se invece è impostato “ShowTaskpane” è possibile indicare la url della pagina da visualizzare nel pannello.

Esempio Button con ExecuteAction

 <Control xsi:type="Button" id="testButton">
   <Label resid="residTestButtonLabel" />
   <Supertip>
     <Title resid="residTestButtonTipTitle" />
     <Description resid="residTestButtonTipDescription" />
   </Supertip>
   <Icon>
     <bt:Image size="16" resid="icon16" />
     <bt:Image size="32" resid="icon32" />
     <bt:Image size="80" resid="icon80" />
   </Icon>
   <Action xsi:type="ExecuteFunction">
     <FunctionName>mioMetodo</FunctionName>
   </Action>
 </Control>

per il ShowTaskpane è sufficiente modificare l’elemento Action

 <Action xsi:type="ShowTaskpane">
 <SourceLocation resid="readidTaskpaneUrl" />
 </Action>

Il controllo Menu, che si presenta in realtà come un dropdown button, ha gli stessi elementi del Button, con la differenza che al posto di Action occorre utilizzare l’elemento Items, all’interno del quale vanno definiti uno o più elementi di tipo Item.

Gli Item hanno esattamente gli stessi elementi descritti per il Button e possono quindi richiamare un metodo attraverso il comando ExecuteFunction

  <Items> 
      <Item id="menuItem1"> 
        <Label resid="residItem1Title" /> 
        <Supertip> 
          <Title resid="residItem1Label" /> 
          <Description resid="residItem1Tip" /> 
        </Supertip> 
        <Icon> 
          <bt:Image size="16" resid="img16" /> 
          <bt:Image size="32" resid="img32" /> 
          <bt:Image size="80" resid="img80" /> 
        </Icon> 
        <Action xsi:type="ExecuteFunction"> 
          <FunctionName>mioMetodo</FunctionName> 
        </Action> 
      </Item> 
  </Items> 
Resources

L’ultimo elemento fondamentale che andiamo ad analizzare è quello delle risorse.

In questo elemento vengono definite le url delle icone, dei files contenenti il codice JavaScript per gli eventi dei bottoni, e le stringhe (con le eventuali localizzazioni) per le label dei vari controlli.

Gli elementi presenti in Resources possono essere utilizzati dai diversi controlli del manifest, facendo riferimento all’attributo id della risorsa. Ad esempio, per impostare la url del file da utilizzare come “Code Behind” nell’elemento FunctionFile che abbiamo visto in precedenza, è stato impostato l’identificativo “residFunctionFileUrl” nell’attributo resid.

Nelle risorse dovrà quindi essere presente un elemento di tipo url che abbia id = “residFunctionFileUrl” e che contenga l’effettivo indirizzo del file

 <Resources>
   <bt:Urls>
     <bt:Url id="residFunctionFileUrl" DefaultValue="https://www.mioindirizzo.com/Pages/functionCode.html"/>
   </bt:Urls>
 </Resources>

Oltre alle Url, in questo elemento possono essere definite anche immagini e stringhe

 <Resources>
   <bt:Images>
     <bt:Image id="icon1_16x16" DefaultValue="https://www.contoso.com/Images/icon_default.png"/>
     <bt:Image id="icon1_32x32" DefaultValue="https://www.contoso.com/Images/icon_default.png"/>
     <bt:Image id="icon1_80x80" DefaultValue="https://www.contoso.com/Images/icon_default.png"/>
   </bt:Images>
   <bt:ShortStrings>
     <bt:String id="residLabel1" DefaultValue="Etichetta 1"/>
     <bt:String id="residLabel2" DefaultValue="Etichetta 2"/>
   </bt:ShortStrings>
   <bt:LongStrings>
     <bt:String id="residToolTip1" DefaultValue="Questo è il mio primo comando"/>
     <bt:String id="residToolTip2" DefaultValue="Questo è il mio secondo comando"/>
   </bt:LongStrings>
 </Resources>

Per le immagini è importante ricordare che è obbligatorio impostare tutti e 3 i formati richiesti, ovvero:

- 16x16

- 32x32

- 80x80

e che tutti gli indirizzi (sia per gli elementi Images, che per gli elementi Url) devono essere HTTPS

Conclusione

In questo post è stata fornita una panoramica sulla definizione dei commands nel file manifest di un add-in per Outlook. Nel prossimo post ci concentreremo invece sugli gli elementi che si devono utilizzare per la personalizzazione della UI degli altri client di Office, come Word, Excel e PowerPoint

Per maggiori informazioni sulla definizione degli add-in commands per Outlook, trovate la documentazione dettagliata all’indirizzo:

https://msdn.microsoft.com/en-us/library/office/mt267547.aspx