J’ai eu le besoin de créer de nouvelles pages de composants web part depuis un FeatureReceiver. Cette tâche n’est pas très compliquée lorsque l’on travaille avec MOSS. En effet, MOSS est orienté Publishig contrairement à WSS. Le bout de code qui permettrait de créer une nouvelle page ressemble à :
1: // Je crée une instance de PublishingWeb à partir du SPSite courrant
2: PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(site.RootWeb);
3:
4: // Je sélectionne le type de contenu de publication à partir duquel
5: // je veux créer une nouvelle page
6: SPContentTypeId ct = new SPContentTypeId("ID du type de contenu à utiliser");
7:
8: // Je récupère tous les modèles de page associés à ce type de contenu
9: PageLayout[] layouts = pWeb.GetAvailablePageLayouts(ct);
10:
11: // En utilisant LINQ, le sélectionne l'instance PageLayout (modèle) que je veux
12: // utiliser
13: var layout = from l in layouts
14: where l.Name == "BlankWebPartPage.aspx"
15: select l;
16:
17: // Je crée une nouvelle page, basée sur le modèle précédemment sélectionné, je lui
18: // affecte une titre puis la sauvegarde
19: PublishingPage p = pWeb.GetPublishingPages().Add("newpage.aspx", (PageLayout)layout.First());
20: p.Title = "ma page qui tue";
21: p.Update();
Par contre, la tâche se complique dans WSS …. En effet, l’objet PublishingWeb n’existe pas. En furetant à droite et à gauche, il s’avère que le mieux est de récupérer le modèle de page souhaité, de le charger dans une FileStream, puis de créer un nouveau SPFile à partir de ce FileStream. Passons tout de suite au code :
1: // J'ai déjà mon SPWeb ...
2:
3: // Quel modèle j'utilise (que je trouve dans $HIVE\TEMPLATE\1033\STS\DOCTEMP\SMARTPGS\, 1033 étant bien
4: // entendu la langue ...
5: string template = "spstd5.aspx";
6:
7: // Je construit le chemin d'accès à ce fichier, en se servant de SPUtility.GetGenericSetupPath et de
8: // web.Language pour faire un code plus générique
9: string hive = SPUtility.GetGenericSetupPath(string.Format(@"TEMPLATE\{0}\STS\DOCTEMP\SMARTPGS\", web.Language));
10:
11: // Je charge ce fichier dans un Stream
12: using (FileStream fs = new FileStream(Path.Combine(hive, template), FileMode.Open))
13: {
14: // Je me positionne dans la bonne bibliothèque, et éventuellement le bon
15: // dossier, et je récupère la collection de fichiers SPFileCollection
16: SPFolder lib = web.GetFolder("Bibliothèque de pages où stocker la page");
17: SPFileCollection files = lib.Files;
18:
19: // Je crée mon nouveau SPFile basé sur mon Stream que j’ajoute à cette collection
20: SPFile newF = files.Add(name, fs);
21: }
Le bout de de code précédent nous permet donc de créer une nouvelle page …
Par contre, si vous créez une nouvelle page graphiquement via les pages d’administration SharePoint, cette nouvelle page possède une banière de titre, comme le montre la capture suivante:
Or, cette banière n’est pas présente lors de la création de la page via l’API (et donc via le bout de code précédent).
Il s’avère que cette banière de titre est une web part, mais qui n’est pas dans une zone éditable via le navigateur. Il faut donc ajouter dynamiquement cette web part à la création de la page. Reprenons le bout de code précédent, et ajoutons entre la ligne 20 et 21 le code suivant:
1: // Récuprérons le gestionnaire de web part pour la page courrante (newF étant le nouveau SPFile créé)
2: SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(newF.Url, SWWP.PersonalizationScope.Shared);
3:
4: // Créeons une nouvelle instance de la web part standard TitleBarwebPart, et
5: // assignons lui un titre (propriété HeaderTitle, et non Title)
6: TitleBarWebPart tb = new TitleBarWebPart();
7: tb.HeaderTitle = "MyTitle bloody good";
8:
9: // Ajoutons cette web part dans la zone TitleBar, en position 0, puis
10: // sauvegardons le tout
11: manager.AddWebPart(tb, "TitleBar", 0);
12: manager.SaveChanges(tb);
Nous avons donc maintenant une solution complète pour créer des pages WSS 3.0 depuis l’API, à l’identique de la manière “graphique”.
- Julien