Delphi ASP.NET Portal Starter Kit v.1.0 (DPSK)

Pascal Chapuis

Cet article présente le projet « Delphi ASP.NET Portal Starter Kit ». Ce projet permet très simplement de créer et de maintenir un portail Internet intégrant la gestion de contenu. Les fonctionnalités et l'implémentation sont présentées. Les principales carences de ce projet sont listées. Une série d'améliorations sont proposées.

- Titre : Delphi ASP.NET Portal Starter Kit v.1.0 (DPSK)

- Auteur : Pascal Chapuis

- Parution : 18 mai 2005

- Mise à jour : 30 décembre 2019

- Licence : Copyright ® 2005 Pascal Chapuis. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation générale - fonctionnalités intégrées

- I-A. Origine du projet initial

- I-B. Portail Internet et gestion de contenu (CMS)

- I-C. Arborescence, page modèle et modules

- I-D. Liste et définition des modules enfichables

- I-E. Sécurité via les rôles

- I-F. Accès pour les périphériques mobiles

- I-G. Qualité de service (QOS) et cache

- II. Présentation technique du projet Delphi

- II-A. Composantes logicielles

- II-B. Pourquoi une traduction Delphi ?

- II-C. Configuration XML

- II-D. Modules enfichables

- II-E. Utilisateur et rôle : sécurité

- II-F. ASP.NET Mobile

- II-G. Fonctionnement du cache

- III. Carences de cette version

- III-A. Configuration « PortalCfg.XML » et HttpContext.Current

- III-B. Ordre des onglets et des modules

- III-C. Accès ADO à différentes bases de données

- III-D. Divers

- IV. Améliorations proposées

- IV-A. Édition de contenu et granularité des primitives d'édition

- IV-B. Validation de la publication : modérateur

- IV-C. Portail multilingue

- IV-D. Personnalisation de la charte graphique

- IV-E. Arborescences et onglets (tabs)

- IV-F. Modules supplémentaires

- IV-G. Modules pluggables de Dot Nuke Net et interfaces

- V. Conclusion

- VI. Références

- VI-A. Microsoft ASP.NET

- VI-B. Delphi ASP.NET Portal Starter Kit

- VI-C. Autres projets de portail Internet

- VII. Remerciements

I - Présentation générale - fonctionnalités intégrées

Cette présentation générale présente les fonctionnalités principales du projet. Ces caractéristiques sont nécessaires à un portail Internet intégrant la gestion de contenu. Cette première partie se veut plus fonctionnelle que technique. Cette première partie conviendra au lecteur peu technicien, mais désireux de comprendre les fonctions essentielles présentes dans ce projet.

I-A - Origine du projet initial

Le projet ASP.NET Portal Starter Kit a été initialement publié par Vertigo Software en novembre 2002. La création de ce projet fut motivée par le besoin de fournir des projets de démonstration accompagnant la nouvelle technologie ASP.NET. Ainsi une gamme de différents Starter Kit est née.

La liste des différents « ASP.NET Starter Kit » disponibles est la suivante :

- Issue Tracker Starter Kit : portail Internet de gestion de déploiement de logiciels ;

- Time Tracker Starter Kit : portail Internet de gestion de projets ;

- Reports Starter Kit : kit de construction d'états d'impression ;

- Community Starter Kit : portail Internet communautaire ;

- Commerce Starter Kit : portail Internet de commerce électronique ;

- Portal Starter Kit : l'objet de cet article.

Ces différents projets sont proposés dans les langages VB#, J# et C# et sont en téléchargement gratuit sur le portail Microsoft dédié à ASP.NET.

I-B - Portail Internet et gestion de contenu (CMS)

Dans les systèmes de gestion de contenu, CMS (Content Management System), la présentation est séparée des données.

Les deux niveaux suivants sont à distinguer :

- la présentation (layout) : arborescence du site, charte graphique, agencement des différents modules dans une page… ;

- le contenu (content) : informations présentées par les modules.

La principale caractéristique du Portal Starter Kit est l'intégration en ligne de la gestion de contenu (CMS). Ainsi le portail offre deux modes de fonctionnement principaux :

- la consultation classique : navigation « standard » ou navigation avec participation aux modules publics (discussions…) ;

- la consultation avec administration en ligne de la présentation et du contenu : dans ce mode les modules proposent des liens vers l'édition de leur contenu. La page d'administration du portail est accessible :

Dephi ASP.NET Portal Starter Kit permet de créer et de maintenir un ou plusieurs portails. Les informations de contenu de plusieurs portails peuvent être stockées dans une même base de données. Le fichier de configuration « PortalCfg.xml » est associé à un portail unique.

I-C - Arborescence, page modèle et modules

L'arborescence principale du portail est représentée via un système d'onglets. Chacun de ces onglets correspond à une page du portail. Cette arborescence est administrable en ligne via la page d'administration. Cette administration permet la gestion une d'une arborescence dynamique.

Chaque page du portail implémentée via Portal Starter Kit est composite et donc créée dynamiquement.

Une page finale est le résultat de l'assemblage dynamique de plusieurs modules.

