Les features avec Sharepoint

Dieudonne N'TAMACK

Dans ce tutoriel, vous allez apprendre ce que sont et à quoi servent les features (fonctionnalités) et comment les utiliser.

- Titre : Les features avec Sharepoint

- Auteur : Dieudonne N'TAMACK

- Parution : 15 février 2008

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Introduction

- II. Tour d'horizon des features

- III. Création de nos deux features

- III-A. Mise en oeuvre de notre environnement

- III-B. Création de notre feature au niveau de la collection de site

- III-C. Création de notre feature au niveau site

- III-D. Déploiement de nos features

- IV. Conclusion

I - Introduction

Les features ou fonctionnalités, comme leur nom l'indique, sont les fonctionnalités qui viennent enrichir les portails et applications SharePoint. Sous wss 3.0/moss 2007, quasiment tout est une fonctionnalité. Vous ne me croyez pas ? Eh bien regardez dans le dossier 12\TEMPLATE\FEATURES. Tous les dossiers que vous voyez apparaitre sont des fonctionnalités ! Et il y'en a plus de 200. La document Library, les basic webparts, tous sont des fonctionnalités que vous pouvez aisément installer/désinstaller, activer/désactiver. De même, vous pouvez créer et rajouter des fonctionnalités additionnelles en rajoutant un dossier. Dans la suite de cet article, après avoir défini les fonctionnalités, nous allons en créer 2 ; l'une qui va déployer de nouvelles pages maitre au sein de notre collection de site, et l'autre qui va appliquer la modification de la nouvelle master page au sein d'un site défini.

II - Tour d'horizon des features

Les fonctionnalités peuvent être déployées à plusieurs niveaux, au sein de notre ferme SharePoint. On va par exemple avoir des fonctionnalités qui sont déployables au niveau de la ferme toute entière, mais également au niveau d'une application web, d'une collection de site ou même d'un simple site web. A partir de l'administration centrale, dans la page des « Opérations », on va pouvoir gérer les fonctionnalités au niveau de la ferme ;

Toujours dans l'administration centrale, à partir de la page « Gestion des Applications », on va pouvoir gérer les fonctionnalités au niveau de nos applications web

Ensuite, au niveau de chacun des sites de plus haut niveau de chacune des nos collections de sites, nous allons pouvoir gérer les fonctionnalités de tous les sites de la collection.

Et enfin, au niveau de chacun des sites, nous allons pouvoir gérer les fonctionnalités de ce site. Le site de plus haut niveau de notre collection de site étant également un site en particulier, on va pouvoir, depuis la même page d'administration, gérer également les fonctionnalités de ce site.

Maintenant que nous avons vu où étaient localisées visuellement nos fonctionnalités au niveau de l'interface web, retournons dans le dossier des features. Si vous regardez à l'intérieur de chacun des dossiers représentant les fonctionnalités, vous verrez qu'il y'a toujours un fichier « Feature.xml » et d'autres fichiers/dossiers.

Ce fichier, « Feature.xml » est en fait le seul obligatoire, et c'est lui qui décrit ce qu'est la fonctionnalité. Les autres éléments sont des éléments qui seront des parties de la fonctionnalité, par exemple des webparts dans le cas ou notre fonctionnalité déploierait de nouvelles webparts, mais ces éléments ne font pas partie des éléments obligatoires pour créer une fonctionnalité. Si vous le souhaitez, vous pouvez par exemple définir une fonctionnalité qui ne contient que le fichier « Feature.xml » ; nous verrons d'ailleurs plus loin ce genre de fonctionnalités. Avec les fonctionnalités, on va pouvoir tout déployer, au sein de notre portail web ; vous trouverez une liste exhaustive de ce qu'on va pouvoir déployer ici. Lorsque vous définissez une fonctionnalité, vous lui attribuez une portée. C'est cette portée qui permet de définir le champ de visibilité de votre fonctionnalité.

