Custom Field Types / Colonnes personnelles – PART 1

Le développement sous SharePoint est souvent associé aux WebParts, Event Handlers et Workflows. Néanmoins ce n’est pas tout, il est possible de développer bien d’autres éléments pour SharePoint. C’est le cas des colonnes personnelles encore appelées “Custom Field Types”. Qu’est ce que c’est et à quoi ca sert?

Lorsque vous ajoutez une colonne à une liste SharePoint vous avez le choix entre plusieurs types de colonnes en fonction des données que vous souhaitez y stocker. Et bien un custom field type correspond à un type de colonne que vous avez développé vous même avec vos petits doigts musclés. Les possibilités sont très intéressantes.

Je vous donne donc pour cette première partie un exemple très simple de Custom Field Type qui ne sert pas à RIEN pour le moment. Au final (dans quelques posts) vous disposerez d’une colonne recherche avec filtre CAML. Dans cet exemple la colonne sera composée de deux Textbox : Prénom et Nom. Les valeurs seront alors stockées sous la forme prénom;nom mais seront restituées correctement lors de l’affichage.

Le principe

Les différents types de colonnes sont définis par des fichiers XML dont le nom commence par fldtypes et qui se trouvent dans le 12 HIVE\TEMPLATE\XML (12 HIVE correspond au répertoire C:\Program Files\Common Files\Microsoft Shared\web server extensions\12).

Nous allons donc déployer un certain nombre d’éléments dont un fichier fldtypes qui décrira notre colonne. Ce fichier référence une classe héritant de SPFieldText qui gèrera le fonctionnement global de notre colonne (c’est elle qui définit sous quel format la valeur de la colonne est récupérée, quel contrôle est chargé de l’affichage).

Cette classe permettra d’instancier un contrôle de rendu (classe héritant de BaseFieldControl dans notre cas) qui se charge d’effectuer le rendu de la colonne en mode “New” et “Edit” (nous verrons en temps voulu comment se fait l’affichage en mode “Display”). Comme si tout cela n’était pas déjà assez compliqué nous allons également utiliser un modèle de rendu de champ (fichier ascx à placer dans 12\TEMPLATE\CONTROLTEMPLATES) dont je détaille l’utilisation dans l’étape 3.

Etape 1 : Création du projet

Chose importante : il vous faut STSDEV. Si vous ne connaissez pas cet outil merveilleux alors surfez au plus vite sur http://www.codeplex.com/stsdev des vidéos de démo sont disponibles. Créez alors un projet nommé “MyFirstCustomField” de type “Empty Solution (C# assembly)” à l’aide de STSDEV. Ouvrez ensuite la solution générée avec Visual Studio.

Etape 2 : fldtypes

Si vous avez regardé les vidéos présentes sur le codeplex STSDEV vous devriez avoir compris que le répertoire RootFiles de votre projet Visual Studio correspond au 12 HIVE. Créez donc un dossier TEMPLATE dans RootFiles puis un dossier XML dans TEMPLATE et ajoutez-y un fichier fldtypes_myfirstcustomfield.xml. Important : le nom du fichier DOIT commencer par fldtypes.

TypeName : correspond au nom interne de votre champ.
ParentType : type de contenu parent. Pour le moment nous utiliserons Text par la suite nous choisirons Lookup pour créer un champ de type de recherche.
TypeDisplayName : nom de votre colonne utilisé dans l’interface utilisateur SharePoint.
TypeShortDescription : description utilisée lors de l’ajout de la colonne à une liste
FieldTypeClass : référence complète de la classe associée à votre custom field. Pour le moment nous n’avons pas créé cette classe mais cela ne nous empêche pas de renseigner la propriété.

Comment obtenir la valeur de FieldTypeClass?
Si vous débutez dans le développement de solutions SharePoint c’est peut-être la question que vous êtes en train de vous poser. Sachez que le code que vous déployez doit être signé pour être utilisé par SharePoint. C’est pour cela qu’à la création de votre projet avec STSDEV un fichier de clé vous a été demandé. C’est à cela que sert le PublicKeyToken. Le plus simple pour récupérer notre valeur est d’utiliser un petit utilitaire bien connu des codeurs .Net : Reflector.
Commencez par générer votre solution (en mode DebugBuild) puis ouvrez la DLL générée (MyFirstCustomField.dll) à l’aide de Reflector.

