Création d’un projet MVC .Net vide via le CMS Orchard

250px-Orchard_logo_1.svg

 

Dans cet article, je vais vous expliquer comment créer un projet .net vide avec le CMS Orchard. Nous verrons comment construire un module Orchard, étape par étape mais aussi la configuration de celui-ci une fois créé.

1- Création du module Orchard.

Un module Orchard est un projet ASP.net MVC qui se trouve dans le répertoire Modules d’Orchard. Il peut contenir plusieurs widgets et il doit être visible via l’interface d’administration d’Orchard à fin de  l’activer ou le désactiver.

La création du module Orchard se fait via les étapes suivantes:

  • Activez le module CodeGenaration via l’interface d’administration Orchard.
  • Ouvrez un cmd en mode admin puis lancez le programme orchard.exe qui se trouve dans le dossier bin d’Orchard.
  • Exécutez la commande codegen module OC.NewModule /IncludeInSolution:false

Le module sera ajouté dans le dossier modules

CreateModule

ExlorerModules

Notre module apparaît sous Visual studio sous la forme :

ModuleArchi

2-  Création du widget Orchard.

Pour créer un widget Orchard  il faut suivre les étapes suivantes :

  1. Création d’un content Part Record
  2. Création d’un content Part
  3. Création d’un content Part Handler
  4. Création de la vue Part EditorView
  5. Création d’un content Driver
  6. Module Data Migration
  7. Création du Placement.info

Avant d’aller plus loin, il faut garder à l’esprit qu’un widget Orchard possède deux aspects :

  • Aspect applicatif qui sera géré par asp.net mvc (contrôleur vue modèle).
  • Aspect administratif dans lequel on définit les propriétés d’administration comme par exemple la hauteur du widget, la taille des colonnes du widget, le nombre de lignes …

Orchard se charge de gérer tout ça à travers ses modèles (content part Record, content Part) ses contrôleurs (content Driver Content part Handler) et ses vues spécifiques à l’administration.

2-1 Création d’un content Part Record

Il représente le modèle des propriétés d’administration du widget qui sera stocké dans une table spécifique dans la base, ce model doit hériter de la classe ContentPartRecord :

using Orchard.ContentManagement.Records;
namespace NewSampleModule.Models
{
     public class ContactWidgetPartRecord : ContentPartRecord
{
    public virtual int HeightProperty { get; set; }
 }
}

 

2-2 Création d’un content Part

Le content part est utilisé par les vues pour afficher les propriétés d’administration

Par convention il doit être mis dans le dossier model

namespace NewSampleModule.Models
{
    public class ContactWidgetPart : ContentPart<ContactWidgetPartRecord>

   {
        public int HeightProperty
        {
            get { return this.Record.HeightProperty; }
            set { this.Record.HeightProperty = value; }
        }
    }
}

 

2-3- Création d’un content Part Handler

Content handler permet la définition du comportement du content part au moment de l’activation du module,  il offre la possibilité d’installer des repositories et de modifier des modèles de données avant de rendre le contenu.

Dans notre cas nous n’utiliserons pas d’événement, il va donc nous permettre uniquement de définir un repository pour permettre à Orchard de sauvegarder le content part record lors de la création du widget.

Par convention, il faut le créer dans le répertoire Handlers.

Il faut hériter de la classe abstraite ContentHandler :

using NewSampleModule.Models;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;

namespace NewSampleModule.Handlers
{
    public class ContactContentPartHandler: ContentHandler
    {
        public ContactContentPartHandler(IRepository<ContactWidgetPartRecord> repository)
        {           Filters.Add(StorageFilter.For(repository));
        }
    }
}

2-4- Création des vues PartView et partEditorView

PartEditorView est la vue d’administration du widget, il contient le formulaire de saisie des propriétés du widget

PartView est la vue qui contiendra les éléments du widget

La syntaxe des vues c’est du Razor  sans déclaration du modèle.

La convention est de placer la vue PartView dans le dossier Views/Parts  et la vue PartEditorView dans le dossier  View/EditorTemplates/Parts.

 

ContactContentPartEditorView.cshtml

<fieldset>
    <legend>@T("Widget's properties")</legend>
</fieldset>
<div class="editor-label">
    @T("Grid's height")
</div>
<div class="editor-field">
    @Html.EditorFor(x => x.HeightProperty)
    @Html.ValidationMessageFor(x => x.HeightProperty)
</div>

 

ContactContentPartView.cshtml

<div id="@Model.Id">
    Contact Widget sample
</div>

 

Remarque :

Dans la vue ContactPartView, on remarque la définition de l’id de la div principal du widget, cela servira pour identifier le widget en question. En effet, dans Orchard on peut instancier le même widget plusieurs fois, chaque instance a sa propre Id et correspond à un Content part Record.

2-5 Création d’un content Driver

Il joue le même rôle qu’un contrôleur dans asp.net MVC. Il permet le rendu du content part pour l’édition de ses propriétés d’administration et pour afficher le widget.