Vous avez le choix entre 4 valeurs :

- Farm, pour rendre votre fonctionnalite disponible dans toute la ferme SharePoint

- WebApplication, pour rendre disponible votre fonctionnalite pour tous les sites de toutes les collections de site d'une application web

- Site, pour rendre disponible une fonctionnalite au sein d'une collection de site

- Web, pour rendre disponible une fonctionnalite au sein d'un site web unique.

Pour définir la portée de votre fonctionnalité, un bon point de départ consiste à vous interroger sur son utilité ; par exemple, si vous décidez de déployer des webparts, vous allez les héberger au sein de la webpart galerie ; cette dernière est unique au sein d'une collection de site et rend les webparts disponible pour toute la collection du site. Vous pouvez également utiliser ce lien, qui vous aide dans l'identification de la portée de votre fonctionnalité.

III - Création de nos deux features

Nous allons donc nous lancer dès maintenant dans la création de nos features. Comme nous l'avons déjà précisé, il nous faudra créer un fichier nommé Feaure.xml et un dossier, qui en général, porte le nom de la fonctionnalité. Toutes ces taches sont réalisables par le biais d'un fichier texte, mais nous allons tout de même faire les choses proprement et avec Visual Studio. L'objectif de cet article étant de voir le fonctionnement des features, nous ne passerons pas par les VSeWSS pour réaliser toutes nos taches.

III-A - Mise en oeuvre de notre environnement

Nous allons donc créer 1 nouveau projet Visual studio de type Class Library, et, pour l'instant, nous allons y créer un dossier Template, comme ci-dessous encadré en rouge (le reste sera créé au fur et à mesure).

Nous allons donc créer dans notre dossier Template 2 Features, l'une, Coforcert_MasterPages, qui sera déployée au niveau collection de site (scope = Site), va nous permettre d'uploader sur notre collection de sites de nouvelles master pages lors de l'activation de la fonctionnalité, et enfin l'autre, Coforcert_ApplyInternetMP, qui sera déployée au niveau site (scope=Web), qui va nous permettre d'appliquer la page maitre CoforcertInternet.master sur notre site. Les features que nous allons développer, dans un souci de portabilité sur des sites multilingues, ne comporteront directement aucun texte, mais utiliserons un fichier ressource. Pour ce faire, nous allons également créer un dossier « Ressources » et y stocker nos fichiers ressources ; Créez donc également ce dossier « Ressources », et ses fichiers, comme ci-dessus

III-B - Création de notre feature au niveau de la collection de site

Nous allons donc à présent créer notre 1ère feature, à savoir Coforcert_MasterPages, et donc créer le fichier « Feature.xml » lui correspondant. Dans cette partie, nous allons uniquement travailler dans le dossier « Coforcert_MasterPages ». Avant de se lancer dans l'édition de ce fichier, il est bon d'avoir un squelette entier de ce que peut contenir une feature. Voici ci-dessous le squelette d'un fichier Feature.xml

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/">
<ActivationDependencies>
<ActivationDependency/>
</ActivationDependencies>
<ElementManifests>
<ElementManifest/>
<ElementFile/>
</ElementManifests>
<Properties>
<Property/>
</Properties>
</Feature>

Cependant, avant de commencer à rédiger ces fichiers, nous allons importer un certain nombre de schémas xsd, afin de pouvoir bénéficier de la fonctionnalité d'IntelliSense avec Visual Studio. Pour cela, rendez vous dans le dossier 12\Template\XML, et copiez tous les fichiers portant l'extension « xsd ». Ce sont les fichiers définissant tous les schémas utilisés par SharePoint.

