Package

[eBooks] – Collection d’ebooks gratuits

Posted on Updated on

Bonjour à tous.

 

Aujourd’hui, pas d’article technique mais une collection d’ebooks gratuits à télécharger (en anglais) de tous types :

  • Office & Office 365
  • SharePoint
  • SQL Server
  • System Center
  • Visual Studio
  • Web development
  • Windows
  • Windows Azure

Et en plusieurs formats pour la plupart : PDF, EPUB, MOBI. On ne va pas se priver !

Ca se passe par ici : http://blogs.msdn.com/b/mssmallbiz/archive/2013/06/18/huge-collection-of-free-microsoft-ebooks-for-you-including-office-office-365-sharepoint-sql-server-system-center-visual-studio-web-development-windows-windows-azure-and-windows-server.aspx

 

Bonne lecture !

Advertisements

[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 !

SP2010–Remplacer les formulaires–Part 2

Posted on Updated on

Bonjour à tous.

Dans la partie précédente, nous avons vu comment créer trois modèles de listes SharePoint 2010 (fonctionnera également avec 2007 et 2013, Server ou Foundation). Avec ces modèles nous avons déployé pour chacun d’eux une instance : Pays, Villes et Commandes.

Le tout bien sûr “packagé” dans une solution SharePoint avec Visual Studio 2010. Ainsi nous avons utilisé une “Feature” pour déployer le tout qui, lorsqu’elle s’active, déploie les modèles, créée les instances de ces listes et remplit les listes Pays et Villes avec un ensemble de données.

Dans cette nouvelle partie, nous allons tenter de remplacer les formulaires standards :

  • DispForm.aspx
  • NewForm.aspx
  • EditForm.aspx

Dans le but de surcharger leur comportement, principalement au niveau des listes déroulantes : la liste des villes disponibles sera filtrée en fonction du pays qui sera sélectionné.

Pour compléter, vous pourriez également faire appel à quelques projets CodePlex fournissant ces listes déroulantes liées par le biais de champs personnalisés (Custom Fields) qui sont réutilisables et en soit plus “propres”. Je vous propose une autre méthode, sans passer par ces fonctionnalités additionnelles, plus dans le cas d’un usage unique.

1/ Comprendre la structure – le pourquoi…

Avant d’entamer la phase technique du développement/déploiement, il est essentiel de comprendre comment fonctionnent les formulaires standards, où ils sont déployés, etc.

Vous pouvez utiliser SharePoint Manager 2010 ou SharePoint Designer 2010 pour explorer la structure utilisé par les listes pour rediriger l’utilisateur vers ces fameux formulaires lorsqu’il souhaitera ajouter/modifier/voir les propriétés d’un élément/document dans une liste/bibliothèque de documents SharePoint. La structure est plutôt simple. Elle se compose de :

  • Un répertoire racine : RootFolder. Ce répertoire est créé par défaut.
  • Des sous-répertoires créés par les utilisateurs
  • Des items/documents créés par les utilisateurs
  • Un répertoire particulier : “Forms” qui contient les formulaires en question pour les bibliothèques de documents
  • Pour les listes, les formulaires en questions sont placés directement dans le RootFolder.

0102

Il m’est arrivé, bien souvent, de reprendre des projets SharePoint, par les biais de missions de conseil, d’assistance et je vois assez régulièrement des développeurs ayant essayé de “surcharger” ces formulaires en créant leurs propres formulaires (par copier/coller)… ayant des nom différents. Et en général… :

  • DispForm.aspx devient DisForm2.aspx
  • NewForm.aspx devient NewForm2.aspx
  • EditForm.aspx devient EditForm2.aspx

Et moi…. ça ne me convient pas ! En effet, les anciens formulaires restent disponibles, ils ne sont pas masqués… et restent donc accessible pour quelqu’un d’observateur qui saura assez rapidement appeler ces url et pourra donc se passer des règles de gestion que l’on souhaite imposer. Nous allons voir maintenant comment écraser ces fichiers standards en déployant notre solution SharePoint et les associer à nos listes Villes et Commandes.

2/ Déployer des Formulaires personnalisés

Reprenons notre solution. On remarque tout de suite que nous n’avons aucun fichier “aspx” dans les répertoires de la solution (répertoires des listes en particulier).

Première manipulation : utiliser SharePoint Designer 2010 pour récupérer les fichiers “aspx” originaux.

On commence donc par lancer SharePoint Designer 2010 (de préférence en 32bits Clignement d'œil), on se connecte donc sur le site et utilise l’explorateur pour atteindre notre liste, Villes par exemple (via l’explorateur à gauche “All Files > Lists > Villes”) :

image

03

On remarque tout de suite la présence des fichiers qui nous intéressent. Manipulation assez simple, on ouvre chacun des fichiers (en mode Avancé : clic droit sur chaque fichier > Ouvrir en mode avancé) et on copie/colle le contenu de chacun dans un fichier (avec Notepad ou autre) le but étant de sauvegarder chacun de ces fichiers dans le répertoire de la solution, à l’intérieur du dossier concernant notre liste et bien sûr avec le nom qui va bien… :

04

On copie le contenu du fichier…

05

Dans un Notepad :

06

On sauvegarde dans les répertoires Windows des définitions des listes Villes et Commandes, puis on inclut les fichiers dans la solution SharePoint :

07

Les nouveaux fichiers sont inclus :

08

Il reste ensuite une dernière manipulation à faire, sur chacun de nos fichiers aspx ajoutés dans la solution, nous allons faire un clic-droit > Propriétés :

09

Et nous allons changer la propriété “Deployment Type” en “ElementFile” (on peut vérifier le répertoire de déploiement qui doit pointer vers le répertoire de sortie de la feature dans le répertoire 14 (SharePointRoot) :

10

On reproduit ceci sur chacun des fichiers aspx. Vous pouvez vérifier dans le fichier “SharePointProjectItem.spdata” (celui au niveau de la déclaration du modèle de liste) que les modifications ont bien été apportées :

11

Notre solution est donc enrichie avec ces nouvelles pages. Toutefois, si l’on déploie ces nouvelles pages aspx directement, l’instance déployée n’utilisera pas directement nos nouvelles pages. Pour cela, nous allons devoir modifier le fichier Schema.xml pour chacune de ces listes, au niveau du nœud “Forms” (tout à la fin du fichier) :

<Forms>
<Form Type=”DisplayForm” Url=”DispForm.aspx” SetupPath=”pages\form.aspx” WebPartZoneID=”Main” />
<Form Type=”EditForm” Url=”EditForm.aspx” SetupPath=”pages\form.aspx” WebPartZoneID=”Main” />
<Form Type=”NewForm” Url=”NewForm.aspx” SetupPath=”pages\form.aspx” WebPartZoneID=”Main” />
</Forms>

Chaque formulaire/page est associé à notre liste SharePoint par le biais d’un nœud <Form />.

Nous allons modifier chacun de ces nœuds <Form /> pour indiquer à SharePoint qu’il doit utiliser nos pages et pas celles par défaut. Nous allons donc supprimer l’attribut SetupPath pour faire pointer chacun des formulaires vers nos pages custom.

Nous allons également ajouter quelques attributs :

  • Path=”NewForm.aspx” => Chemin relatif vers le fichier NewForm.aspx dans notre solution
  • Default=”TRUE” => Page par défaut
  • UseDefaultListFormWebPart=”False” => Ne pas utiliser le WebPart Standard
  • WebPartOrder=”1″ => Le WebPart sera placé en premier dans la zone de WebParts (il n’y en aura qu’un dans la page de toute manière)

Ce qui donne :

<Form Type=”NewForm” Url=”NewForm.aspx” Path=”NewForm.aspx” WebPartZoneID=”Main” Default=”TRUE” UseDefaultListFormWebPart=”False” WebPartOrder=”1″>

</Form>

Nous allons ensuite ajouter le WebPart de type ListFormWebPart dans la page NewForm.aspx pour afficher le formulaire standard. Il existe plusieurs méthodes que vous retrouverez sur Google, Bing ou autre.

Pour ma part, je vais choisir une méthode moins traditionnelle qui consiste à placer ce WebPart directement dans la déclaration de l’association du formulaire d’ajout d’élément et notre page custom (toutes les méthodes sont possible, celle-ci n’est pas meilleure !… juste différente). Nous allons ajouter un tag <WebParts> directement dans le <Form/> précédent, qui contiendra la déclaration du WebPart de type ListFormWebPart. Certains ont déjà du croiser ce type de déclaration, très utilisé lorsqu’on déploie des pages web avec des Modules. On obtiendra :

<Forms>

<Form Type=”NewForm” Url=”NewForm.aspx” Path=”NewForm.aspx” WebPartZoneID=”Main” Default=”TRUE” UseDefaultListFormWebPart=”False” WebPartOrder=”1″>
<WebParts>
<AllUsersWebPart WebPartZoneID=”Main” WebPartOrder=”1″>
<![CDATA[
<WebPart xmlns=”http://schemas.microsoft.com/WebPart/v2″>
<Assembly>Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<TypeName>Microsoft.SharePoint.WebPartPages.ListFormWebPart</TypeName>
<PageType>PAGE_NEWFORM</PageType>
</WebPart>]]>
</AllUsersWebPart>
</WebParts>
</Form>
</Forms>

On déclare ici un WebPart de type Microsoft.SharePoint.WebPartPages.ListFormWebPart dans la zone “Main”. Notez également le tag PageType qui a la valeur PAGE_NEWFORM indiquant qu’il s’agit bien de ce WebPart dans le mode de rendu “New” (nouvel élément). Vous trouverez ici les valeurs possibles pour cette énumération : http://msdn.microsoft.com/fr-fr/library/microsoft.sharepoint.pagetype(v=office.12).aspx

On reproduit cela pour chacun des formulaires, sur nos listes Villes et Commandes :

18

Mais me direz-vous, nous avons copié les pages NewForm, DispForm et EditForm avec SharePoint Designer et ce WebPart devrait être déjà présent dans les pages… Oui tout à fait, c’est pour cela que nous allons le supprimer !

On ouvre donc un à un chacun des fichiers NewForm.aspx, EditForm.aspx et DispForm.aspx (pour les listes Villes et Commandes) et on recherche :

<WebPartPages:ListFormWebPart runat=”server” __MarkupType=”xmlmarkup” ……… </WebPartPages:ListFormWebPart>

On sélectionne le tout et on supprime tout le contenu de cet élément (l’élément y compris) :

19

On sauvegarde le tout.

Pour préciser pourquoi on ne conserve pas ce WebPart dans les pages, vous avez peut être remarque qu’il possédait la propriété ListId. Malheureusement, cette propriété est valorisée avec un GUID qui représente l’identifiant unique de la liste… et qui sera différent à chaque redéploiement de notre Solution. Impossible donc de packager ce composant directement avec le bon GUID. Vous pourrez par contre utiliser l’attribut ListName valorisé avec l’url relative de la liste.

Il nous reste à compiler, déployer… Pour vérifier que les fichiers sont bien déployés et écrasent bien les fichiers natifs, il faut changer un peu le contenu de la page (le bon vieux test du TOTO dans la page Clignement d'œil)…

Pour cela, j’ai choisi le formulaire NewForm.aspx de la liste de Commandes. Dans le ContentPlaceHolder “PlaceHolderPageTitle”, j’ajoute un TOTO :

20

On compile avec Visual Studio et on déploie sur notre plateforme SharePoint. Une fois le tout déployé, je me dirige vers ma liste de Commandes dans le navigateur, je clique sur nouveau :

21

On retrouve bien le TOTO dans le titre de la fenêtre !!! (Bien sûr on supprime le TOTO Sourire et on redéploye).

Ca c’est fait.

3/ Modifier le comportement des pages

Nos pages étant maintenant déployées, nous allons modifier leur héritage natif pour les faire hériter de classes contenues dans notre propre assembly (DLL). Pour cela, nous allons créer une classe C# pour chacun des pages NewForm, DispForm & EditForm, et ce pour chacune de nos listes (donc 6 classes dans mon cas).

En général, je créé un répertoire Pages à la racine de mon projet (les pages sont compilées dans la DLL et le fichier .cs n’est pas déployé). Une fois le dossier créé, j’ajoute 6 classes :

14

15

Ensuite, nous allons faire hériter chacune de ces classes de “WebPartPage” et ajouter “using Microsoft.SharePoint.WebPartPages” :

16

Ensuite, dans chacune des pages aspx, nous allons :

  • Ajouter tout au début :  <%@ Assembly Name=”$SharePoint.Project.AssemblyFullName$” %>
  • Modifier le Inherits pour pointer vers notre assembly :

Inherits=”Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint, Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c”

devient

Inherits=”DEMO1.Pages.CommandesNewForm,$SharePoint.Project.AssemblyFullName$”

Où :

  • DEMO1.Pages.CommandesNewForm = Namespace + nom de la classe
  • $SharePoint.Project.AssemblyFullName$ : nom complet de l’Assembly, valorisé par Visual Studio avant le déploiement.

On recommence la manipulation sur chacune des 6 pages aspx:

22

On compile/déploie à nouveau le tout. Pour tester que le code-behind est bien appelé, on peut passer en debug sur la solution et vérifier que la méthode OnLoad() est bien appelée :

23

Et voilà !

Je me décide enfin à publier cet article…, je continuerai la suite un peu plus tard ! Au programme, personnalisation du comportement des formulaires !

Wait & see (pas trop longtemps j’espère Sourire) !

SP2010-Remplacer les formulaires – Part 1 – Template de Liste

Posted on Updated on

Bonjour à tous.

Cela fait maintenant quelques semaines que je n’ai pas bloggé, je profite d’une petite “accalmie” pour publier un article qui vous montrera comment déployer des formulaires NewForm.aspx; EditForm.aspx et DispForm.aspx dans SharePoint 2010 (fonctionnera également avec SharePoint 2007 & 2013).

Bien souvent, quand je me déplace chez des clients ou que je reprend des développements qui ont été réalisés, je m’aperçois que ces formulaires ont été ré-implémentés et redéployés par le biais d’une solution SharePoint, ce qui est plutôt bien. Ce qui me choque en général, c’est que ces formulaires ne viennent pas remplacer “physiquement” les existants mais s’ajoutent aux formulaires existants, avec des nouveaux noms : newform2.aspx, editform2.aspx ou encore dispform2.aspx.

Si des utilisateurs (malins) connaissent les url vers les formulaires natifs, ils pourront toujours les utiliser !!! Et ça, c’est vraiment pas bien !

Je vais donc tenter de vous expliquer comment remplacer ces formulaires (les écraser en fait) par le biais d’une solutions SharePoint… et sans utiliser du C# => Chalenge Sourire

Nous essaierons d’utiliser au maximum les API natives de SharePoint et les fichiers XML de déploiements supportés.

Dans un second temps, j’aimerai également vous montrer comment remplacer/overrider le comportement natifs des contrôles dans ces formulaires… mais ça sera pour un prochain article !

Première chose, se connecter sur une collection de sites, un site et créer une liste. Dans mon cas ce sera une liste custom… et même une seconde liste que je créée par avance pour la suite de l’article. Je vais également créer une colonne de type lookup (recherche d’éléments déjà présents sur le site) qui “reliera” mes deux listes… Et encore une troisième qui utilisera elle aussi une colonne de type lookup :

On aura donc trois listes avec leurs attributs :

image

  • Pays contiendra le nom du pays, sa surface et son nombre d’habitants
  • Ville contiendra le nom de la ville, le pays d’appartenance, sa surface et son nombre d’habitants
  • Commande contiendra le titre de la commande, le montant, le pays et la ville. Dans un premier temps on utilisera deux lookup, pointant sur chacune de listes pays & ville. On remplacera plus tard ce comportement par des listes déroulantes liées et pré-filtrées. On sélectionnera le pays et cela filtrera la liste des villes proposées. Mais tout cela dans un second temps.

1/ Commençons par créer une solution avec Visual Studio 2010

NB : il faudra travailler un maximum en utilisant les noms internes des objets (List, Site, Web, Field) afin d’éviter les problème de renommage de ces objets (display name). On utilisera donc au maximum les staticName, internalName ou encore Name lorsqu’il seront disponibles sur ces éléments.

Commençons donc par la création de notre solution SharePoint dans Visual Studio 2010 que j’appelle DEMO1, de type “Empty SharePoint Project” :

image

On renseigne l’url du site de déploiement (debug) et on choisit une solution de type “Farm” :

image

La solution est créée, elle est vide ou presque :

image

Nous allons ensuite faire un clic droit sur le projet et ajouter un nouvel élément (Add New Item), de type SharePoint > 2010 > List Definition et on la nomme “Pays”. Cliquer sur “Add” :

image

Un assistant se lance pour nous aider à créer la structure générale de ce nouvel élément. Ainsi, on renseigne le nom d’affichage de notre modèle de liste. “Pays” dans mon cas, et on choisit le modèle “Custom List” qui est basique et conviendra très bien à notre exemple. Je choisis également de créer une instance lorsque la “Feature” déployant notre solution sera activée. On clique sur “Finish” :

image

La structure générale de la liste est créée :

image

On observe tout de suite que Visual Studio n’a pas créé 1 seul fichier mais bien un ensemble. Dans le “Répertoire” Pays, on retrouve 2 fichiers XML :

  1. Elements.xml : décrit à SharePoint comment déployer le modèle lors de l’ajout de ce modèle
  2. Schema.xml : décrit la structure des éléments à déployer : colonnes, vues, etc.

Dans le sous dossier ListInstance1, on retrouve également un fichier XML “Elements.xml” qui décrira comment créer une instance de cette liste à partir du modèle lors de l’activation de la Feature : nom de la liste, url, visibilité, etc.

Nous allons ensuite reproduire 2 fois ces manipulations pour créer deux nouvelles listes : Ville et Commandes :

image

J’ai pris le soin ici de renommer correctement les instances dans l’explorateur de solutions.

2/ Modifier les modèles de liste – Elements.xml

Notre structure générale est créée. Passons maintenant à l’enrichissement de ces modèles en les personnalisant, en ajoutant de nouvelle colonnes, etc.

Pays

Pour la liste pays, nous devons :

  • Ajouter les colonnes Surface, NbrHabitants
  • Masquer le modèle dans la galerie (les utilisateurs/power users ne pourront pas créer de nouvelles instances à partir de ce modèle)
  • personnaliser par-ci, par-là Sourire

Commençons par le fichier Elements.xml du modèle de liste :

<ListTemplate
Name=”Pays”
Type=”10000″
BaseType=”0″
OnQuickLaunch=”TRUE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Pays”
Description=”My List Definition”
Image=”/_layouts/images/itgen.png”/>

Nous allons commencer par modifier les attributs existants :

  • Name=”Pays” => cela me convient
  • Type=”10000” (attention il ne faudra pas avoir un autre modèle sur la plateforme portant ce numéro)
  • BaseType=”0” => cela me convient (on aura 1 pour les bibliothèques de documents)
  • OnQuickLaunch=”TRUE” => Je change en FALSE, la liste n’apparaitra pas pas défaut dans la barre de navigation rapide “QuickLaunch”
  • SecurityBits=”11″ => OK
  • Sequence => aucune importance, le modèle sera masque dans la galerie des modèles de liste (ordre de tri dans cette galerie)
  • DisplayName=”Pays” => OK
  • Description=”My List Definition” => On donne une description
  • Image=”/_layouts/images/itgen.png”/ => Je vais changer pour fournir une image un peu plus sympa, que je déploierais grâce à la solution dans 14/TEMPLATES/IMAGES/DEMO/monimage.png

On ajoutera les attributs :

  • Category=”Custom Lists” => pas obligatoire
  • DisableAttachments=”TRUE” => on désactive les pièces jointes
  • FolderCreation=”FALSE” => on désactive la création de répertoires
  • Hidden=”TRUE” => On masque le modèle dans la galerie
  • VersioningEnabled=”FALSE” => on désactive le versioning

Ce qui donne :

ListTemplate
Name=”Pays”
Type=”10000″
Category=”Custom Lists”
DisableAttachments=”TRUE”
FolderCreation=”FALSE”
Hidden=”TRUE”
VersioningEnabled=”FALSE”
BaseType=”0″
OnQuickLaunch=”FALSE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Pays”
Description=”Modèle de liste pays”
Image=”/_layouts/images/demo/pays.png”/>

Notez également qu’il vous sera possible de “localiser” les noms (Name, Description par exemple) pour faire la traduction automatique suivant la langue du navigateur/UI.

Ville

Nous allons effectuer les mêmes manipulation sur le fichier Elements.xml du modèle de liste Ville :

<ListTemplate
Name=”Ville”
Type=”10001″
Category=”Custom Lists”
DisableAttachments=”TRUE”
FolderCreation=”FALSE”
Hidden=”TRUE”
VersioningEnabled=”FALSE”
BaseType=”0″
OnQuickLaunch=”FALSE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Ville”
Description=”Modèle de liste ville.”
Image=”/_layouts/images/demo/villes.png”/>

Commandes

Pour la liste commande, on reproduit les mêmes manipulations, sauf que ne masquera pas ce modèle pour pouvoir créer de multiples instances de cette liste. Nous modifierons également l’attribut OnQuickLaunch à TRUE :

<ListTemplate
Name=”Commandes”
Type=”10002″
Category=”Custom Lists”
DisableAttachments=”TRUE”
FolderCreation=”FALSE”
VersioningEnabled=”FALSE”
BaseType=”0″
OnQuickLaunch=”TRUE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Commandes”
Description=”Modèle de liste commandes.”
Image=”/_layouts/images/demo/commandes.png”/>

3/ Modifier les modèles de liste – Schema.xml

Maintenant, il nous faut modifier les 3 fichiers Schema.xml pour ajouter les nouvelles colonnes sur chacun de nos 3 modèles.

Pays

Dans notre liste pays, nous allons ajouter deux colonnes supplémentaires : Surface & NbrHabitants. Pour cela, on ouvre le fichier Schema.xml du modèle de liste Pays :

image

Dans cette structure XML, on distinguera 4 parties principales :

  • ContentTypes : déclaration des types de contenus associés à la liste, ici celui élément (Item)
  • Fields : métadonnées/colonnes/champs associés à ce modèle de liste
  • Views : Vues disponibles sur ce modèle de liste
  • Forms : formulaires d’ajout/modification/affichage de chaque élément de cette liste

Nous allons modifier principalement les <Fields /> pour ajouter les deux colonnes. Ici plusieurs écoles s’affrontent. Vous pouvez partir de rien, aidé par l’IntelliSense de Visual Studio ou alors créer une liste et ces colonnes dans SharePoint et utiliser SharePoint Manager 2010 pour récupérer le schéma généré par SharePoint. Pour sa facilité, je choisirai la seconde option, mais en restant vigilant sur le flot de XML généré…

J’ai donc créé une liste “pays” dans SharePoint et créé les colonnes demandées.

On prendra soin également de choisir le type de champ le plus pertinent pour nos données : texte, monnaie, nombre, recherche, etc.

image

    Voila donc le formulaire d’ajout d’un pays :

image

Vous trouverez de quoi télécharger SharePoint Manager 2010 sur CodePlex : SharePoint Manager 2010.

On lance SharePoint Manager 2010, et on explore l’arborescence de nos sites jusqu’à arriver sur notre liste “Pays” :

image

Dans la section de droite, vous trouverez un onglet “SchemaXml” avec l’ensemble du schéma :

image

On repère rapidement, dans la section <Fields> que nos deux champs créés précédemment apparaissent :

  • <Field Type=”Number” DisplayName=”Surface” Required=”FALSE”… />
  • <Field Type=”Number” DisplayName=”NbrHabitants” Required=”FALSE” … />
    Ce sont ces deux nœuds XML qu’il va falloir intégrer au fichier Schema.xml. On copie donc ces deux lignes et on les colle dans Schema.xml, dans le nœud <Fields></Fields> :

image

Petite option supplémentaire, on peut directement ajouter ces deux champs dans les différentes vues proposées par notre modèle de liste Pays. Pour cela, dans Schema.xml, on ouvre le nœud <Views>, on y trouve deux nœuds <View></View>. Une des vues sera utilisée pour les terminaux de type mobiles, et l’autre pour l’affichage par défaut dans le navigateur de cette liste “Pays”. Nous allons directement modifier la vue commençant par :

<View BaseViewID=”1″ Type=”HTML” WebPartZoneID=”Main”

Et ajouter dans le sous-noeud <ViewFields> deux nouvelles lignes (en copiant/collant 1 existante) et en modifiant l’attribut Name avec les noms de noms champs. Je supprime également le Field Attachments correspondant aux pièces jointes que j’ai désactivé dans la déclaration du Template (voir Elements.xml précédent) :

        <ViewFields>
<FieldRef Name=”LinkTitle”></FieldRef>
<FieldRef Name=”Surface”></FieldRef>
<FieldRef Name=”NbrHabitants”></FieldRef>
</ViewFields>

Attention, l’ordre a son important, les premières lignes deviendront les premières colonnes dans l’affichage. On obtiendra donc :

image

Notez également le nœud <OrderBy> au dessous qui vous permettra d’ordonner votre liste sur les noms des pays, alphabétiquement. Je modifie donc :

        <Query>
<OrderBy>
<FieldRef Name=”Title”></FieldRef>
</OrderBy>
</Query>

C’est tout pour ce modèle de liste. Passons maintenant à l’instance qui sera créé à partir de ce modèle. Pour cela, on se rend dans l’explorateur de solution et on ouvre le fichier Elements.xml de l’instance de la liste Pays :

image

Dans ce dernier, nous allons encore modifier la structure XML pour paramétrer l’instance de la liste Pays qui sera automatiquement créée lors de l’activation de la feature (nous y reviendrons…).

On modifie pour obtenir :

<ListInstance Title=”Pays”
OnQuickLaunch=”FALSE”
TemplateType=”10000″
Url=”Lists/Pays”
Description=”Liste des pays”>
</ListInstance>

Notez que le TemplateType est le même que celui définit dans le <ListTemplate>, c’est très important ! Sinon SharePoint ne saura pas quel modèle utiliser pour créer l’instance. Pour l’url, ma liste sera accessible à l’adresse :

Ville

Nous allons reprendre les mêmes manipulations pour ce modèle de liste. Nous allons utiliser également SharePoint Manager 2010 pour récupérer les nœuds XML des colonnes.

Nous utilisons SharePoint Manager 2010, récupération des nœuds XML, copier/coller, etc.

image

Dans le Schema.xml, nous  ajoutons donc :

<Fields>
<Field Type=”Number” DisplayName=”Surface” Required=”FALSE”…

<Field Type=”Number” DisplayName=”NbrHabitants” Required=”FALSE”…

<Field Type=”Lookup” DisplayName=”Pays” Required=”TRUE”…

</Fields>

Jusqu’ici, nous n’avions eu que des colonnes texte ou nombre. Nous venons d’ajouter un nouveau type de colonne, le type “Lookup” (Recherche d’information déjà présentes sur le site). Ces champs permettent de référencer des données qui sont stockées dans une autre liste/bibliothèque SharePoint. Si l’on regarde les différents attributs proposés, on note :

  • List=”{1f675688-39f5-441d-bdb7-19f7c3dce646}”
  • ShowField=”Title”
    Ce sont ces deux attributs qui établissent la relation entre la liste Ville et la liste Pays et plus particulièrement la colonne “Title” de la liste Pays. Lorsque nous déploierons cette solution/feature, SharePoint ne saura pas faire le lien entre ces deux listes, parce que, tout simple le GUID de la liste Pays va être régénéré !!! Et oui… il va donc falloir remplacer ce premier attribut “List” par autre chose (et si possible pas de code C# qui recréera cette relation).
    Après un petit tour dans le SDK de SharePoint, on s’aperçoit qu’il est possible de remplacer ce GUID par l’adresse relative de cette liste : Lists/Pays. On obtient donc :

<Field Type=”Lookup” DisplayName=”Pays” Required=”TRUE” EnforceUniqueValues=”FALSE” List=”Lists/Pays” ShowField=”Title”

Pour la vue par défaut de cette liste, nous effectuons également les modification afin que ces champs apparaissent dans la vue :

image

C’est tout pour ce modèle de liste. Passons maintenant à l’instance qui sera créé à partir de ce modèle. Pour cela, on se rend dans l’explorateur de solution et on ouvre le fichier Elements.xml de l’instance de la liste Ville :

image

Dans ce dernier, nous allons encore modifier la structure XML pour paramétrer l’instance de la liste Ville qui sera automatiquement créée lors de l’activation de la feature (nous y reviendrons…).

On modifie pour obtenir :

<ListInstance Title=”Villes”
OnQuickLaunch=”FALSE”
TemplateType=”10001″
Url=”Lists/Villes”
Description=”Liste des villes.”>
</ListInstance>

image

Notez que le TemplateType est le même que celui définit dans le <ListTemplate>, c’est très important ! Sinon SharePoint ne saura pas quel modèle utiliser pour créer l’instance. Pour l’url, ma liste sera accessible à l’adresse :

Commandes

Pour cette dernière liste, nous allons reproduire exactement les mêmes étapes mais cette fois-ci, nous aurons deux champs de type “lookup”.

Dans le schema.xml nous aurons donc :

<Fields>
<Field Type=”Currency” DisplayName=”Montant” Required=”TRUE” … />
<Field Type=”Lookup” DisplayName=”Pays” Required=”TRUE” …  List=”Lists/Pays” ShowField=”Title” … />
<Field Type=”Lookup” DisplayName=”Ville” Required=”TRUE” List=”Lists/Villes” ShowField=”Title” … />

</Fields>

image

C’est tout pour ce modèle de liste. Passons maintenant à l’instance qui sera créé à partir de ce modèle. Pour cela, on se rend dans l’explorateur de solution et on ouvre le fichier Elements.xml de l’instance de la liste Commandes :

image

Dans ce dernier, nous allons encore modifier la structure XML pour paramétrer l’instance de la liste Commandes qui sera automatiquement créée lors de l’activation de la feature (nous y reviendrons…).

On modifie pour obtenir :

<ListInstance Title=”Commandes”
OnQuickLaunch=”TRUE”
TemplateType=”10002″
Url=”Lists/Commandes”
Description=”Liste de commandes.”>
</ListInstance>

image

Notez que le TemplateType est le même que celui définit dans le <ListTemplate>, c’est très important ! Sinon SharePoint ne saura pas quel modèle utiliser pour créer l’instance. Pour l’url, ma liste sera accessible à l’adresse :

Certains diront qu’il y a des attributs qui ne seront pas utilisé dans notre structure XML (Schema.xml, Elements.xml), je vous laisse vous reporter au SDK, Technet et autre pour faire le tri….

4/ Créer le package de déploiement

Il nous reste une étape, et pas des moindres, créer la solution, la feature qui permettra de déployer nos modèles de listes. Pour cela, Visual Studio nous aide bien (et c’est tout à son honneur quand on a connu SharePoint 2003 & 2007…).

Nous allons donc nous rendre dans le répertoire Features où nous remarquons qu’une feature est déjà disponible :

image

On double-clique, l’assistant de configuration des features apparait :

image

Aucun des modèles/instances n’est ajouté à la feature. Commençons par cela, on utilise les “flèches du milieu” pour faire passer les éléments de gauche à droite :

image

Nous allons également renommer la feature, donner une petite description, etc. Il vous sera également possible d’ajouter une petite icone pour distinguer plus rapidement vos features.

Chose importante, je souhaiterai que mes listes Pays & Villes ne soient créées (leurs instances plus particulièrement) que sur le site à la racine de la collection (RootWeb). Pour cela, le plus simple et de changer le Scope (Etendue) en Site (Collection de sites).

image

Et c’est tout… Bien sûr suivant le projet et les éléments qui le composent, vous choisirez peut être d’utiliser plusieurs fonctionnalités, avec des scopes différents…

5/ Le test !

C’est parti pour le test… vous pouvez utiliser F5 (mode debug… qui ne débuggera rien ici !) ou alors le clic droit sur le projet, Build, Deploy. Ce choisis la seconde option.

Vous aurez peut être une erreur lors du déploiement vous disant que Pays et Pays se déploie dans le même emplacement. En effet en regardant les chemins (path) de déploiement on s’aperçoit que les instances se déploient dans le même répertoire que la définition. Je renomme dans les modèles de liste :

image

Vous obtiendrez peut être cette fenêtre de warning :

image

Elle vous informe tout simplement qu’une liste avec le même nom “Pays” existe deja. On coche “Do not prompt me again for these items” puis on clique sur “Resolve automatically”…

Déploiement réussi :

image

Il faudra également ajouter les images correspondant aux miniatures de nos listes. J’ai fait quelques petits changements dans les Elements.xml des modèles en modifiant l’attribut Image :

  • Image=”/_layouts/images/demo/pays16x16.png”/
  • Image=”/_layouts/images/demo/villes16x16.png”/
  • Image=”/_layouts/images/demo/commandes16x16.png”/

Voila ce que cela donne dans le menu “View all site content” :

image

Rendons nous sur chacune des liste afin de vérifier :

  • La déclaration des vues/affichages (colonnes présentes, tris)
  • La déclaration des colonnes créées

Coté affichage, rien à signaler. Par contre si on lance le formulaire d’ajout d’un pays/ville/commandes, le formulaire ne présente que le champ Titre !!! Effectivement, c’est un comportement particulier de SharePoint voire étrange que l’on constate ici.

Premier réflexe, ajouter les attributs :

ShowInNewForm=”TRUE” ShowInEditForm=”TRUE” ShowInDisplayForm=”TRUE”

Sur chacun des champs. Mais cela n’aura aucun effet. Nous aurons alors deux choix :

  • Recourir à un type de contenu SharePoint
  • Supprimer les types de contenu

En général, je me tourne vers la première option. Mais dans notre cas, aucun intérêt de créer des types de contenu (ContentTypes) vu qu’on ne les utilisera qu’une seule fois (pour Pays & Ville) et qu’on ne réutilisera pas non plus la structure de Commandes (si ce n’est pour créer de nouvelles listes de commandes => et pas des sous-enfants).

Voila donc comment faire fonctionner tout cela. Première opération, supprimer les sections <ContentTypes>…</ContentTypes> ou tout du moins le contenu => <ContentTypes/> dans les 3 Schema.xml :

image

On sauvegarde le tout et on redéploie… et là, magique :

image

5/ Charger des données

Une petite dernière chose, avant de passer à la suite… Les listes étant créées, elles seront supprimées, recréées à chaque déploiement depuis Visual Studio. Pour ne pas perdre trop de temps à se recréer un jeu de test, nous pouvons remplir ces listes directement depuis leur définition. C’est ce qu’on appelle les RowData.

Nous allons commencer par ajouter des données dans Pays puis Ville. Cette méthode est aussi très pratique pour remplir automatiquement des listes de paramètres stockées dans SharePoint (ici notre liste de Pays ne change pas tous les jours…). Voila comment faire.

Dans chacun des fichiers Elements.xml des instances de nos listes, nous allons ajouter un bloc de XML :

<ListInstance Title=”Pays”
OnQuickLaunch=”FALSE”
TemplateType=”10000″
Url=”Lists/Pays”
Description=”Liste des pays”>
<Data>
<Rows>
<Row>
<Field Name=””></Field>
</Row>
</Rows>
</Data>
</ListInstance>

En résumé, les nœuds XML :

  • Data : ensemble des données à ajouter
  • Rows : collection des lignes (ensemble d’enregistrements)
  • Row : 1 ligne d’enregistrement
  • Field : champ à valoriser pour l’enregistrement courant.

Donc pour un pays, on aurait (données recueillies sur www.france.fr) :

    <Data>
<Rows>
<Row>
<Field Name=”Title”>France</Field>
<Field Name=”Surface”>543965</Field>
<Field Name=”NbrHabitants”>65350000</Field>
</Row>
</Rows>
</Data>

En on recréée une structure Row pour chacun des pays. J’en ajouterai une petite dizaine pour les tests.

image

On remarque tout de suite que les pays sont triés sur le nom (alphabétique) alors dans le Schema.xml :

        <Row>
<Field Name=”Title”>France</Field>
<Field Name=”Surface”>543965</Field>
<Field Name=”NbrHabitants”>65350000</Field>
</Row>
<Row>
<Field Name=”Title”>Espagne</Field>
<Field Name=”Surface”>505911</Field>
<Field Name=”NbrHabitants”>46754784</Field>
</Row>
<Row>
<Field Name=”Title”>Angleterre</Field>
<Field Name=”Surface”>130395</Field>
<Field Name=”NbrHabitants”>52234000</Field>
</Row>

Nous allons faire la même chose avec les Villes. Petite différence, le champ lookup qui pointe sur la liste des Pays… Et c’est donc un peu différent. En effet, les champs lookups doivent être renseigné avec ID;#Valeur :

         <Row>
<Field Name=”Title”>Marseille</Field>
<Field Name=”Surface”>240</Field>
<Field Name=”NbrHabitants”>850602</Field>
<Field Name=”Pays”>1;#France</Field>
</Row>
<Row>
<Field Name=”Title”>Madrid</Field>
<Field Name=”Surface”>608</Field>
<Field Name=”NbrHabitants”>3413271</Field>
<Field Name=”Pays”>2;#Espagne</Field>
</Row>

Attention, l’ID et celui dans SharePoint (et donc dans l’ordre d’insertion qui correspond à l’ordre dans l’Element.xml de la liste Pays !)

image

Et voilà ! Puisque les listes sont supprimées à chaque déploiement, nous n’auront pas besoin de remplacer les ID dans les fichiers Elements.xml.

Dernière vérification, la liste de commandes est-elle bien renseignée ?? Bien sûr que oui !

image

Par contre on voit tout de suite que Barcelone n’est pas en Allemagne… Clignement d'œil

Et donc… prochain article… ré-implémenter le comportement de ce formulaire… et faire communiquer nos deux liste déroulantes !

SP2013–Design Manager

Posted on Updated on

Parmi les nouveautés de SharePoint 2013, il en est une qui n’est pas forcément souvent abordée : Le Design Manager.

Ce n’est pas en soit une nouveauté fonctionnelle mais bien une agrégation d’anciens menus, de nouvelles présentation qui vous permettrons d’accéder et modifier vos ressources graphiques intervenant dans le design de votre site : masterpages, CSS, layouts, etc.

 

Voyons ensemble comment se présente la chose…

Commençons par accéder à ce Design Manager :

01

02

 

Nous voyons tout de suite une succession de 8 menus sur la gauche et leur numérotation n’est pas un hasard, nous déroulerons ces menus en respectant cet ordre pour créer un package de déploiement de branding directement depuis le Design Manager !

 

1/ Sur la page d’accueil de ce Design manager, deux menus principaux. Le premier (Import a complete design package) vous permettra d’importer un package (WSP : Windows SharePoint Package) contenant un design que vous aurez soit acheté chez un éditeur, soit développé vous même grâce à Visual Studio ou le Design Manager. Utile par exemple pour migrer le design mis en place sur une plateforme de développement vers celle d’intégration !

03

 

Le second menu (Pick a pre-installed look) vous permettra de sélectionner un design (thème) déjà présent dans votre plateforme et de l’appliquer à votre site.

04

30

 

Voyons maintenant les menus accessible par la barre latérale à gauche…

2/ Second menu : Manage Device Channels

05

Ce menu présente une interface de type ”Liste” SharePoint… mais à quoi servent ces “Channels”. Et bien ça c’est nouveau, vous allez pouvoir créer des canaux (super traduction…) permettant d’orienter un design suivant un type de navigateur/matériel. Vous pourrez alors dédier un design à des matériels de type Windows Phone, ou encore pour des navigateurs comme Opera Mini. Nous allons donc essayer de créer un nouveau canal :

06

 

On rempli donc les quelques paramètres demandés :

  • Name : nom du canal
  • Alias : cet alias pourra être utilisé dans la déclaration des contrôles/composants des masterpages par exemple pour paramétrer les affichages en fonction du canal d’affichage (par exemple si l’utilisateur navigue sur un Opera Mini, alors on affichera un contrôle différemment d’un autre utilisateur utilisant chrome).
  • Description : description de l’utilisation de ce canal
  • Device Inclusion Rules : règles appliquées pour déterminer si ce canal doit être appliqué au matériel. En effet, on déclarera ici des chaines de caractères qui seront comparées au “browser user agent” pour déterminer si on doit sélectionner ce canal ou un autre. Vous pourrez déterminer ce critère en utilisant par exemple http://whatsmyuseragent.com/ ou http://www.useragentstring.com/pages/Browserlist/ ou encore http://www.nczonline.net/blog/2010/01/12/history-of-the-user-agent-string/ et http://www.zytrax.com/tech/web/mobile_ids.html
  • Activer ou désactiver le canal

07

 

Ici j’ ai créé 2 canaux supplémentaires :

  • Un pour les Windows Phone OS
  • Une pour les navigateurs Opera

08

 

Vous avez également la possibilité de réordonner liste de vos canaux, ils seront parcourus dans l’ordre fixé ici lors de vérification des règles d’application d’un design par rapport au fameux browser user agent :

09

 

Pour réordonner :

10

 

3/ Passons au troisième menu : Upload Design Files. Ce menu vous permettra d’ouvrir un navigateur ou un Webdav sur la bibliothèque de masterpages et d’uploader vos ressources : Masterpages, CSS, JavaScripts, images, etc.

11

 

4/ Le quatrième menu : Edit Master Pages vous permet de parcourir la bibliothèque des masterpages, de modifier les types de contenu associés à une page…

Tout en haut, on observe deux menus supplémentaires. Le premier se propose de convertir un fichier HTML en masterpage SharePoint… Pour être honnête je ne l’ai pas testé : TODO !

Le second vous propose de créer une masterpage minimale, et ça c’est quand même pratique ! Là où avant il fallait repartir d’une masterpage existante et faire du tri ou aller récupérer les “Minimal Masterpages” sur Codeplex, ça fait gagner du temps !

12

 

Création d’une nouvelle masterpage, rien de plus simple :

15

 

5/ Cinquième menu : Edit Display Templates. Ce menu va vous permettre d’éditer les templates utilisés par défaut pour les rendus des contrôles SharePoint, des WebParts comme par exemple celui utilisé pour le rendu des résultats de recherche. Vous pourrez donc dupliquer les rendus existant, les modifier et les associer aux WebPart habituels… le tout mixé avec des Device channels qui permettront d’avoir des rendus différents suivant les matériels/navigateurs :

19

 

6/ Sixième menu : Edit Page Layouts. Dans ce menu, vous pourrez ajouter directement un nouveau layout depuis un lien en haut de la page. Ici aussi, même remarque que pour les masterpages précédemment, cela nous évitera de devoir copier/coller un layout de départ, mais plutôt de commencer la personnalisation depuis un “minimal layout”.

21

31

 

7/ Septième menu : Publish and apply Design. Ce menu vous permettra, comme son nom l’indique, d’appliquer le Design que vous venez de mettre en place. Pour cela un lien “Apply master pages to your site based on device channel” vous permettra d’accéder à une page dans laquelle vous pourrez appliquer ce design sur les canaux créés tout au début :

24

25

 

8/ Huitième menu : Create Design Package. C’est l’aboutissement des manipulations faites dans les précédents menus, c’est ici que le pourra créer un package de type WSP contenant le Design créé jusqu’ici. Très simple d’utilisation, vous aurez seulement à compléter le nom du package, cliquer sur “Create” et SharePoint 2013 vous proposera de sauvegarder localement ce nouveau package :

26

 

Le package est généré, un nouveau lien apparait nous permettant de le télécharger et de l’enregistrer localement.

28

 

Encore des fonctionnalités biens utiles apportées par ce Design Manager. Plus besoin de crées des solutions Visual Studio pour déployer vos brandings, ils nous suffira de créer un design, le packager et c’est parti. A noter également ces fameux “Device Channels” qui nous permettront d’adapter facilement nos Design suivant le matériel (Device) ou encore suivant le navigateur qui se connectera à notre SharePoint.