La convention est de le placer dans le répertoire Drivers du module

La classe doit hériter de la classe abstraite ContentPartDriver, il faut définir la méthode display pour afficher la vue ContactPartView, et la méthode Editor pour afficher la vue ConactPartEditorView.

using NewSampleModule.Models;
using Orchard.ContentManagement.Drivers;

namespace NewSampleModule.Drivers
{
    public class ContactContentPartDriver : ContentPartDriver<ContactWidgetPart>

    {
        protected override string Prefix

        {
            get { return "ContactWidgetPart"; }

        }

protected override DriverResult Display(ContactWidgetPart part, string displayType, dynamic shapeHelper)

        {
            return ContentShape("Parts_ContactContentPartView",
                () => shapeHelper.Parts_ContactContentPartView(
                        Id: part.Id,
                        HeightProperty: part.HeightProperty
                       )
                );
        }

protected override DriverResult Editor(ContactWidgetPart part, dynamic shapeHelper)

        {
            return ContentShape("Parts_ContactContentPartEditorView_Edit",
             () => shapeHelper.EditorTemplate(
                 TemplateName: "Parts/ContactContentPartEditorView",
                 Model: part,
                 Prefix: Prefix));

        }      

    }

}

 

Remarque :

Il faut obligatoirement respecter les règles de nommage suivantes pour avoir le résultat :

  • Le nom du content part Record doit être le même que le nom de table défini dans la migration (pour plus d'info voir la section suite.) (ContactWidgetPartRecord) .
  • Le nom du content part Record doit avoir comme préfixe le nom du content part (ContactWidgetPartRecord), (ContactWidgetPart)
  • Le nom de la partView (ContactContentPartView) doit être le même que celui défini dans le driver (Parts_ContactContentPartView).
  • Idem Le nom de la PartEditorView (Parts_ContactContentPartEditorView_Edit)  doit être le même que dans le driver (Parts_ContactContentPartEditorView_Edit) et (Parts/ContactContentPartEditorView).

 

2-6 Module Data Migration

Ce module se charge de mettre à jour le schéma de la base de données d’Orchard, comme expliqué avant, un content part record représente une instance du widget. Il correspond à une ligne de la table représentant les instances du widget dans orchard, cette table sera créée par le module Data Migration.

Par convention ce module sera placé à la racine.

Voici à quoi va ressembler ce module :

namespace NewSampleModule
{
    public class Migrations : DataMigrationImpl
    {
        public int Create()

        {
            SchemaBuilder.CreateTable("ContactWidgetPartRecord", table => table
             .ContentPartRecord()
             .Column<int>("HeightProperty")
             );

            ContentDefinitionManager.AlterPartDefinition("ContactWidgetPart", builder => builder.Attachable());
            ContentDefinitionManager.AlterTypeDefinition("ContactWidget",
                type => type               
              .WithPart("ContactWidgetPart")
              .WithPart("WidgetPart")
              .WithPart("CommonPart")                    
              .WithSetting("Stereotype", "Widget")
              .DisplayedAs("Contact Widget"));
            return 1;
        }
    }
}

2-7- Création du Placement.info

La dernière étape est la création du fichier Placement.info qui indique à Orchard l’ordre dans lequel les parts sont rendues, ce fichier est indispensable pour avoir un rendu du widget. Il doit être mis à la racine.

Voici son contenu :

<Placement>

  <Place Parts_ContactContentPartView="Content:1" />

  <Place Parts_ContactContentPartEditorView_Edit="Content:2" />

</Placement>

A chaque fois qu’on veut afficher une nouvelle vue, il faut l’ajouter dans ce fichier en incrémentant l’ordre.

A ce stade l’architecture de l’application est la suivante :

ModulePlacement

Après le build et le recyclage du pool, on doit voir  le module NewSampleModule apparaître dans la liste des modules d’Orchard (accessible dans l’interface d’administration d’orchard/modules)

 

ModulesOrchard

3- Configuration du nouveau module

Après l’activation du nouveau module, il faut configurer son widget pour l’afficher dans le site d’Orchard. Pour cela il faut suivre ces étapes :

  • Dans la pages widgets accessible via le menu Widgets, cliquez sur le bouton add de la ligne content :

WidgetsOrchard

  • Choisissez le widget à inclure dans la partie content. Dans notre cas, on inclut Contact Widget.

SelectWidgets

  • Lorsqu’on clique sur Contact Widget on est redirigé vers la page d’administration du widget dans laquelle on va saisir les informations spécifiques à ce widget, c’est la fameuse page ContentPartEditorView qu’on a créé auparavant :

WidgetProperties

  • Il faut saisir le titre du widget.
  • Après la sauvegarde, cliquez sur le logo du site pour rafraîchir et voir la vue ContentPartView

OrchardResult

Dans le blog suivant, je vous expliquerez comment créer les menus, les couches (layers) et les pages dans Orchard.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.