Nous allons copier tous ces fichiers dans le dossier « C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schémas », dossier correspondant à tous les schémas de Visual studio 2008. Ceci étant fait, maintenant, lorsque nous créerons de nouveaux fichiers respectant les schémas pour SharePoint avec Visual Studio, nous bénéficierons automatiquement de l'auto complétion ; pour cela, lorsque l'on créera un nouveau fichier XML correspondant à un schéma SharePoint, il nous suffira d'importer le schéma. Dans cet article, l'unique schéma dont nous aurons besoin est le « wss.xsd ». Lors de la création donc d'un fichier XML, il suffit d'afficher la fenêtre des propriétés, et d'importer le schéma.

Pour en revenir à notre feature, nous allons uniquement référencer un nouveau fichier xml, qui nous servira à décrire les fichiers que nous allons importer grâce à notre feature. Pour cela, nous allons créer, à l'intérieur du dossier « Coforcert_MasterPages » un nouveau fichier que nous allons appeler, par convention, elements.xml. Nous allons ensuite référencer ce fichier au niveau de notre feature grâce à l'élément « ElementManifest » Ceci étant fait, éditons à présent notre fichier Feature.xml. Ci-dessous le code complet de notre fichier.

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="1AC630A7-5A31-4e7c-8A44-74B7EAFD9773"
Description="$Resources:Coforcert_MasterPages,Description;"
ImageUrl="/_layouts/IMAGES/RootPagesLib.gif"
Scope="Site"
Title="$Resources:Coforcert_MasterPages,Title;"
Version="1.0.0.0"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests> <ElementManifest Location="elements.xml"/> </ElementManifests>
</Feature>

Comme vous pouvez le remarquer dans les attributs Description et Title, nous précisons que nous utilisons un fichier de ressources ($Resources), que ce fichier de ressources se nomme Coforcert_MasterPages, et que nous allons récupérer de ce fichier la valeur Description, dans le 1er cas, et Title, dans le 2ème cas. Nous devons ensuite éditer nos fichiers, afin de fournir ces valeurs. Ci-dessous, le fichier Coforcert_MasterPages.fr-fr.resx

Et ci-dessous, le 2ème fichier de ressources, lui aussi en version française.

Nous aurions également pu créer des fichiers pour des langues supplémentaires. Visuellement, voici le résultat obtenu, une fois nos features déployées.

A cette étape, nous avons donc créé notre fichier Feature.xml dans notre dossier « Coforcert_MasterPage », et édité nos 2 fichiers de ressources, dans notre dossier « Resources ». Pour terminer notre feature, il ne nous reste plus qu'à éditer notre fichier « elements.xml ».

C'est dans ce fichier, elements.xml, que nous allons spécifier que nous allons déployer nos mater pages. Pour ce faire, nous allons importer des fichiers dans notre bibliothèque de pages maitre au niveau de notre collection de site. Sous SharePoint, à chaque fois que nous allons déployer des fichiers, nous déploierons en fait des modules contenant ces fichiers. Ci-dessous le code nous permettant de déployer 4 master pages, coforcert.master, coforcertintra.master, coforcertextra.master et coforcertinter.master

<?xml version="1.0" encoding="utf-8" ?>
<Elements Id="A08AFBFF-373C-422b-8C48-4F4D67FCA016"
xmlns="http://schemas.microsoft.com/sharepoint/"> <Module List="116"
Url="_catalogs/masterpage"
Name="Coforcert MasterPages"
Path="masterpages" RootWebOnly="True"> <File Url="coforcert.master" Type="GhostableInLibrary"/>
<File Url="coforcertintra.master" Type="GhostableInLibrary"/>
<File Url="coforcertextra.master" Type ="GhostableInLibrary"/>
<File Url="coforcertinter.master" Type="GhostableInLibrary"/>
</Module>
</Elements>

L'attribut List, permet de spécifier dans quelle type de liste les fichiers vont être déployés ; 116 correspond à la catalog masterpage ; l'attribut Url permet de spécifier l'url de ladite liste, l'attribut Path permet de définir où se trouvent les fichiers à importer ; dans notre cas, ils sont dans notre dossier masterpages dans Visual studio, et enfin l'attribut GhostableInLibrary permet de spécifier que nos fichiers seront mis en cache dans notre bibliothèque.