La valeur Name correspond donc à notre assembly. C’est un bon début mais ce n’est pas suffisant. En effet la propriété FieldTypeClass n’indique pas l’assembly mais la classe qui sera utilisée. On rajoute cette information sous la forme Namespace.Classe ce qui nous donne dans notre cas: MyFirstCustomField.MyFirstCustomField, MyFirstCustomField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4d2fbb5068cc2292.
Ici le namespace est donc MyFirstCustomField et la classe se nommera MyFirstCustomField également.

Etape 3 : Le rendu

Dans ce type de projet le rendu est relativement important puisque c’est justement l’intérêt d’un Custom Field : effectuer un rendu personnalisé des données contenues dans les listes SharePoint. Le fonctionnement est similaire à celui des Web UserControl que l’on utilise en ASP .Net.

Voyons cela en détail…

Ajoutez un fichier XML “MyFirstCustomFieldControl.ascx” dans RootFiles\TEMPLATE\CONTROLTEMPLATES (à vous de créer l’arborescence). Voici son contenu:

Maintenant nous allons créer le code-behind. Ajoutez une classe “MyFirstCustomFieldControl” à la racine de votre projet.

Vous remarquerez la présence d’un contrôle RenderingTemplate, il est obligatoire! C’est grâce à ce contrôle que SharePoint fait le lien entre votre fichier ASCX et votre code behind (et oui rien à voir ici avec les classes partielles des User Controls d’ASP .Net).

Ajoutez maintenant une classe publique “MyFirstCustomFieldControl” à la racine de votre projet et faites la hériter de BaseFieldControl. Première chose à faire : overrider la propriété DefaultTemplateName afin de pouvoir faire le lien entre notre contrôle de rendu et le modèle de rendu de champ

 

Important: la valeur retournée par cette propriété doit correspondre à l’ID du RenderingTemplate.

Comment accéder à nos contrôles depuis le code behind? Commencons par les déclarer comme membres de la classe:

 

On override CreateChildControls pour récupérer et initialiser les contrôles:

 

 

Le code est ici très simple puisque nous n’avons aucun traitement à réaliser. On se contente simplement de récupérer les contrôles qui se trouvent dans le RenderingTemplate. Notez que notre contrôle ne sera pas utilisé pour l’affichage du champ ce qui explique le return lorsque ControlMode est à Display.

Il nous reste maintenant à définir comment récupérer la valeur de notre champ et comment initialiser nos contrôles lors de l’édition (il faut en effet récupérer la valeur existante et initialiser nos éléments en conséquence). Cela se passe dans la propriété Value:

 

 

Ici le traitement est très simple. On stocke les valeurs des textbox sous la forme prenom;nom et lorsque l’on Set la valeur du champ on récupère chaque partie que l’on assigne sur la bonne textbox.

Etape 4 : MyFirstCustomField.cs

Il ne nous reste plus qu’à créer la classe qui va représenter notre Custom Field. Cette classe permet de gérer les évènements qui se produisent lorsqu’une colonne de ce type est ajoutée, modifiée, supprimée. Elle permet également de gérer les différentes propriétés associées à la colonne et d’indiquer le contrôle à utiliser pour effectuer le rendu.

Ajoutez donc une classe “MyFirstCustomField” à la racine de votre projet. Déclarez la classe public et faites la hériter de SPFieldText. Définissez les deux constructeurs suivants:

On indique maintenant quel contrôle utiliser pour effectuer le rendu à l’aide de la propriété FieldRenderingControl:

 

 

Etape 5 : RenderPattern