Cet assemblage est basé sur une page modèle ou gabarit. Cette page modèle inclut trois zones : la zone gauche, la zone du centre et la zone de droite. La page d'administration de la présentation permet de positionner les modules d'une page du portail dans ces zones.

La page modèle est composée d'une partie représentant la bannière du site. Dans cette bannière sont présents le titre du site, les onglets… De même la partie titre des modules est extraite dans un composant. Cette décomposition des pages/composants en sous-éléments permet de maintenir facilement l'aspect général du portail.

Les éléments communs du site sont isolés et extraits dans des composants. La factorisation des parties communes via les composants (contrôle utilisateur ASP.NET) permet de simplifier la maintenance du portail et d'uniformiser le look and feel.

I-D - Liste et définition des modules enfichables

La liste des modules disponibles est présentée ci-dessous. Ces modules sont groupés dans deux tableaux principaux en fonction de leur rôle d'administration du portail ou de leur rôle de présentation de contenu.

Liste des modules d'administrations présents sur la page de gestion du site :

N°

Module

Description

Fichier du contrôle

Page d'administration associée

1

Définition de Module Type

gestion de la liste des modules du portail

\Admin\ModuleDefs.ascx

\Admin\ModuleDefinitions.aspx
\Admin\ModuleSettings.aspx

2

Rôles

gestion des rôles associés à un utilisateur

\Admin\Roles.ascx

\Admin\SecurityRoles.aspx

3

Onglets

gestion des onglets du portail

\Admin\Tabs.ascx

\Admin\TabLayout.aspx

4

Paramètres du site

gestion des paramètres généraux du portail

\Admin\SiteSettings.ascx

page d'administration du site

5

Gestion des Utilisateurs

gestion des utilisateurs du portail

\Admin\users.ascx

\Admin\manageusers.aspx

Liste des modules de présentation de contenu :

N°

Module

Description

Fichier du contrôle

Page d'administration associée

1

Annonces

Annonce texte avec les champs : titre, date d'expiration, description, lien « en savoir plus »

\DesktopModules\Announcements.ascx
\MobileModules\mAnnouncements.ascx

\DesktopModules\EditAnnouncements.aspx

2

Contacts

liste de contacts avec les champs : nom, rôle, email, premier contact, second contact

\DesktopModules\Contacts.ascx
\MobileModules\mContacts.ascx

\DesktopModules\EditContacts.aspx

3

Discussion

Discussion avec les champs : titre, date, auteur, texte

\DesktopModules\Discussion.ascx

\DesktopModules\DiscussDetails.aspx

4

Événements

Événement texte avec les champs : titre, où et quand, description, date d'expiration

\DesktopModules\Events.ascx
\MobileModules\mEvents.ascx

\DesktopModules\EditEvents.aspx

5

html

Document html avec les champs : document html, résumé html et document html pour les mobiles

\DesktopModules\HtmlModule.ascx
\MobileModules\mText.ascx

\DesktopModules\EditHtml.aspx

6

Image

Image avec champs : taille de l'image affichée, chemin du fichier image

\DesktopModules\ImageModule.ascx

\DesktopModules\EditImage.aspx

7

Liens

Lien hypertexte avec les champs : URL, URL pour les mobiles, ordre d'affichage, description

\DesktopModules\Links.ascx

\DesktopModules\EditLinks.aspx

8

Liens rapides

Lien hypertexte avec les champs : URL et ordre d'affichage, description

\DesktopModules\QuickLinks.ascx

\DesktopModules\EditLinks.aspx

9

XML/XSL

Transformation XML/XSLT avec les champs : chemin d'un fichier XML et du fichier de transformation XSL/T

\DesktopModules\XmlModule.ascx

\DesktopModules\EditXml.aspx

10

Documents

Documents avec les champs : nom de document, lien sur le document, catégorie et propriétaire

\DesktopModules\Document.ascx

\DesktopModules\ViewDocument.aspx

Module utilitaire :

N°

Module

Description