Voila c'en est terminé pour notre Feature au niveau Collection de Site ; finalement, ce n'était pas sorcier ! Nous allons maintenant réaliser notre 2ème feature, celle qui sera déployée au niveau site.

III-C - Création de notre feature au niveau site

Cette fonctionnalité, « Coforcert_ApplyInternetMP », une fois les master pages déployées, va nous permettre d'installer, lors de son activation, la master page nommée « coforcertinter.master ». En plus de cela, pour compliquer un peu la tache, elle va nous créer une liste annonce et rajouter une annonce à chaque activation/désactivation de la feature, et pour terminer, va nous rajouter un lien « Gestion Des Fonctionnalités », dans le menu « Actions du Site ».

Procédons par étapes. Nous allons commencer par installer, lors de l'activation de la feature au niveau collection de site, notre feature au niveau site. Ici, nous allons gérer les dépendances au niveau des features.

<ActivationDependencies>
<ActivationDependency FeatureId="1AC630A7-5A31-4e7c-8A44-74B7EAFD9773"/>
</ActivationDependencies>

Le « FeatureId » correspond à l'id de la feature précédemment développée et qui sera déployée au niveau de la collection. De même, il va nous falloir déclencher quelque part une action lors de l'interception de l'activation de la Feature ; nous allons en fait, écrire un « Feature Receiver»

<Feature Id="277E2BFB-C895-464a-AA3C-23D3DCB22137"
Description="$Resources:Coforcert_ApplyInternetMP,Description;"
ImageUrl="/_layouts/IMAGES/Posts.png"
Scope="Web"
Title="$Resources:Coforcert_ApplyInternetMP,Title"
Version="1.0.0.0"
ReceiverAssembly="Project, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=04dd87c088df5ca8"
ReceiverClass="Coforcert.Assemblies.ReceiverAssembly"
xmlns="http://schemas.microsoft.com/sharepoint/">

On aurait pu s'arrêter ici, mais on va également rajouter une action dans le menu « Action du Site », et pour cela, on va à nouveau spécifier un fichier xml complémentaire, que nous allons appeler « ManageFeature.xml ». Voici le code complet du fichier « Feature.xml »

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="277E2BFB-C895-464a-AA3C-23D3DCB22137"
Description="$Resources:Coforcert_ApplyInternetMP,Description;"
ImageUrl="/_layouts/IMAGES/Posts.png"
Scope="Web"
Title="$Resources:Coforcert_ApplyInternetMP,Title"
Version="1.0.0.0"
ReceiverAssembly="Project, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=04dd87c088df5ca8"
ReceiverClass="Coforcert.Assemblies.ReceiverAssembly"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ActivationDependencies>
<ActivationDependency FeatureId="1AC630A7-5A31-4e7c-8A44-74B7EAFD9773"/>
</ActivationDependencies>
<ElementManifests>
<ElementManifest Location="ManageFeature.xml"/>
</ElementManifests>
</Feature>

Et celui du fichier « ManageFeature.xml »

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction Id="UserInterfaceLightUp.SiteActionsToolbar"
GroupId="SiteActions"
Location="Microsoft.SharePoint.StandardMenu"
Sequence="1000"
Title="$Resources:Coforcert_ApplyInternetMP,FeatureManagement;">
<UrlAction Url="/_layouts/ManageFeature.aspx"/>
</CustomAction>
</Elements>