On y est presque, la colonne s’affiche lors de l’ajout et de l’édition et est capable d’enregistrer des valeurs. Néanmoins les valeurs stockées le seront sous la forme prénom;nom. Etant donné que le type parent de la colonne est Text, ces valeurs seront rendues sous ce format lors de l’affichage. La plupart du temps lorsque l’affichage des valeurs est peu complexe on utilise le CAML et les RenderPatterns. Dans notre exemple j’utilise un petit bout de code Javascript pour formater la valeur de la colonne. Voici le contenu du fichier fldtypes_myfirstcutomfield.xml une fois le RenderPattern ajouté:

Je vous l’accorde ce n’est pas très esthétique et surtout ca risque de planter assez facilement si on s’amuse à mettre n’importe quoi comme valeur. Cela vous permet néanmoins de vous faire une idée.

Vous remarquerez l’utilisation de l’élément Column qui fait référence à la valeur de la colonne.

Etape 6 : le déploiement

Voilà c’est terminé (ouf). Il ne vous reste plus qu’à utiliser la cible “DebugDeploy” de votre projet et à générer la solution. Si vous modifiez votre code je vous conseille d’utiliser ensuite la cible “DebugRedeploy”

Ajout de la colonne

Ajout élément

 Affichage liste

Dans la prochaine partie nous verrons comment modifier ce projet afin de créer une colonne de type recherche sur laquelle nous pourrons configurer une requête CAML afin de filtrer les éléments.

Adieu Lycos, bonjour Ikoula

Et oui Lycos Hébergement ferme ses portes. L'activité ne serait plus suffisament rentable et le groupe a donc décidé d'y mettre un terme. Je vous laisse imaginer ma tête lorsque j'ai reçu le premier message d'avertissement à ce sujet. J'avais choisi Lycos il y a bien 7 ans de cela car c'était tout simplement l'un des plus connus, j'étais sur qu'il n'arriverait jamais rien à mes données. Raté.

Heureusement les clients ont été prévenus à temps afin de pouvoir migrer les données en toute sérénité. Néanmoins pour ma part je n'ai jamais réussi à joindre le support technique de Lycos, ils étaient déjà partis.

Il a donc fallu que je trouve un nouvel hébergeur pour Wawawum ainsi que deux autres sites dont je m'occupe sur le plan technique. Je commence par voir du côté d'OVH, celui dont j'entends le plus parler. Je tombe alors sur des offres qui me surprennent: 2,4Go pour un 240 PLAN (nom du pack) à 8,47€ TTC par mois, 7,2Go pour un 720 PLAN à 17,44€ TTC par mois. Mais bon sang moi j'ai besoin d'espace, de liberté !!! Où vais-je pouvoir stocker d'éventuels WebCasts avec aussi peu d'espace Web?
Ce qui m'étonne encore plus c'est de voir que l'espace Web est réduit au profit de l'espace destiné aux e-mails. Sur le 720 PLAN il est indiqué 1000 comptes e-mails de 2Go. J'aimerais qu'on m'explique, s'agit-il de 1000 comptes mail qui peuvent au total consommer 2Go d'espace? Merci de commenter sur ce point.

Bref, j'ai regardé les offres de plusieurs hébergeurs mais elles étaient toutes similaires à celles que je viens de décrire. Impossible pour moi de migrer mes sites qui jusque là bénéficiaient de 10Go d'espace pour plus ou moins 150€ par an domaine compris.

Heureusement mon cher colloc m'a trouvé l'hébergement de mes rêves, merci Moh. Me voici donc avec un serveur virtualisé tournant sous Windows Server 2008 Enterprise Edition ce qui me permet de faire tourner des sites aussi bien en PHP qu'en ASP.Net. De quoi profiter des 20 Go d'espace disque qui me sont alloués. Je tiens également à souligner le professionalisme de l'équipe technique qui est allée jusqu'à m'appeler sur mon numéro personnel pour s'assurer que j'avais bien compris comment fonctionnait leur offre. J'avais je n'aurais imaginé cela de la part de Lycos. Ah oui j'ai oublié de citer le nom de cet hébergeur : iKoula. J'en suis pour le moment pleinement satisfait, le serveur qui ne dispose pourtant que de 512 Mo de RAM tourne très bien et héberge du coup mes 3 sites pour une vingtaine d'euros par mois.