MOSS 2007

[Visual Studio & SharePoint]–Paramètres remplaçables

Posted on Updated on

Bonjour à tous.

Si vous développez des projets SharePoint 2010 ou 2013 avec Visual Studio 2010 ou 2012, vous devez connaitre les paramètres remplaçable. En effet, Visual Studio vous permet d’utiliser des sortes de “Pragmas” remplacés à la compilation par Visual Studio lui-même.

Vous reconnaitrez ces paramètres remplaçables rapidement car ils sont entourés par des “$”, du type : $SharePoint.Project.FileName$

Vous retrouverez ces paramètres par exemple dans les pages d’application (Applications Pages), dans l’entête de chacune des pages :

<%@ Assembly Name=”$SharePoint.Project.AssemblyFullName$” %>

Lorsque on lancera la compilation du projet dans Visual Studio, ces paramètres seront remplacés par :

<%@ Assembly Name=”MonProjet.SharePoint, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXX” %>

Voici le tableau des paramètres remplaçables que vous pourrez utiliser :

Nom du paramètre Description
$SharePoint.Package.Name$ Nom du package
$SharePoint.Package.FileName$ Nom du fichier de définition du package
$SharePoint.Package.FileNameWithoutExtension$ Nom sans extension du fichier de définition du package
$SharePoint.Package.Id$ ID unique SharePoint du package
$SharePoint.Feature.FileName$ Nom du fichier de définition d’une fonctionnalité
$SharePoint.Feature.FileNameWithoutExtension$ Nom du fichier de définition d’une fonctionnalité sans l’extension du nom de fichier
$SharePoint.Feature.Id$ ID unique SharePoint de la fonctionnalité
$SharePoint.Feature.DeploymentPath$ Nom du dossier de la fonctionnalité dans le package
$SharePoint.Project.FileName$ Nom du projet
$SharePoint.Project.FileNameWithoutExtension$ Nom du projet sans l’extension
$SharePoint.Project.AssemblyFullName$ Nom complet de l’assembly du projet
$SharePoint.Project.AssemblyFileName$ Nom de l’assembly du projet
$SharePoint.Project.AssemblyFileNameWithoutExtension$ Nom de l’assembly du projet sans l’extension
$SharePoint.Project.AssemblyPublicKeyToken$ PublicKeyToken de l’assembly
$SharePoint.ProjectItem.Name$ Nom de l’élément de projet
$SharePoint.Type.[GUID].AssemblyQualifiedName$ Nom qualifié de l’assembly
$SharePoint.Type.[GUID].FullName$ Nom complet de l’assembly

Microsoft précise également que l’on peut utiliser ces paramètres remplaçables dans les fichiers de type :

  • XML
  • ASPX
  • ASCX
  • WebPart
  • DWP

Il est possible d’étendre ces possibilités en modifiant le fichier : Microsoft.VisualStudio.SharePoint.targets qui se trouve dans : …\<program files>\MSBuild\Microsoft\VisualStudio\v10.0\SharePointTools

01

On l’édite avec NotePad par exemple :

02

On ajoute des extensions de fichier supportées si besoin. Par contre, si on change de machine, on prendra cette configuration !!! Donc attention, ces paramètres ne seront plus remplacés.

En résumé, ces paramètres sont vraiment très pratiques, et on les utilise très souvent (Visual Studio en utilise lui aussi fréquemment lorsque l’on créé une page d’application par exemple).

Pensez-y !

Advertisements

Longueur maximum des Url dans SharePoint 2010

Posted on Updated on

Il arrive fréquemment qu’on me pose cette question… “Heu SharePoint c’est chouette mais là j’ai une url toute pourrie… comment ça se fait?” ou encore “Bah j’ai une erreur incompréhensible… jsé pas koi sur l’url…” (à quelques mots près…).

Effectivement il y a quelques pré-requis concernant les url dans SharePoint :

1/ On évite les url encodées (toutes pourries comme ils disent)

Effectivement, lorsque vous créez une liste/bibliothèque, SharePoint ne vous propose pas un champ url pour saisir l’adresse de cette liste/bibliothèque.

Tout simplement, il récupère le nom (“Title”) saisi et l’encode, par exemple : “Mes documents du projet” devient “Mes%20documents%20du%20projet” et remplace donc les espaces par des ‘%20’. Vous retrouvez donc dans l’url vers votre liste/bibliothèque : http://monserveursharepoint/sites/monsitesharepoint/Mes%20documents%20du%20projet.