Maintenant, il ne nous reste plus qu'à implémenter notre classe « Feature Receiver », et le tour sera joué. Pour cela, dans le dossier « Assembly », nous allons créer une nouvelle classe et la faire dériver de SPFeatureReceiver, comme le code ci-dessous.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Globalization;
namespace Coforcert.Assemblies {
public class ReceiverAssembly : SPFeatureReceiver {
public SPList GetAnnouncementList() {
//Crée une nouvelle liste d'annonce Feature Logs, ou la récupère si elle est déjà créée
SPWeb web = SPContext.Current.Web;
string listName = "Feature Logs";
SPList list = null;
foreach (SPList currentList in web.Lists){
if (currentList.Title.Equals(listName, StringComparison.InvariantCultureIgnoreCase)) {
list = currentList;
break;
}
}
if (list == null)
{
string descr = @"Liste utilisée pour logguer les évenements des features";
Guid listID = web.Lists.Add(listName, descr, SPListTemplateType.Announcements);
list = web.Lists[listID];
list.OnQuickLaunch = true;
list.Update();
}
return list;
}
public override void FeatureActivated(SPFeatureReceiverProperties properties) {
//Change la master page puis met à jour le site
SPWeb currentWeb = SPContext.Current.Web;
string currentWebUrl = currentWeb.Url;
currentWeb.MasterUrl = "/_catalogs/masterpage/coforcertinter.master";
currentWeb.Update();
//Crée un nouvel item dans la liste puis la met à jour
SPList aList = GetAnnouncementList();
SPListItem item = aList.Items.Add();
SPListItem item1 = aList.Items.Add();
SPListItem item2 = aList.Items.Add();
aList.Update();
//modifie le nouvel item créé puis le met à jour
item["Title"] = "Nouvel Evenement - " + properties.Definition.DisplayName;
item["Body"] = string.Format("La fonctionnalité {0} a été activé le {1}",
properties.Definition.GetTitle(CultureInfo.CurrentUICulture), DateTime.Now);
item["Expires"] = DateTime.Now.AddDays(1);
item.Update();
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties) {
SPWeb currentWeb = SPContext.Current.Web;
string currentWebUrl = currentWeb.Url;
currentWeb.MasterUrl = "/_catalogs/masterpage/default.master";
currentWeb.Update();
SPList aList = GetAnnouncementList();
SPListItem item = aList.Items.Add();
item["Title"] = "Nouvel Evenement - " + properties.Definition.DisplayName;
item["Body"] = string.Format("La fonctionnalité {0} a été désactivé le {1}",
properties.Definition.GetTitle(CultureInfo.CurrentUICulture), DateTime.Now);
item.Update();
aList.Update();
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties){}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties){}
}
}

Les méthodes se terminant en ing (FeatureUninstalling, FeatureDeactivating), sont des méthodes qui s'exécutent avant l'action ; ici ce sera avant la désinstallation ou avant la désactivation. Les autres se terminant en ed, s'exécutent après. Une fois ceci terminé, il ne reste plus qu'à traiter le déploiement et notre projet sera terminé.

III-D - Déploiement de nos features

Une fois nos features implémentées, il va falloir les déployer. Pour cela, rien ne vaut une bonne veille méthode « manuelle ». Pour déployer nos features, il va falloir les copier dans leur répertoire, à savoir le 12/Template/Features. De même, notre Assembly, il va falloir la déployer, soit dans le GAC, soit dans le bin de notre application web, et enfin copier également nos fichiers de ressources dans le répertoire 12/Resources.

Pour effectuer toutes ces taches, et être sur de n'en oublier aucune, rien ne vaut un bon script. Créez au sein de votre projet, un fichier « install.bat », et ajoutez-y ces quelques commandes :

@SET GACUTIL="C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe" %GACUTIL% -i bin\debug\Projet.dll
@SET TEMPLATEDIR="c:\program files\fichiers communs\microsoft shared\web server extensions\12\Template"
xcopy /e /y TEMPLATE\* %TEMPLATEDIR%
@SET RESOURCESDIR="c:\program files\fichiers communs\microsoft shared\web server extensions\12\Resources"
xcopy /e /y Resources\* %RESOURCESDIR%
@SET STSADM="c:\program files\fichiers communs\microsoft shared\web server extensions\12\bin\stsadm"
%STSADM% -o installfeature -filename Coforcert_MasterPages\feature.xml -force
%STSADM% -o installfeature -filename Coforcert_ApplyInternetMP\feature.xml -force
%STSADM% -o activatefeature -filename Coforcert_MasterPages\feature.xml -force -url http://wss3/sites/dev
cscript c:\windows\system32\iisapp.vbs /a "SharePoint - 80" /r