Fichier du control (répertoire \Admin

Position

1

Connexion au portail

Module de connexion au portail (nom de connexion, mot de passe, bouton valider et s'enregistrer)

Signin.ascx

premier onglet du portail

À chacun de ces modules de présentation de contenu est associé un objet métier implémentant l'accès aux informations de contenu. Ces informations de contenu sont stockées dans une base de données (SQL Server ou FireBird). Il est ainsi possible d'interfacer une base de données existante avec le portail.

Le paramétrage du contenu présenté par les modules Images et XML/XSL, n'est pas stocké dans la base de données. Dans ce cas ces paramètres sont stockés dans la configuration XML.

D'autres modules peuvent être ajoutés (pluggable) via le module « définition de Module Type ». Un module spécifique est facilement intégrable à l'ensemble du portail. Par exemple un module « Blogs » est simple à développer et ne présente aucune difficulté d'intégration dans le portail. L'ensemble reste cohérent grâce à ce système de modules enfichables.

I-E - Sécurité via les rôles

Le projet ASP.NET Portal Starter Kit intègre les notions de sécurité permettant une intervention sur le portail de plusieurs intervenants (travail collaboratif). Par exemple, un portail réalisé avec ce projet convient à un portail de communauté de communes dans lequel chaque commune est responsable de sa rubrique, mais ne doit pas intervenir sur la rubrique de la commune voisine.

Chacun des onglets du portail correspond à une page ayant des droits d'accès en consultation. Par exemple l'onglet Administration ne sera proposé qu'aux utilisateurs possédant le rôle d'administrateur. Le même principe de sécurité est valable pour les modules composant les pages. Il est donc possible de distribuer des rôles sur les pages, mais aussi sur les modules. Ces rôles sont affectés à deux actions principales :

- consultation (« AccessRoles ») : la liste des rôles autorisés à consulter une page ;

- édition de contenu (« EditRoles ») : la liste des rôles autorisés à éditer le contenu.

Le basculement du mode consultation vers le mode administration de contenu est effectué via la connexion au portail et via le(s) rôle(s) associé(s) au compte de connexion. Un utilisateur lambda (public) lors de sa connexion au site ne se verra pas proposer la maintenance du site alors qu'un utilisateur connecté par exemple comme Administrateur (rôle admin) disposera d'une interface lui permettant de maintenir en ligne le portail.

Il est possible de définir de nouveaux rôles via le module d'administration. Ces rôles sont stockés dans une table de la base de données. Ils sont croisés avec les utilisateurs. Par exemple à l'utilisateur Administrateur est associé le rôle « Admin ». Lors de l'administration, le rôle associé à une page ou à un module est copié dans le fichier de configuration « PortalCfg.xml ».

I-F - Accès pour les périphériques mobiles

Le projet ASP.NET Portal Starter Kit permet de communiquer avec un public important grâce aux fonctionnalités intégrées d'accès aux périphériques Mobiles. Par exemple, le portail Internet d'un office de tourisme peut offrir l'accès à la liste des événements locaux via la connexion des téléphones mobiles des touristes en vacances.

Chaque page (onglet) et chaque module possèdent une option ShowMobile. Cette option, en mode administration, permet de définir si la page et/ou le module sont affichés pour les périphériques mobiles. Tous les modules ne sont pas implémentés pour permettre un affichage pour les périphériques mobiles (cf. liste des modules 1.4).

Les modules « mixtes » disponibles pour les périphériques mobiles sont :

1. Annonces

2. Contacts

3. Événements

4. Html

Les caractéristiques d'un périphérique mobile ne sont pas forcément compatibles avec le contenu publié sur un ordinateur. En conséquence, deux zones distinctes (spécifiques aux périphériques de type Desktop ou de type Mobile) permettent de saisir le contenu présenté par le module.

Les informations publiées par un module mixte (ordinateur et mobile) sont spécifiques au périphérique du client cible.

I-G - Qualité de service (QOS) et cache

Un système de cache configurable dans l'administration du portail permet d'offrir un temps de réponse stable. Via ce système de cache paramétrable, les modules lors de leur création initiale sont automatiquement inscrits dans le cache du système. Leur construction complète n'est pas nécessaire à la prochaine requête. Le HTML correspondant au module est automatiquement restitué à partir du cache du système. Le temps de réponse (accès à la base, présentation des infos…) est ainsi optimisé au minimum.

Ce cache peut provoquer une désynchronisation avec la base de données. Dans le cas où les informations de contenu sont modifiées dans la base, cette modification ne sera pas visible par le client, car la chaîne correspondant au module (cache) avant la modification sera renvoyée.

II - Présentation technique du projet Delphi

Le projet Delphi ASP.NET Portal Starter Kit est un projet important de par sa taille. Néanmoins la complexité de l'ensemble est moindre. Avec les contrôles utilisateurs ASP.NET (ascx), les pages (aspx), mais aussi les contrôles ASP.NET ressemblent à des poupées russes. Ceci rend le code plus digeste, mais l'appréhension de l'ensemble plus complexe. Dans cette présentation, les points clés sont abordés. Le code étant important (environ 20 000 lignes) il est ambitieux de décrire l'ensemble dans le détail.

II-A - Composantes logicielles

- Windows 2000, XP ou 2003

- Framework : Microsoft .NET version 1.0 ou version 1.1 (gratuit)

- Serveur de base de données : SQL Server 2000 ou MSDE Microsoft SQL Server Desktop Engine (gratuit) ou FireBird (gratuit)

- Composants ADO spécifiques FireBird : .NET Data Provider

- Serveur Web : IIS ou Cassini (gratuit)

- Mobile : Microsoft Mobile Internet Toolkit 1.0 (gratuit)

- EDI : Borland Delphi 8.NET ou Delphi 2005

- EDI ASP.NET : Microsoft WebMatrix (gratuit)

II-B - Pourquoi une traduction Delphi ?

Avec .NET, il est très simple d'utiliser avec Delphi les classes définies initialement en C#. Par exemple une inclusion (uses) du namespace « ASPNET.StarterKit.Portal » permet de définir un nouveau module héritant de la classe C# « PortalModuleControl » initiale :

Composant Delphi 'TWebUserDelphiCalendrier' héritant de la classe C# via l'inclusion du namespace C#

unit CalendarDelphi;

interface

uses System.Data, System.Drawing, System.Web, System.Web.UI,
System.Web.UI.WebControls, System.Web.UI.HtmlControls,
System.ComponentModel,
System.Globalization,
ASPNET.StarterKit.Portal; //  namespace PortalModuleControl/C#

type

TWebUserDelphiCalendrier = class(PortalModuleControl) //  héritage

Via .NET, il est également possible d'étendre une classe avec les Class Helpers (« class helper for … »).

Afin de profiter du code C#, la traduction du projet n'est donc pas forcément nécessaire. Plusieurs raisons cependant encouragent à faire cette traduction :

- le projet initial ne couvre pas toutes vos exigences et l'extension des classes du projet C# ne permet pas de pallier ce besoin. Le moteur du projet initial doit donc être modifié ;

- des erreurs/problèmes sont présents dans le code C#. La maintenance du code original est à prévoir ;

- vous voulez diffuser votre produit contenu dans votre assemblage sans dépendance à d'autres assemblages ;

- Delphi est votre « langage maternel » et il n'existe (à ma connaissance) aucun Framework .NET de création de portails Internet en Delphi .NET.

II-C - Configuration XML

Les informations de présentation (onglets, composition des onglets), de sécurité (rôles associés…) du portail ainsi que l'index du portail (PortalId) sont stockés dans le fichier Portal.XML. À ce fichier correspond un mappage objet de type Stronged Typed DataSet défini dans l'unité « PortalCfg.pas ». Dans le code C# original, ce mappage (PortalCfg.cs) est automatiquement obtenu via l'utilitaire XSD.EXE du framework.

Utilisation de XSD.EXE : mappage d'un schéma XML vers un Stronged Typed DataSet en langage C#

C:\Program Files\Microsoft.Net\SDK\v1.1\Bin\XSD.EXE PortalCfg.xsd /language:CS /D

Cependant avec l'utilitaire « XSD.exe », il n'est pas possible d'utiliser le provider de code Delphi (DelphiCodeProvider). Cet utilitaire ne sait pas utiliser le fournisseur de code Delphi. Dans ce projet, après une longue recherche pour pallier ce problème, le fichier « PortalCfg.pas » est la traduction du fichier C# original (PortalCfg.cs) via BabelClient.

Ce service de traduction automatique de C# vers Delphi n'est pas totalement efficace, des corrections manuelles sont ajoutées dans le source du fichier « PortalCfg.pas ».

Cet exemple avec FireBird réalise un mappage via une base de données vers un Stronged Typed DataSet en langage Delphi.

Un outil de réflexion peut être utile pour réaliser rapidement la traduction d'un assembly initialement en C# vers Delphi. Le reflector de Lutz Roeder est performant dans cette tâche. Il est d'une aide précieuse dans la traduction (recherche de namespaces correspondant à une classe…).

Structure de « PortalCfg.XML » : nœuds, pages et contrôles principaux impliqués

Aperçu de la configuration 'PortalCfg.XML' et page et composant impliqués

Un portail est référencé par un index (PortalId) présent dans le fichier de configuration du portail (PortalCfg.xml). Chaque page correspondant à un onglet est référencée dans un nœud « Tab ». À chacun de ces nœuds correspondent les nœuds enfants des modules assemblés par cette page. Comme pour la partie haute (bannière) de la page modèle, les modules sont eux-mêmes composites. La partie titre est implémentée dans un composant spécial. Pour les modules standards, ce contrôle est « DesktopModuleTitle.ascx ». Pour les modules spécifiques aux mobiles, le titre du module est implémenté par « MobileModuleTitle.ascx ».

II-D - Modules enfichables

La notion de contrôle utilisateur ASP.NET (extension ASCX) permet de créer un site résultant de l'assemblage de composants. Cette notion objet nouvellement intégrée à ASP.NET est très utilisée dans ce projet. Chaque entité du portail correspond à un contrôle utilisateur. Cette notion est identique aux principes des composants dans Delphi.

Les modules de présentation de contenu sont composés de deux parties principales correspondant à un contrôle de présentation et une page d'administration :

- le contrôle de présentation du contenu (par exemple « Announcements.ascx ») ;

- la page d'administration du contenu (par exemple « EditAnnouncements.aspx »).

Le contrôle utilisateur ASP.NET de présentation de contenu (ascx) propose le lien vers l'édition. Ce lien (Modifier, Editer, Nouvelle annonce…) est présent dans la partie titre (contrôle utilisateur ASP.NET « DesktopModuleTitle.ascx ») du module.

Extrait du contrôle utilisateur 'DesktopModuleTitle.ascx' - lien vers l'édition de contenu du module

<asp:hyperlink id=EditButton enableviewstate="false"
cssclass="CommandButton" runat="server">
</asp:hyperlink>

Les modules spécifiques aux mobiles n'implémentent pas l'édition en ligne. Pour modifier le contenu présenté par un module mobile, il est nécessaire d'utiliser la partie « Desktop » du portail.

Chacun des modules de présentation de contenu hérite d'un contrôle générique « TPortalModuleControl ». Cet héritage permet d'implémenter les règles communes au portail (charte graphique, sécurité…). Ces modules implémentent également des règles métier spécifiques à leurs tâches (polymorphisme).

Les unités dans lesquelles sont implémentés les objets métier d'accès au contenu sont postfixées de « DB » (par exemple ContactDB.pas). Ces unités sont dans le répertoire : « \Components ». Un objet encapsule ces fonctionnalités. Voici par exemple la définition de l'objet métier du module « Contacts » :

Extrait de l'unité '\Components\ContactDB.pas' : Encapsulation des fonctionnalités métier du module Contacts

ContactsDB = class
public
constructor Create;
function AddContact(moduleId: Integer; itemId: Integer; userName: Widestring;
name: Widestring; role: Widestring; email: Widestring; contact1: Widestring; contact2: Widestring): Integer;
procedure DeleteContact(itemID: Integer);
function GetContacts(moduleId: Integer): DataSet;
{$IFDEF SQLSERVEUR}
function GetSingleContact(itemId: Integer): SqlDataReader;
{$ELSE}
function GetSingleContact(itemId: Integer): FbDataReader;
{$ENDIF}
procedure UpdateContact(moduleId: Integer; itemId: Integer; userName: Widestring;
name: Widestring; role: Widestring; email: Widestring; contact1: Widestring; contact2: Widestring);
end;

Le fichier « Portal.XML » ne contient aucune donnée relative au contenu d'un module (sauf pour le cas particulier des modules « Image » et « XML/XSL »). Seuls les index et les rôles associés aux modules sont présents dans la configuration « PortalCfg.xml ». Les données correspondant au contenu d'un module sont stockées dans une base de données (Microsoft SQL Server ou FireBird). L'index du module est utilisé pour indexer ce contenu dans la base de données.

II-E - Utilisateur et rôle : sécurité

Lors de l'ajout et de la composition d'une page dans la partie administration du site, les droits de consultation (AccessRoles) de cette page ainsi que les droits en édition des modules (EditRoles) sont fixés. Ces droits sont sauvegardés dans le fichier « PortalCfg.XML » :

L'objet « PortalSecurity » défini dans l'unité \Components\security.pas possède trois méthodes permettant de tester les paramètres de sécurité définis dans la configuration :

Extrait de l'unité \Components\security.pas - Classe PortalSecurity : Sécurité et Configuration

PortalSecurity = class
public
constructor Create;
class function Encrypt(cleanString: Widestring): Widestring; static;
class function HasEditPermissions(moduleId: Integer): boolean; static;
class function IsInRole(role: Widestring): boolean; static;
class function IsInRoles(roles: Widestring): boolean; static;
end;

II-F - ASP.NET Mobile

Un article d'introduction à ASP.NET Mobile est disponible sur le site pchapuis.developpez.com.

L'accès aux périphériques mobiles utilise une page typée ASP.NET Mobile héritant de la classe .NET « MobilePage ». Comme pour les pages des périphériques de type « Desktop », une page modèle est définie : « MobileDefault.aspx » spécifiquement pour ces périphériques.

La redirection en fonction du type de périphérique n'est pas automatique. Elle est prise en charge par le code suivant :

Redirection dans la page par défaut (Default.aspx) des périphériques en fonction de leur type

procedure TWebFormDefault.Page_Load(sender: System.Object; e: System.EventArgs);
begin
if (Request.Browser['IsMobileDevice']= 'true' )
then Response.Redirect(DEFAULT_MOBILEINDEX)
else Response.Redirect(DEFAULT_DESKTOPINDEX);
end;

La page « MobileDefault.aspx » inclut une fiche spécifique au mobile (« System.Web.UI.MobileControls.Form ») et un contrôle « TabbedPanel » défini dans l'unité « MobileControls ».

Ce contrôle MobileControls.TabbedPanel est équivalent aux onglets des pages pour « Desktop ». Il implémente les spécificités d'un contrôle dédié aux périphériques mobiles. Il gère par exemple l'arborescence, la pagination ainsi que le type de vue de la page (SummaryView).

Ce contrôle « TabbedPanel » est encapsulé dans différents adaptateurs. Ces adaptateurs permettent la prise en charge spécifique des différents formats (HTML 3.2, WML 1.1, cHTML) disponibles avec ASP.NET Mobile.

Extrait de l'unité 'MobileControls' - adaptateurs spécifiques

HtmlTabbedPanelAdapter = class(HtmlControlAdapter)
strict protected
public
procedure Render(writer: HtmlMobileTextWriter); override;
function get_Control: TabbedPanel; reintroduce;
property Control: TabbedPanel read get_Control;
strict private
class function GetColorString(color: Color; defaultColor: Widestring): Widestring;static;
end;

WmlTabbedPanelAdapter = class(WmlControlAdapter)
strict private
_menu: List;
procedure OnListItemCommand(sender: &Object; e: ListCommandEventArgs);
strict protected
function get_Control: TabbedPanel; reintroduce;
property Control: TabbedPanel read get_Control;
public
procedure OnInit(e: EventArgs); override;
procedure OnLoad(e: EventArgs); override;
procedure Render(writer: WmlMobileTextWriter); override;
end;

ChtmlTabbedPanelAdapter = class(HtmlControlAdapter)
strict protected
function get_Control: TabbedPanel; reintroduce;
property Control: TabbedPanel read get_Control;
public
procedure Render(writer: HtmlMobileTextWriter); override;
end;

Pour être instanciés par le site (dans le source des pages ASPx), ces contrôles spécifiques doivent être enregistrés dans le fichier de configuration « Web.config.XML » du site :

Ce recensement dans « web.config.xml » fixe la relation entre un format spécifique (HtmlDeviceAdapters, ChtmlDeviceAdapters, WmlDeviceAdapters), un composant spécifique prenant en charge ce format et l'assemblage implémentant ce composant.

Dans ce projet Delphi, une ligne de code est ajoutée dans l'unité « MobileDefault.pas » pour supprimer la répétition des éléments de menu WML pour le premier élément. Cette ligne de code n'est pas présente dans le projet C# initial. Ce code spécifique au projet Delphi est le suivant :

if Assigned(WmlTabbedPanelAdapter(TabView.Adapter)) and (TabIndex=0) then exit;

II-G - Fonctionnement du cache

Actuellement les sites Internet sont rarement adaptés pour répondre aux montées en charge. Lors d'une vague de connexion massive, le site dans le meilleur des cas ne répond plus ou dans le pire des cas la machine/le système passe hors service. Pour faire face à ce type de problème, un système de cache est implémenté dans le projet.

L'objet TCachedPortalModuleControl stocke automatiquement dans le cache du système la chaîne HTML correspondant à un module.

Définition de l'objet 'TCachedPortalModuleControl' défini dans l'unité 'DesktopControls.pas'

TCachedPortalModuleControl = class(Control)
// Private field variables
private
_moduleConfiguration: ModuleSettings;
_cachedOutput   : Widestring;
_portalId       : integer;
strict protected
procedure CreateChildControls; override;
procedure Render(output: HtmlTextWriter); override;
public
function get_CacheKey: Widestring;
function get_ModuleId: Integer;
// Methods
public constructor Create;
published
// Properties
property CacheKey: Widestring read get_CacheKey;
property ModuleConfiguration: ModuleSettings read _ModuleConfiguration write _ModuleConfiguration;
property ModuleId: Integer read get_ModuleId;
property PortalId: Integer read _PortalId write _PortalId;
end;

L'objet TCachedPortalModuleControl est mis en œuvre dans la page par défaut (DesktopDefault.aspx). Lors de la construction de la page correspondant à l'onglet sélectionné, le cache est créé. Chaque module inséré dans une page peut définir le temps d'expiration de ce cache (CacheTimeout) :

configuation XML d'un module 'Liens rapides' avec le cache activé (CacheTimeout=120)

<Module ModuleId="1"
ModuleTitle="QuickLinks"
EditRoles="Admins;Participants;"
ModuleDefId="8"
PaneName="leftPane"
CacheTimeout="120"
ModuleOrder="7"
ShowMobile="false"/>

Cet objet de gestion du cache est mis en œuvre par le framework via les méthodes « Render » (capture) et « CreateChildControls » (restitution). La méthode « Render » surchargée permet (dans le cas où CacheTime est différent de 0) de « capturer » le contenu HTML correspondant à un module. Cette chaîne HTML est alors insérée dans le cache du contexte avec le timeout correspondant au cache du module correspondant :

DesktopControls.TCachedPortalModuleControl.Render : capture dans la cache de la chaîne HTML correspondant à un module

procedure TCachedPortalModuleControl.Render(output: HtmlTextWriter);
var
tempWriter : TextWriter;
begin
if (_moduleConfiguration.CacheTime = 0) then
begin
inherited Render(output);
exit;
end
else
begin
if (_cachedOutput = '') then
begin
tempWriter := stringWriter.Create();
inherited Render(HtmlTextWriter.Create(tempWriter));
_cachedOutput := tempWriter.ToString();
Context.Cache.Insert(    CacheKey,_cachedOutput,
nil,
DateTime.Now.AddSeconds(_moduleConfiguration.CacheTime),
TimeSpan.Zero);
end;
output.Write(_cachedOutput);
end;
end;

Dans la méthode surchargée « CreateChildControls », la chaîne correspondant au module est restituée via son chargement à partir du cache du contexte. Si la chaîne n'est pas trouvée alors le module est entièrement recréé (timeout).

DesktopControls.TCachedPortalModuleControl.CreateChildControls : restitution d'un module via le cache

var
module : TPortalModuleControl;
begin
if (_moduleConfiguration.CacheTime > 0) then
_cachedOutput := Widestring(Context.Cache[CacheKey]);
if (_cachedOutput='') then
begin
inherited CreateChildControls();
module := TPortalModuleControl(Page.LoadControl(_moduleConfiguration.DesktopSrc));
module.ModuleConfiguration := Self.ModuleConfiguration;
module.PortalId := Self.PortalId;
Self.Controls.Add(module);
end;

III - Carences de cette version

Delphi ASP.NET Portal Starter Kit correspond à une stricte traduction du projet C# original. Bien que le projet initial soit mature, il subsiste néanmoins quelques problèmes mineurs.

III-A - Configuration « PortalCfg.XML » et HttpContext.Current

Problème : la configuration « PortalCfg.XML » du portail est stockée dans le cache du contexte http (unité « uConfiguration.pas » : HttpContext.Current.Cache). Lors de l'administration du site, la sauvegarde/restitution de cette configuration est parfois erronée. Ainsi les modifications ne sont pas prises en compte immédiatement. Il peut se produire une erreur suite à la désynchronisation des informations de configuration.

Solution proposée : la configuration « PortalCfg.XML » peut être stockée dans une table de la base de données. Ce stockage offre l'avantage d'un accès transactionnel. L'inconvénient de cette solution est un temps d'accès supérieur à celui d'un accès au cache.

Dans le source du projet, des modifications (HttpContext.Current.Application) ont été apportées pour résoudre le problème de la désynchronisation de la configuration du cache. Ces modifications ne sont pas suffisantes (cf. unité uConfiguration.pas et commentaire « PC++ »).

III-B - Ordre des onglets et des modules

Problème : il peut être difficile de changer la position d'un onglet ou d'un module. Ceci est principalement causé par l'algorithme simplet d'incrémentation/décrémentation de l'index de l'élément. Les tests concernant ce problème doivent prendre en compte le problème connexe énoncé dans le point 3.1.

Solution proposée : l'algorithme de modification des index et/ou de déplacement d'un élément doit-être amélioré.

III-C - Accès ADO à différentes bases de données

Problème : pour un besoin de code source unique et de simplicité, l'accès à la base SQL Server ou Interbase est conditionné par la directive de compilation « SQLSERVEUR ». Les composants ADO permettant cet accès sont typés et donc différents en fonction de la base de données utilisée.

Solution proposée : il existe des composants ADO permettant un accès générique. La mise en œuvre de tels composants permet de supprimer la directive de compilation et ainsi d'alléger le code source d'accès à la base. Avec de tels composants, seule la chaîne de connexion conditionne le type de base de données couplée avec le portail.

III-D - Divers

Autres imperfections diverses :

- la suppression d'un élément (onglet, modules…) n'est pas précédée d'une confirmation de suppression ;

- dans le module Discussion, la suppression n'est pas proposée. Après un nouveau message, le retour à la discussion n'est pas implémenté.

IV - Améliorations proposées

De nombreuses fonctions nécessaires à un portail professionnel ne sont pas implémentées dans le projet. Certaines de ces améliorations sont en cours de développement par l'auteur de cette version. Ces améliorations impliquent des modifications dans les objets principaux du projet.

IV-A - Édition de contenu et granularité des primitives d'édition

Carence : l'édition du contenu d'un module est en mode « tout ou rien ». L'utilisateur possédant le rôle d'administrateur accède à toutes les fonctions (insertion, édition, suppression). Les autres utilisateurs ne possédant pas ce droit d'administration n'ont accès à aucune fonction d'édition de contenu. Il serait intéressant de dégrader cet accès en édition pour offrir par exemple un accès « opérateur de suppression » ou encore « modérateur »…

Solution proposée : une table énumère les différentes actions possibles en mode édition (insertion, édition, suppression, modération). Les rôles sont associés avec les éléments de cette table. Le problème majeur de cette solution est de ne pas définir de droits relatifs aux modules. Par exemple l'opérateur de suppression devient opérateur de suppression pour tous les modules.

IV-B - Validation de la publication : modérateur

Carence : actuellement en mode administration de contenu, les données insérées/modifiées sont immédiatement publiées. Il est uniquement possible de modérer un module via la consultation régulière et la suppression d'un élément indésirable. Cependant un élément indésirable peut être potentiellement consulté avant d'avoir été supprimé.

Solution proposée : ce besoin n'est pas vraiment une exigence pour tous les modules. En conséquence, une extension des fonctions métier des modules concernés règle ce problème. Par exemple pour les discussions, l'ajout d'un nouveau champ (Approuved) de type booléen permet de vérifier si l'élément peut être publié. La valeur de ce champ est fixée à FALSE à l'insertion. Un bouton permet de basculer l'état de ce champ à Vrai (Approuved). Ce bouton est uniquement disponible pour les utilisateurs possédant le rôle de « modérateur ». Une extension à cette solution est de stocker l'historique des modifications d'un élément. Ceci permet de suivre les différentes interventions faites par les différents opérateurs sur un élément.

IV-C - Portail multilingue

Carence : le portail ne propose pas le choix de la langue de publication des informations. La structure des tables et de la configuration n'anticipe pas cette fonctionnalité de globalisation.

Solution proposée : cette fonctionnalité est implémentée au niveau du module. Le module générique dont héritent les modules implémente cette fonctionnalité. Un attribut supplémentaire permet de définir la langue dans laquelle est disponible l'information. Ce choix d'un langage parmi les langages disponibles est proposé par le module générique à l'utilisateur et à l'administrateur de contenu. Le changement de langue d'un module doit être propagé à l'ensemble des modules de la page en cours. Ceci est effectué par une variable de session qui stocke les préférences utilisateur.

IV-D - Personnalisation de la charte graphique

Carence : une fonctionnalité standard dans les « portails Internet modernes » est la personnalisation de la charte graphique (skins). Dans le projet Delphi ASP.NET Portal Starter Kit seule une feuille de style (ASPNETPortal.css) permet de modifier l'aspect général du portail. Il serait intéressant d'ajouter une fonctionnalité de personnalisation graphique.

Solution proposée : la factorisation d'un module en plusieurs parties (entête, pied de page, bordure) résout en grande partie ce problème. Ces nouvelles parties communes à tous les modules sont sélectionnées parmi une liste composée d'éléments de styles différents. Ces différents styles sont obtenus via l'association à des feuilles de styles distinctes et/ou via une personnalisation du style HTML de l'élément factorisé.

IV-E - Arborescences et onglets (tabs)

Carence : l'arborescence du site associée à des onglets est limitée. C'est une simple liste. Il n'est pas possible de hiérarchiser un élément de façon à avoir un sous-menu.

Solution proposée : pour obtenir une arborescence plus hiérarchisée, le système offre le choix du contrôle permettant la sélection de la page en cours. Les différents choix pour ce contrôle sont : onglets ou menu. Le choix d'une arborescence de type menu entraine une modification de la structure du fichier de configuration du site (PortalCfg.xml). Une liste de listes à n niveaux permet de proposer une arborescence de type simple (onglets) ou complexe (menu). Associé à cette nouvelle structure, un contrôle utilisateur ASP.NET doit offrir une interface utilisateur de type correspondant (Menu).

IV-F - Modules supplémentaires

Carence : actuellement certaines fonctionnalités classiques ne sont pas implémentées. Par exemple, un module recherche n'est pas proposé. De même, un module « lettre d'informations » serait le bienvenu. L'implémentation actuelle du portail ne traite pas l'aspect courrier électronique…

Solution proposée : l'implémentation d'un module de recherche est assez complexe, car cette recherche doit être limitée au contenu du portail autorisé à l'utilisateur (AccessRoles) effectuant cette recherche. Ainsi la recherche est dépendante de la configuration du portail associé à l'utilisateur en cours. C'est la configuration qui donne le référentiel de recherche. Rechercher sur les modules de type « annonces, documents ou autres » semble être un critère supplémentaire intéressant pour restreindre la recherche. La recherche sur les documents (doc, xls…) suppose l'utilisation d'un moteur de recherche permettant la recherche fulltext dans des formats variés. Microsoft Index Server est indiqué pour ce type d'exigence.

IV-G - Modules pluggables de Dot Nuke Net et interfaces

Les fonctionnalités d'un module ne sont pas forcément nécessaires à tous les modules. Par exemple, la fonction de recherche est inutile pour une image. Ce constat est appréhendé dans Dot Nuke Net (DNN) via les interfaces. Les nouvelles fonctions associées aux portails sont déclarées et implémentées via des interfaces. Seul le moteur (page) est éventuellement modifié pour prendre en charge ces nouvelles fonctionnalités. Par exemple l'interface « ISearchable » est utilisée pour invoquer une recherche sur les modules l'implémentant. Cette figure de style conceptuelle (design pattern) correspond au « décorator » ou « wrapper ». Dans le cadre de l'évolution du produit, ce modèle de conception sera utilisé.

V - Conclusion

Le projet Delphi ASP.NET Portal Starter Kit est un projet important de par sa taille. C'est un excellent exemple pour découvrir la technologie du futur que constitue Microsoft ASP.NET. Les différents points forts de cette technologie sont inclus dans ce projet. La partie Mobile permet d'imaginer des applications Internet jusque là difficiles à réaliser avec Delphi. Outre ce côté pédagogique, ce projet permet de réaliser simplement un portail Internet. Un produit réellement professionnel est largement envisageable moyennant quelques jours de développement afin de compléter cette solution séduisante.

VI - Références

VI-A - Microsoft ASP.NET

- Portail Microsoft dédié à ASP.NET

- Démonstration en ligne du projet initial : Portal Starter Kit

- Document Microsoft (format Word) Portal Whitepaper.doc

- Code Source du serveur web CASSINI

VI-B - Delphi ASP.NET Portal Starter Kit

- Téléchargement du code source du projet Delphi ASP.NET Portal Starter Kit sur CodeCentral.Borland.com

- Procédure d'installation et FAQ sur ChapsAndChips.chez.tiscali.fr

- Démonstration en ligne du projet Delphi ASP.NET Portal Starter Kit sur www.Delphinaute.be/ChapsAndChips

- Article « Une introduction à ASP.NET Mobile » sur Developpez.com

- Autres implémentations Delphi des Starters Kits sur www.aspxDelphi.net

VI-C - Autres projets de portail Internet

- un projet français : Open Portal

- le fameux Dot Nuke Net

- Rainbow Portal

- php et PHP-Nuke

- J2EE et Magnolia

- ASPNuke

- Xoops

- Jahia

VII - Remerciements

L'auteur du projet Delphi ASP.NET Portal Starter Kit, remercie très sincèrement Norbert Saint Georges pour son soutien concernant ce projet Delphi ainsi que pour l'hébergement de la démonstration du projet gracieusement offert sur Delphinaute.be.

Merci également à Bestiol pour la relecture de cet article.