Vous l’admettrez je l’espère, ce n’est pas très user friendly… C’est pour cette raison que Microsoft recommande de créer votre liste/bibliothèque avec un nom :

  • caractères en minuscule
  • Pas de caractères particuliers : quote, virgule, deux-points, etc.
  • court
  • renommer la liste/bibliothèque une fois créé (le nom interne ne change pas (internal name ou static name), seul le nom d’affichage change (Display name)

=> Il en est de même pour les répertoires (folders).

2/ Longueur des url

Effectivement les url sont limitées dans SharePoint (quelque soit la version)

  • Nom de répertoire : 128 caractère mais réellement limité à 123 (la textbox pour le nom du répertoire est limitée à 123 !!!)
  • Nom de fichier : 128 caractères (123 dans l’édition des propriétés du document… toujours à cause de la textbox. Mais depuis Office, 123 caractères + ‘.’ + extension (4 caractères : docx, xlsx, etc.) = 128 !!!)
  • Url complète jusqu’à votre document : 260 caractères

=> Attention !!! les nom encodés avec ‘%20’ comptent pour 3 caractères et pas seulement un espace !

Bien sûr SharePoint vous avertira avec un beau message d’erreur dans le cas d’un dépassement du nombre de caractères.

En espérant vous avoir inspiré 😉

Allez… c’est le moment “j’me la pète”

Posted on Updated on

Labs !!!

Posted on Updated on

Labs est un site dédié aux technologies Microsoft dont le but est de partager nos connaissances et notre passion.

Vous y retrouverez tous les articles, projets, KB, études de cas ainsi que les blogs des consultants de Bewise.

N’hésitez pas à nous envoyer vos retours !

Convertir un document Office docx en page html grâce à SharePoint–Partie 3

Posted on Updated on

Rappels

Dans les deux parties précédentes : Partie 1 et Partie 2, nous avons vu comment activer le service de conversion de documents à l’aide de l’administration centrale de MOSS 2007 puis comment créer les types de contenus et les bibliothèques de documents. Bien sûr, nous avons créé un package de déploiement avec WSPBuilder afin d’appliquer ces personnalisations sous la forme de fonctionnalités (features) dans SharePoint.

Une fois ce travail réalisé, dans cette partie donc, nous allons créer une action personnalisée (Custom Action) permettant de rediriger l’utilisateur vers une page personnalisée qui lancera la conversion.

Puis nous verrons comment démarrer un Workflow sur la finalisation de l’activité de conversion de documents.

C’est parti !

Création de la Custom Action

Qu’est-ce qu’une Custom Action ou Action Personnalisée ?

Une action personnalisée permet d’insérer des boutons, des liens dans les menus standards de SharePoint. Il sera donc possible au développeur d’ajouter des entrées dans le menu “Actions du site”, le menu de login, le menu contextuel sur chaque élément de liste, etc.

Elles permettent de s’intégrer facilement à l’interface de SharePoint afin d’y greffer ses propres éléments de menus. Ces custom actions ou actions personnalisées doivent être ajoutées dans une fonctionnalité (Feature) afin d’être déployées dans SharePoint.

Revenons à la solution Visual Studio précédemment créée. Nous allons maintenant ajouter cette custom action afin qu’elle soit déployée avec les types de contenus, les définitions de liste, etc. Nous allons également associer cette Custom Action avec la définition de liste pour que la nouvelle entrée dans le menu contextuel n’apparaisse que dans le contexte de cette liste (sur une instance d’une liste créée à partir de cette définition).

Cette action personnalisée se développe sous la forme d’une structure XML que l’on ajoutera à la définition de la feature.

Souvenez vous, dans la définition de la feature, nous avions précédemment déclaré un fichier “Elements.xml” dans le fichier “feature.xml” :

61

Ouvrons donc ce fichier “elements.xml” et ajouter la déclaration XML :

62

Dans cette déclaration :

  • Id = Un identifiant unique pour la custom action, format string ou GUID
  • Title = Texte qui sera affiché dans le menu de SharePoint
  • Location = localisation du menu dans l’interface SharePoint (voir tableau ci-après)
  • Description = Description longue de l’entrée de menu
  • RegistrationId = Identifiant du modèle visé (ici notre définition de liste, Type=1001)
  • RegistrationType = Type d’objet visé par l’action, ici “List”
  • Sequence = Ordre de l’entrée dans le menu : 0 en haut, supérieur à 0 vers le bas
  • Un sous élément UrlAction (voir après le tableau).

Vous pourrez trouver ici les autres paramètres disponibles pour la déclaration de l’action personnalisée à cette adresse : http://msdn.microsoft.com/fr-fr/library/ms460194(v=office.12).aspx.

Revenons à l’attribut “Location”. Ce paramètre indique à SharePoint où ajouter l’élément de menu. Vous trouverez ici : http://msdn.microsoft.com/fr-fr/library/bb802730(v=office.12).aspx toutes les possibilités afin de placer votre custom action.

Reste le dernier élément : “UrlAction”. Cela représente tout simplement l’adresse vers laquelle sera redirigé l’utilisateur lors du clic sur notre entrée de menu.

Ici donc, on utilise certaines variables : les “Jetons d’Url” disponibles lors de la déclaration d’une custom action comme ~site == site web courant, ~sitecollection == collection de sites et qui permettent de recomposer l’Url pour la redirection, sans faire de code qui devrait recomposer l’adresse.

D’autres “Jetons d’Url” sont également disponibles comme {ItemId} == identifiant de l’élément, {ListId} == identifiant de la liste, etc.

Vous pourrez trouver d’autres renseignements ici : http://msdn.microsoft.com/fr-fr/library/ms473643(v=office.12).aspx.

Dans l’exemple, on redirige l’utilisateur vers une page stockée dans le répertoire layouts > Exemple > PagesAdmin et qui s’appellera “ConvertDoc.aspx” avec ces paramètres :

  • ID = {ItemId} : identifiant de l’item courant
  • ListId = {ListId} : identifiant de la liste courante
  • SourceUrl = {ItemUrl} : Url de l’item courant => url de redirection lors de l’annulation
  • SiteUrl = {SiteUrl} => url pour la redirection

Attention certains nom de paramètres sont très mal acceptés par SharePoint, j’en avais déjà parlé dans un article précédent : https://kazoumoulox.wordpress.com/2009/04/07/sharepoint-aucun-element-nexiste-a-lemplacement/.

Pensez à séparer les paramètres dans l’url avec des “&amp;” qui équivaut à ‘&’ en html encodé.

Page de conversion

Il nous reste maintenant à créer la page qui sera appelée lors du clic… Nous savons déjà où la déployer et donc la placer dans la solution WSP !

En effet, dans l’UrlAction, nous avons spécifié une adresse qui renvoie vers une page stockée dans le répertoire 12/TEMPLATE/LAYOUTS. Pour ajouter la page, ajouter dans la solution Visual Studio le dossier LAYOUTS, puis le sous répertoire Exemple et enfin un sous répertoire PagesAdmin comme suit :

63

Nous allons maintenant ajouter la page ASPX ConvertDoc et son fichier de code behind. Pour cela, dans le répertoire PagesAdmin ajouter un fichier ConvertDoc.aspx.

Puis ajouter un répertoire Code et dedans un fichier ConvertDoc.cs (Ce fichier sera compilé dans l’assembly mais pas déployé tel quel sur le disque du serveur, on le met donc en dehors du répertoire 12) :

64

La structure est prête, maintenant place au CODE !!!

Première chose, renseigner le fichier aspx afin de lui indiquer que le code exécuté sera cela de la classe ConvertDoc contenue dans ConvertDoc.cs

On ouvre ConvertDoc.cs et on renseigne :

  • Le namespace : namespace Exemple.Pages.BackOffice
  • L’héritage de la classe : public class ConvertDoc : LayoutsPageBase (obligatoire pour une page placée dans le répertoire Layouts)
  • Les using utiles : au moins Microsoft.SharePoint en plus et pensez à ajouter les références vers les assemblies que vous allez utiliser comme System.Web.

65

Puis on va dans le fichier aspx et on ajoute les directive indiquant dans quelle classe se trouve le code behind de cette page, ainsi que l’import des DLL de SharePoint :

image

  • Première ligne : Assembly = On indique dans quelle assembly sera situé le code behind (nom complet : Name, Version, Culture et PublicKeyToken).
  • Seconde ligne : Langage de compilation (C#), et classe de laquelle devra hériter cette page : Exemple.Pages.BackOffice.ConvertDoc, masterpage utilisée : ~/layouts/application.master.
  • Troisième ligne : Import de l’assembly Microsoft.SharePoint
  • Quatrième ligne : Déclaration du TagPrefix SharePoint pour utiliser les composants/contrôles contenus dans la DLL Microsoft.SharePoint, dans le namespace : Microsoft.SharePoint.WebControls.

Il faut également déclarer certain contrôles Content utilisés par SharePoint (dans la masterpage avec les ContentPlaceHolderIDs) comme ceux utilisés pour le titre de la page, titre de la fenêtre Internet Explorer, la zone centrale, etc.

Pour cela, on utilise une déclaration de la forme :

<asp:Content ID=”Content1″ ContentPlaceHolderID=”PlaceHolderPageTitle” runat=”server”>
<SharePoint:EncodedLiteral ID=”EncodedLiteral1″ runat=”server”  Text=”Conversion de documents Word en Html”  EncodeMethod=’HtmlEncode’ />
</asp:Content>

Nous pouvons déjà vérifier que la custom action et la page sont correctement déployés et qu’ils sont bien intégrés à SharePoint. Pour cela, on compile la solution puis on la déploie à l’aide de WSPBuilder (voir partie 2).

En créant une nouvelle bibliothèque de document basée sur le modèle créé dans la partie 2, on ajoute un nouveau document. Une fois créé, on fait apparaitre le menu contextuel de l’élément et on vérifie que notre nouvelle entrée de menu soit bien présente :

image

Et en cliquant sur le lien, on arrive sur la page ConvertDoc (Dans laquelle j’ai déjà placé quelques contrôles comme une liste déroulante (DropDownList) et des LiteralControls) :

image

Nous allons donc remplir cette page, la structurer avec des contrôles asp.Net et coder les actions réalisées par ces contrôles.

Mais à quoi vont servir les contrôles dans cette page ? Tout simplement à choisir la bibliothèque de Pages d’un site de publication, que ce soit le site courant (racine) ou un sous site. Ainsi, on pourra depuis le site racine, créer des pages dans ce même site mais aussi dans ses sous sites de type publication.

On aura donc une bibliothèque de documents d’entrée et une fonction de conversion//routage de la page convertie vers une bibliothèque de pages.

Première chose, ajouter les contrôles dans la page en reprenant le style général des pages de backoffice de SharePoint. Pour faire cela, j’ai juste ouvert une page dans Internet Explorer et affiché la source… puis réutilisé le html que j’ai récupéré.

Pour pouvoir indiquer un titre à la page (fenêtre IE), un titre général et une description, j’ai ouvert cette même page dans Notepad, pour récupéré les ID des ContentPlaceHolders adéquats. Ce qui donne :

  • PlaceHolderPageTitle : Titre de la fenêtre Internet Explorer
  • PlaceHolderPageTitleInTitleArea : Titre dans la zone de titre de la page web
  • PlaceHolderPageImage : Image placée dans la zone de titre (vide dans l’exemple suivant)
  • PlaceHolderPageDescription : Description de la page courante

Dans la page :

<asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
<SharePoint:EncodedLiteral ID="EncodedLiteral1" runat="server" Text="Conversion de documents Word en Html" EncodeMethod='HtmlEncode' />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
    <asp:Literal ID="lblDescription" runat="server" Text="Conversion de documents Word en Html" />
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="PlaceHolderPageImage" runat="server">
    <img src="/_layouts/images/blank.gif" width="1" height="1" alt="">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="PlaceHolderPageDescription" runat="server">
    <SharePoint:EncodedLiteral ID="EncodedLiteral2" runat="server" Text="Conversion de documents Word en Html" EncodeMethod='HtmlEncode' />
</asp:Content>

Puis viendrons les contrôle de la page dans le ContentPlaceHolder Main :

<asp:Content ID="ContentMain" ContentPlaceHolderID="PlaceHolderMain" 
        runat="server">
	...
	...
</asp:Content>

Dans le fichier C#, on va déclarer les contrôle utilisés côté serveur, comme la liste déroulante qui sera remplie en utilisant le modèle objet SharePoint.

On trouve en premier quelques paramètres utiles :

private static string ItemIDParamName = "ID";
private static string ListIdParamName = "ListId";
private static string SourceUrlParamName = "SourceUrl";
private static string SiteUrlParamName = "SiteUrl";
private static string TranformerGuid = "6dfdc5b4-2a28-4a06-b0c6-ad3901e3a807";
private static Guid workflowGuid = new Guid("f3a6ce63-5696-4e0d-af6d-077c69b4f424");
  • Les noms des paramètres utilisés dans la QueryString (ID, ListId, SourceUrl et SiteUrl).
  • Le Guid représentant le “transformateur” => type de conversion utilisé par le job de conversion de documents.
  • Un Guid pour le workflow qui sera déclenché à la fin de la conversion.

Je n’ai pas encore bien expliqué le fonctionnement de cette page. En effet, lors du clic sur la custom action, SharePoint redirige l’utilisateur sur cette page. On affiche la liste déroulante proposant les bibliothèques de pages disponibles. Une fois cette dernière choisie, l’utilisateur clique sur “OK”, la conversion se lance (page d’attente de conversion).

La conversion terminée, on redirige vers cette même page, mais cette fois on propose à l’utilisateur de déclencher un workflow on de retourner à la page de départ (affichage de l’élément). Pour indiquer qu’on est dans la seconde étape, on utilisera des paramètres supplémentaires dans l’url :

  • converted : indique si le document est converti => true
  • targeturl : indique l’url du fichier converti

Premier étape : choix de la bibliothèque de sortie

1/ On teste le mode

2/ On initialise les contrôles de la page

3/ On charge les sites et webs et on parcours à la recherche des bibliothèques de type Pages

if (string.IsNullOrEmpty(GetFromQueryString("converted")) || 
     string.IsNullOrEmpty(GetFromQueryString("targetUrl")))
{
    InitializeControls();

    //La liste est chargée vite & inactive 
    using (SPSite currentSite = new SPSite(SPContext.Current.Site.ID)
    {
        using(SPWeb currentWeb = currentSite.OpenWeb(SPContext.Current.Web.ID))
        {
            PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(currentWeb);
            if(pubWeb != null)
            {
                 GetPagesListInPubWebs(pubWeb);
            }
        }
     }
     if (listToPublish != null && listToPublish.Count > 0)
     {
         LibraryList.Enabled = true;
         LibraryList.Items[0].Selected = true;
         selectedValueFromDDL = LibraryList.Items[0].Value;
         BtnOk.Enabled = true;
     }
}

Et la méthode de récupération récursive des bibliothèques de pages :

private void GetPagesListInPubWebs(PublishingWeb pubWeb)
{
     SPList pages = pubWeb.PagesList;
     if (pages != null)
         listToPublish.Add(pages);

     PublishingWebCollection pubs = pubWeb.GetPublishingWebs();
     if (pubs != null)
     {
         foreach (PublishingWeb pub in pubs)
         {
            GetPagesListInPubWebs(pub);
         }
     }

}

66

Lancement de la conversion de documents :

//Lancer la conversion en html
PublishingWeb targetPubWeb = PublishingWeb.GetPublishingWeb(targetWeb);
if (targetPubWeb != null)
{
    PublishingPageCollection Pages = targetPubWeb.GetPublishingPages();
    if (Pages != null)
    {
        using (SPLongOperation lo = new SPLongOperation(this))
        {
             lo.LeadingHTML = "Conversion du document en cours...";
             lo.TrailingHTML = "La conversion du document Word en Html est en cours.";

             lo.Begin();

             PublishingPage newPage = Pages.Add(currentFile.Item.DisplayName + ".aspx", currentFile, new Guid(TranformerGuid), PageConversionPriority.High);
             //newPage.CheckIn("Nouvelle page publiée");
             newPage.ListItem[SPBuiltInFieldId.Title] = currentFile.Item[SPBuiltInFieldId.Title];

             newPage.Update();

             currentFile.Item["Lien"] = string.Format("{0}{1}", targetPubWeb.Url.EndsWith("/") ? targetPubWeb.Url : targetPubWeb.Url + "/", newPage.Url);
             currentFile.Item.SystemUpdate(false);

             //lo.End(string.Format("{0}{1}", targetPubWeb.Url.EndsWith("/") ? targetPubWeb.Url : targetPubWeb.Url + "/", newPage.Url));
             lo.End(string.Concat(SiteUrl.EndsWith("/") ? SiteUrl : SiteUrl + "/", "_layouts/Exemple/PagesAdmin/ConvertDoc.aspx?ID=", ItemID,
                           "&ListId=", ListId, "&SourceUrl=", SourceUrl, "&SiteUrl=", SiteUrl,
                           "&converted=1&targetUrl=", string.Format("{0}{1}", targetPubWeb.Url.EndsWith("/") ? targetPubWeb.Url : targetPubWeb.Url + "/", newPage.Url)));

          }
      }
      else
           throw new Exception("La bibliothèque de pages cible n'a pas pu être trouvé.");
}

Ici on utilise une méthode de la classe PublishingPagesCollection, la méthode Add() qui permet de passer en paramètre le transformer GUID permettant d’indiquer qu’il faut effectuer une conversion de documents avant d’ajouter le fichier dans la bibliothèque de pages du site choisi.

A noter également que l’on utilise l’API SPLongOperation qui permet d’encapsuler l’exécution d’une procédure afin d’afficher dans SharePoint la page d’attente standard.

67

Deuxième étape : lancement du workflow

Lorsque la conversion est terminée, on redirige (Postback) l’utilisateur sur la même page, en ajoutant des paramètres dans l’url indique que la conversion est terminée et l’url de sortie du fichier converti. On peut donc afficher dans la page une CheckBox demandant si l’utilisateur souhaite déclencher l’association d’un workflow avec cette nouvelle page (par exemple un workflow d’approbation).

Si cette CheckBox est cochée et que l’utilisateur clique sur le bouton “OK”, alors on effectue cette association.

Notez qu’on indique aussi l’url vers le fichier converti afin de vérifier le résultat de cette conversion :

68

1/ Récupération des paramètres depuis la QueryString

2/ Récupération de l’item où “attacher” le workflow

3/ Associer le workflow et l’item, et le démarrer.

//Si l'utilisateur a choisi de lancer l'approbation, démarrage du workflow
if (ckbAppro.Checked)
{
    //récupération des paramètres
    string ItemID = GetFromQueryString(ItemIDParamName);
    string ListId = GetFromQueryString(ListIdParamName);
    string SourceUrl = GetFromQueryString(SourceUrlParamName);
    string SiteUrl = GetFromQueryString(SiteUrlParamName);
    string valueTargetSite = LibraryList.SelectedItem.Value;

    if (!string.IsNullOrEmpty(ItemID) && !string.IsNullOrEmpty(ListId) && !string.IsNullOrEmpty(SourceUrl) && !string.IsNullOrEmpty(SiteUrl) && !string.IsNullOrEmpty(valueTargetSite))
    {
        SPListItem currentItem = GetItemFormListAndId(ListId, ItemID, SourceUrl);
        if (currentItem != null)
        {
            SPWorkflowAssociation wrkAsso = currentItem.ParentList.WorkflowAssociations.GetAssociationByBaseID(workflowGuid);
            if (wrkAsso != null)
            {
                currentItem.Web.Site.WorkflowManager.StartWorkflow(currentItem, wrkAsso, wrkAsso.AssociationData, true);
                SPUtility.Redirect(currentItem.ParentList.DefaultViewUrl, SPRedirectFlags.Default, HttpContext.Current);
            }
        }
    }
}

Voila, la série d’articles se termine… voici les sources utilisées tout le long : Exemple Conversion

Bon code !

Convertir un document Office docx en page html grâce à SharePoint–Partie 2

Posted on Updated on

 

Rappels… et objectifs

 

Dans l’article précédent Partie 1, nous avons comment paramétrer simplement le service de conversion de documents au travers de la console d’administration SharePoint.

Nous avons également vu comment activer ce service dans une application Web choisie et même comment choisir les types de conversions disponibles dans celle-ci.

J’ai décidé d’écrire une suite d’articles reprenant le concept de conversion de documents et de l’intégrer au sein d’un développement réalisé pour MOSS 2007. Ce développement permettra d’utiliser la conversion de documents à partir d’une définition de bibliothèque de documents personnalisée et cette conversion produira des pages HTML automatiquement à partir de documents Office 2007/2010.

Nous allons donc voir comment créer une définition de bibliothèque de documents avec ses types de contenus associés, des colonnes de site et packager le tout dans cette partie.

La prochaine partie se concentrera sur une custom action permettant d’appeler une page “d’administration” personnalisée par nos soins. Cette page nous permettra, à terme, de renseigner certaines métadonnées ou des informations utiles, de vérifier que des conditions sont remplies, etc., avant de lancer la conversion.

Il sera également possible de lancer un workflow manuellement (par code),  de rediriger l’utilisateur vers une page souhaitée et il faudra aussi penser à gérer les cas d’erreur.

Nous penserons bien sûr à packager le tout dans une solution WSP grâce à Visual Studio 2008 et WSPBuilder que vous pouvez télécharger ici : WSPBuilder sur CodePlex.

 

Premières tentatives et échecs…

 

Le but de ce développement est d’intégrer la conversion d’un document Word en html à une page d’administration personnalisée appelée par une custom action. Bien sûr d’autres traitements seront réalisés dans le contexte de cette tâche… sinon on aurait pu utiliser la fonctionnalité standard proposée par SharePoint.

Donc première étape, vérifier la faisabilité de cette conversion par code.

Je me lance donc dans les premières recherches sur le net concernant le job de conversion… je trouve un article sur un blog (ici) que l’on peut interroger depuis du code .Net. Je me précipite donc avant de me rendre compte au bout de quelques minutes que cet article ne concerne que SharePoint Server 2010… et que je travaille sur MOSS 2007.

Du coup cela devient plus compliqué, pas d’API pour accéder au job permettant de lancer la conversion.

Idée suivante… analyser comment fonctionne la fonctionnalité standard, les pages utilisées. J’ouvre donc le fichier ConverterSettings.aspx situé dans 12/TEMPLATE/LAYOUTS/ avec Visual Studio et regarde l’héritage de la page.

On voit qu’elle hérite de :

Inherits="Microsoft.SharePoint.Publishing.Internal.CodeBehind.ConverterSettingsPage"

Classe VS 2008 - Conversion

 

Puis un petit coup de Reflector (ici) qui me permet d’analyser le code contenu dans les assemblies utilisées par ces pages. On charge donc l’assembly Microsoft.SharePoint.Publishing :

Reflector

 

La plupart des classes utilisées sont private ou internal… ça c’est une mauvaise nouvelle, impossible d’appeler ces classes directement… à moins de faire de la réflexion en .Net.

Cette solution ne me satisfait pas, il y a forcément plus simple !

Après quelques recherches, je me suis aperçu que sur un site de publication SharePoint, il existe une méthode Add() que l’on peut appeler sur la classe PublicationPages et qui permet de passer :

        • Un document docx ou xlsx, etc.
        • Un Guid “Transformer Guid”
        • Une priorité (low, normal et High).

        Reflector - PublishingPages

Je me suis donc penché sur cette méthode afin de parvenir à utiliser la conversion de documents par code. Première contrainte, utiliser un site de publication et la bibliothèque de pages “Pages” créée par défaut sur ce type de site. Deuxième contrainte, utiliser seulement des documents Office avec le modèle Open Document (donc à partir de Office 2007).

        Nous reviendrons à l’utilisation de cette analyse dans la partie 3 !

          Création de la définition de la bibliothèque et des types de contenu

          Création de la fonctionnalité (feature)

        Première chose, installer WSPBuilder si ce n’est déjà fait et lancer Visual Studio 2008.

        Créer un nouveau projet vide de type WSPBuilder
        Solution WSP 01
      Solution WSP 02

     

    Créer une fonctionnalité (feature) en ajoutant un élément sur le projet. Je choisis Site pour le Scope car je vais avoir des colonnes de sites et un type de contenu.

    Solution WSP 03

    Solution WSP 04

     

    Voici ce que WSPBuilder et Visual Studio vous ont créé :

    • Des répertoires : 12/TEMPLATE/FEATURES qui ciblent les répertoires d’installation de SharePoint 2007, appelés Hive ou Niche SharePoint.
    • Un répertoire ExempleConversion qui contiendra la fonctionnalité que nous allons créer
    • Deux fichiers XML
      • feature.xml : décrit le processus général du déploiement, c’est le point d’entrée pour SharePoint.
      • elements.xml : va décrire d’autres éléments à déployer
      • Vous pouvez en ajouter autant que vous voulez, comme nous allons le voir.

      Solution WSP 05

        Création d’un modèle de bibliothèque de documents personnalisé

        Pour commencer, je préfère intégrer une définition de bibliothèque de documents personnalisée à ma solution car cela me permet de déployer automatiquement toutes les briques nécessaires à cet exemple.
        Cette définition, lorsqu’elle sera déployée sera disponible dans la galerie des modèles de listes disponibles (lors de la création d’une nouvelle liste/bibliothèque) dès que la fonctionnalité sera activée.
        Pour se faire, j’ai juste créé une nouvelle bibliothèque de documents dans SharePoint, personnalisé les colonnes, types de contenus, vues puis utilisé un outil fourni dans les VSeWSS à savoir SharePoint Solution Generator (attention cela fonctionne très mal en 64bits…).
        Première étape, créé une collection de sites de type publication. Dans la “Console d’administration de SharePoint”, aller dans “Gestion des applications”, dans la section “Gestion des sites SharePoint”, “Créer une collection de sites

      Créer une collection de sites 01

       

      Renseignez les paramètres puis créez la collection de sites de type “Portail de publication

      Créer une collection de sites 02

       

      Créer une collection de sites 03

       

      En affichant tout le contenu du site, on remarque que la bibliothèque de pages a bien été créée :

      Contenu du site

       

      On va maintenant créer la bibliothèque de document personnalisée. Cliquez sur “Créer”.

      Dans la page de choix du type de liste/bibliothèque, choisissez “Bibliothèque de documents” et remplissez les champs. Vous pouvez choisir le type “”Document Microsoft Office Word” comme modèle de documents. Cliquez sur “Créer”.

      Création bibliothèque de documents

      La bibliothèque de documents est crée. Maintenant il faut la personnaliser en ajoutant les colonnes, vues, types de contenu, etc.

      Pour ma part, je vais créer un type de contenu avec un modèle de document Word “.dotx” et des colonnes tout en créant un package wsp.

      On créé donc le type de contenu en cliquant sur “Actions du site”, “Paramètres du site”, “Modifier tous les paramètres du site”. Dans la section “Galeries” sélectionnez “Types de contenu de site”. Dans la nouvelle page chargée, cliquez sur “Créer”.

      Création du type de contenu 01

       

      Nous allons en fait créer plusieurs types de contenu. Le but étant que l’on puisse créer rapidement de nouveaux types de contenu avec des modèles de documents associés différents.

      Donc le premier héritera du type de contenu “Document” et contiendra les colonnes de site communes à tous les types de contenu que je souhaite créer.

      Les autres hériteront de ce nouveau type de contenu et possèderont chacun leur modèle de document “dotx”. Ainsi je n’aurai pas à créer à chaque fois les colonnes de site communes à tous les type de contenu.

      Pour le type de contenu parent, renseignez les champs de cette manière et validez avec “OK”. On créé un type de contenu héritant de document et on le place dans un nouveau groupe “Exemple”.

      Création du type de contenu 02

      On personnalise ce content type en ajoutant les colonnes de site.

       

      Puis on créé un type de contenu par modèle de document en héritant de ce dernier. Voici un exemple :

      Création du type de contenu 03

       

      On ajoutera ensuite les colonnes de site supplémentaires et surtout le modèle de document adéquat dans les paramètres avancés de ce nouveau type de contenu.

      On créé donc un document Word 2010 dans mon cas, bien sûr au format dotx, basique. On pourra éventuellement utiliser les QuickParts afin de lier les colonnes du type de contenu  au document word, et donc les utiliser dans ce document en tant que métadonnées.

      Nouveau modele dotx

       

      Puis dans la page de “Paramètres avancés” du type de contenu, cliquez sur “Télécharger”, le document et validez la page.

      Ajout document au type de contenu

       

      Retournez sur les “Paramètres avancés”, le document est bien téléchargé. Cliquez sur le lien “Modifier le modèle”, Word se lance et vous permet de ré-éditer le modèle de document, comme par exemple pour lier des colonnes de sites de ce type de contenu au document par le biais de “QuickParts”.

      Edition modèle de document 01

       

      Mais où est donc téléchargé ce modèle de document ? A l’aide de SharePoint Designer 2007, vous pouvez voir que ce document est placé dans le répertoire “_cts” du site :

      SPDesigner Modele de document 

      C’est important car lors du packaging, nous allons déployer ce modèle de document au même endroit.

      Vous pouvez donc créer autant de types de contenu que souhaité en reproduisant ces manipulations.

      Il ne nous reste plus qu’à associer ce type de contenu à la bibliothèque de documents créée précédemment. On retourne sur la page où est affichée cette bibliothèque et on clique sur “Paramètres”, “Paramètres – bibliothèque de documents”.

      Ajout type de contenu 01

      Dans cette page, on clique sur “Paramètres avancés”

      Ajout type de contenu 02

      On autorise la gestion des types de contenu et on peut également interdire la création de dossiers, on valide la page.

      Ajout type de contenu 03

      Une nouvelle section apparait dans la page de paramétrage de la bibliothèque de documents

      Ajout type de contenu 04

       

      Dans cette section, cliquez sur “Ajouter à partir de types de contenu de site existants” et ajoutez le type de contenu que nous venons de créer et validez.

      Ajout type de contenu 05

       

      Vous pouvez également désactiver le type de contenu “Document” en cliquant sur le lien et en le supprimant (il ne sera que désassocié de cette bibliothèque, pas supprimé totalement bien entendu).

      En revenant sur la page d’affichage de la liste (page AllItems.aspx), en cliquant sur la flèche à coté de “Nouveau”, vous pouvez voir que le nouveau type de contenu est disponible, et en cliquant dessus, Word se lance avec le bon modèle de document

      Ajout type de contenu 06

       

      On ajoutera quelques documents pour les tests dans les parties suivantes.

       

      Création de la définition de bibliothèque de documents

       

      Afin d’arriver à déployer ma solution, je créé donc un package wsp. Il va déployer la définition de cette bibliothèque de documents sur les sites SharePoint quand la fonctionnalité sera activée.

      Pour créé cette définition, nous allons utiliser SharePoint Solution Generator, fourni par les VSeWSS. Attention, ils fonctionnent très bien en 32bits mais pas en 64 !!! Par ici.

      On choisi “List Definition”, “Next”.

      Solution Generator 01

      On entre l’url de notre bibliothèque et “Next”

      Solution Generator 02

       

      En on choisi notre bibliothèque et “Next”

      Solution Generator 03

       

      “Next”

      Solution Generator 04

       

      “Finish”

      Solution Generator 05

       

      La définition est générée, cliquez sur le lien en bas pour ouvrir le répertoire où la solution Visual Studio a été générée.

      Solution Generator 06

       

       

      Dans cette solution :

      • Un répertoire “Properties”
      • Un répertoire “Source Conversion” qui contient la définition et les fichiers nécessaires
      • Un fichier “csproj” pour ouvrir la solution dans Visual Studio
      • Un fichier de log de l’a création de la définition

      Solution Generator 07

       

      Copier le répertoire “Source Conversion” et allez le placer dans la solution créé dans Visual Studio, dans le répertoire de la “feature”.

      Solution Generator 08

       

      Allez dans Visual Studio, cliquez sur les deux icones en haut : “Show all files” puis “Refresh”

      Solution Generator 09

       

      Puis clic droit sur le dossier apparu et “Include In Project” (inclure dans le projet) :

      Solution Generator 10

      Le dossier et les fichiers contenus sont ajouté à la solution Visual Studio :

      Solution Generator 11

       

      Nous devons maintenant faire le nécessaire afin que ces fichiers soient déployés lors de l’activation de la fonctionnalité. En fait, les fichiers seront déployés sur le système de fichiers, dans le répertoire 12 de SharePoint (WSPBuilder copie par défaut les fichiers contenus dans ce répertoire 12 visible dans Visual Studio dans le répertoire 12 de SharePoint). Par contre ils ne sont pas encore référencés dans la fonctionnalité, nous allons le faire dès à présent.

      Ouvrez le fichier “feature.xml” dans Visual Studio. Modifiez les paramètres souhaités (voir SDK de SharePoint), ce qui est important :

      • Scope=”Site” car nous allons déployer des colonnes de sites et un type de contenu qui se déploient au niveau “Site”
      • Id : doit être unique, vous pouvez utiliser l’outil “Create GUID” de Visual studio (ici)
      • Hidden=”FALSE” pour que la fonctionnalité soit visible dans la page d’activation des fonctionnalités de la collection de sites
      • On ajoute la ligne <ElementManifest Location="ListTemplates.xml"/> pour séparer les déclarations de définitions de liste dans un fichier à part.
        On sauvegarde.

      Feature 01

       

      Puis dans le même répertoire que ce fichier “feature.xml”, on ajoute un autre fichier de type xml, nommé “ListTemplates.xml” qui vient d’être référencé dans le fichier précédent. On ouvre ce fichier.

      Feature 02

      On ouvre également le fichier “ListDefinition.xml” contenu dans le répertoire “Source Conversion” et on copie son contenu dans le fichier “ListTemplates.xml”. On aurait pu également déplacer ce fichier dans le bon répertoire et le renommer, mais je préfère le garder en référence le temps d’éditer le deuxième. Je supprimerai ce fichier en fin de manipulation.

      Gardez seulement ouvert le fichier “ListTemplates.xml”. Observez sa structure, il contient 3 lignes, 2 balises “Elements” et 1 balise “ListTemplate” qui est celle qui nous interesse.

      Nous allons modifier principalement 2 choses :

      • Type : créer votre propre identifiant de modèle de liste, pour ma part ce sera 1001
      • DocumentTemplate : 121 soit le modèle Word 2007/2010

      Feature 03

      Feature 04

      Sauvegardez, puis ouvrez le fichier “schema.xml” content dans le répertoire “Source Conversion” et modifiez l’attribut “Type” de la balise “List” en début de fichier "(2ème ligne) et mettez le même nombre que la balise “Type” dans le fichier “ListTemplates.xml”, soit 1001 et sauvegardez.

      Feature 05

      Vous pouvez maintenant supprimer le fichier “ListDefinition.xml” et également le fichier “template.dotx”, ajoutez à la place votre fichier “dotx” créé en début d’article (n’oubliez pas de les inclure dans la solution depuis l’arbre de projet).

      Feature 06

      Pour référencer ce modèle de document, nous allons devoir packager les types de contenu et changer les références vers ce fichier. C’est ce que nous allons voir dans la section suivante.

       

       

      Création de la définition de type de contenu

       

      Nous allons maintenant packager nos types de contenu dans la solution pour qu’ils soient déployés en même temps. Ce package embarquera également les colonnes de site utilisées par ces types de contenu et le modèle de document Office.

      Cette création du package reprend le principe précédent dans Visual Studio, mais j’utiliserai un outil afin d’extraire la définition de ces types de contenu : MOSS Content Types Viewer.

      Première étape, ajouter un fichier “ContentTypes.xml” dans Visual Studio, tout comme on l’a fait pour “ListTemplates”. Pensez à éditer le fichier “feature.xml” afin de référencer ce dernier fichier dans la fonctionnalité.

      Feature 07

      Feature 08

       

      Lancez le fameux outil MOSS Content Types Viewer et connectez le au site où l’on a créé les types de contenu puis recherchez les types de contenu voulus. Pour ma part, je veux récupérer le type de contenu parent et un enfant : Demande et Demande de réservation.

       

      Commençons par le type de contenu parent : Demande.

      Cliquez sur “Show Fields” puis sur le bouton en bas “Copy to Clipboard”.  Puis allez coller tout ça dans le fichier “ContentTypes.xml” en conservant les balises “Element”.

      Feature 09

       Feature 10

      Puis revenez dans l’outil d’extraction du type de contenu, et cliquez sur “Show Fields Refs” et copiez le contenu (sans la balise “Element”)

      Feature 11

       

      Et collez le contenu après les éléments collés précédemment (pensez à ajouter un tag fermant </ContentType>, l’outil l’oubli lors de l’extraction). Voici le résultat :

      Feature 12

      Faites de même avec le type de contenu fils : Demande de réservation. Attention, les balises <Fields> se répètent entre les deux types de contenu, pensez à supprimer les colonnes en double.

      Feature 13

       

      Il reste une toute dernière manipulation, référencer le modèle de document dans la définition du type de contenu et également dans la définition de la bibliothèque de documents ainsi que le déployer à l’aide d’un “Module”. Vous trouverez des informations utiles ici.

      Ouvrez le fichier “feature.xml” et ajoutez une ligne : <ElementFile Location="Source Conversion\Demande de reservation.dotx"/> dans les “ElementManifests” .

      Feature 14

       

      Puis ouvrez le fichier “ContentTypes.xml” et ajoutez le module comme suit : le fichier modèle de document Office sera déployé dans le répertoire _cts du site, dans un sous-répertoire portant le nom du type de contenu courant (nom interne).

      Feature 15

      Ouvrez donc le fichier “schema.xml” et localisez les tags XML “ContentTypes”. Vous trouverez dedans le content type que nous venons de créer. Supprimez les lignes le concernant et remplacez les par un ContentTypeRef pointant vers notre Type de Contenu tout en changeant le répertoire cible comme suit :

      Feature 16

      Voilà, tout est rassemblé dans le package wsp qui sera préparé par WSPBuilder dans Visual Studio. Pour cela, clic droit sur le projet, puis “WSP Builder” et enfin “Build WSP”

      Feature 17

      Puis même chose en cliquant sur “Deploy” et testez.

      Pour cela rendez vous dans la gallerie de fonctionnalités de la collection de sites. Il est possible que la fonctionnalité ne s’y trouve pas, elle n’a pas été installée par Visual Studio. Recourez à STSADM pour installer et déployer cette fonctionnalité avec stsadm –o installfeature et stsadm –o activatefeature (ici et ici).

      Une fois fait, activez la fonctionnalité et créez une bibliothèque de documents type “Source Conversion” et testez que vous pouvez ajouter des documents basés sur le modèle.

      Corrigez les éventuels problèmes que vous avez pu rencontrer en adaptant à vos besoins cette solution.

      Conclusion de cette partie

       

      Dans cette partie, nous avons vu comment utiliser Visual Studio 2008 et WSP Builder pour les développement autour de SharePoint 2007. Nous avons également utilisé des outils tiers, gratuits provenant la plupart du temps de Codeplex (vous y trouverez pléthore d’outils utiles…).

      Nous avons également vu comment créer une définition de bibliothèque de documents (s’adapte bien sur aux divers modèles de listes), des colonnes de sites, des types de contenus, et bien sur comment “packager” le tout afin de le déployer simplement dans SharePoint.

      Dans la prochaine partie, nous verrons la création d’une action personnalisée (custom action) permettant d’appeler une page d’administration que nous allons personnaliser également, tout en “packageant” encore et toujours grâce aux outils disponibles.

      Rendez-vous donc dans quelques temps !