A la place de SharePoint - 80, renseignez le nom du pool d'application que vous utilisez, ou remplacez carrément toute la ligne par « IISRESET ». Néanmoins, l'utilisation de cette ligne par rapport à IISReset est un gain de temps considérable. Testez par vous-même ! Ensuite, étant donné que nous déployons notre Assembly dans le GAC, nous allons devoir la signer. Pour cela, dans l'explorateur de solutions, cliquez droit sur le nom projet et choisissez d'afficher ses propriétés.

Dans l'onglet « Signing », choisissez de signer l'Assembly

Ensuite, toujours dans les propriétés du projet, allez sur l'onglet « Build Events » et remplissez comme ci-dessous.

Vous spécifiez tout simplement à Visual Studio qu'à chaque fois qu'il réussit à compiler le code, il doit se positionner dans le répertoire du projet et exécuter le fichier install.bat A ce niveau, le déploiement des fichiers au bon endroit sera correctement effectué, d'ailleurs je vous conseille de le vérifier. Il vous faudra par la suite installer et activer les fonctionnalités. En fait l'installation des fonctionnalités a déjà été réalisée, ainsi que l'activation de la fonctionnalité niveau collection de site, grâce aux commandes suivantes exécutées dans le fichier bat.

%STSADM% -o installfeature -filename Coforcert_MasterPages\feature.xml -force
%STSADM% -o installfeature -filename Coforcert_ApplyInternetMP\feature.xml -force
%STSADM% -o activatefeature -filename Coforcert_MasterPages\feature.xml -force -url http://wss3/sites/dev

Si nous nous connectons dès maintenant à la page de gestion des features au niveau collection de site, nous obtenons le résultat ci-dessous.

La fonctionnalité a donc bien été installée ; cette fonctionnalité, rappelons-le, est censée déployer de nouvelles master pages dans la masterpage galerie ; allons le vérifier. Depuis la page de gestion du site, cliquez sur pages maitre.

Nous sommes redirigés vers la galerie des pages maitres, et cette dernière contient bien nos nouvelles pages maitres.

Si par contre nous allons sur la page de gestion des fonctionnalités du site web, cette dernière n'a pas encore été activée.

Nous pouvons activer/désactiver des fonctionnalités depuis l'interface web, mais pas les installer/désinstaller. Activons-la ! Instantanément, plusieurs choses se produisent ; d'une part, la master page change (dans mon cas j'ai fait une copie de la master page par défaut et rajouté du texte), ensuite une nouvelle liste nommée « Feature Log » fait également son apparition dans la quick lauch et de nouvelles annonces y sont publiées, et pour terminer une nouvelle action apparait dans le menu « Actions du Site ».

SI cependant, nous désactivons la fonctionnalité « Coforcert_MasterPages » et tentons d'activer la fonctionnalité « Coforcert_ApplyInternetMP », nous recevrons un message d'erreur lié aux dépendances qui existent entre les 2 fonctionnalités.

IV - Conclusion

Dans cet article, vous aurez appris à travailler avec les fonctionnalités de base liées aux Features.
Vous aurez notamment appris à :

1. Déployer des features

2. Creer des dependances de features

3. Creer un event receiver pour une feature

4. Utiliser les fichiers de ressources de langue avec des features

5. Rajouter une action dans le menu Action du Site grace aux features

6. Deployer de nouvelles master pages via des features et changer dynamiquement la master page via un evenement de feature

7. Mettre une master page en Cache dans une librairie de document

8. Creer une liste et ajouter des evenements, suite a l'activation d'une feature, etc...