L'importance des «modèles de branches» dans Episerver

Dans les systèmes CMS modernes, nous créons rarement des pages avec des mises en page fixes sans flexibilité. Souvent, nous donnons à l'équipe marketing le pouvoir de définir des expériences en plaçant un certain nombre de composants configurables sur la page dans la mise en page qui leur convient. C'est stimulant, mais peut aussi être intimidant si vous commencez constamment avec une ardoise vierge. Les modèles de branche sont un concept familier dans d'autres systèmes CMS qui permettent aux développeurs de définir des types de page fournis avec des composants préexistants chaque fois qu'une nouvelle page est créée. Ce concept est également disponible pour Episerver si vous savez où chercher.
Le problème et la solution
Lors de la création de pages dans Episerver, elles sont généralement fournies sans blocs prédéfinis. Lors de la création de pages, cela peut entraîner des difficultés car vous devez définir chaque bloc requis par la page. Bien sûr, en tant que développeurs, nous pouvons coder en dur quelques éléments tels que des héros sur la page elle-même, mais cela conduit à une inflexibilité et vous met sur la voie d'une apparence très statique. En plus de cela, les éléments de page codés en dur perdent la flexibilité du paradigme de bloc d'Episerver.
Pour contourner ce problème, nous pouvons utiliser le système d'événements d'Episerver pour définir un nombre de blocs avec lesquels la page doit être créée par défaut. Cela a l'avantage de permettre une expérience de population de contenu beaucoup plus rationalisée, tout en conservant la flexibilité et la puissance du système de blocage d'Episerver. Cela ressemble à une page beaucoup plus pratique pour remplir du contenu, n'est-ce pas?
Un peu de code
Pour y parvenir, nous devons d'abord définir et puiser dans l'événement Created. Pour ce faire, je crée un module d'initialisation comme ceci:
[InitializableModule] [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] public class EventsInitialization: IInitializableModule { public void Initialize (contexte InitializationEngine) { var events = context.Locate.ContentEvents (); events.CreatedContent + = CreatedContentEvent; events.CreatingContent + = CreatingContentEvent; } public void Uninitialize (contexte InitializationEngine) { var events = context.Locate.ContentEvents (); events.CreatingContent - = CreatingContentEvent; events.CreatedContent - = CreatedContentEvent; } private void CreatingContentEvent (expéditeur de l'objet, ContentEventArgs e) { if (e.Content est la page ICreateEvent) { page.OnCreating (expéditeur, e); } } private void CreatedContentEvent (expéditeur de l'objet, ContentEventArgs e) { if (e.Content est la page ICreateEvent) { page.OnCreated (expéditeur, e); } } } interface publique ICreateEvent { void OnCreated (expéditeur de l'objet, ContentEventArgs e); void OnCreating (expéditeur de l'objet, ContentEventArgs e); }
Désormais, à chaque fois qu'un élément est créé, je vérifie s'il implémente ICreateEvent
. Si l'élément le fait, j'appelle les événements OnCreated
et OnCreating
correspondants. C'est une manière assez astucieuse de gérer les événements d'Episerver que Daved Artemik a partagé avec moi plus tôt cette année. Vous pourriez mettre la logique de création dans ce module d'initialisation, mais je ne trouve pas que ce soit une approche très SOLIDE.
Une fois que cela est configuré, nous devons simplement avoir notre type de page implémenté ICreateEvent
et implémentez les méthodes en conséquence. En général, votre page doit avoir une ou plusieurs zones de contenu dans lesquelles vous allez placer des blocs par programme. Voici une version simplifiée de ma page:
[ContentType( GroupName = "General Pages", DisplayName = "Standard Content Page", GUID = "28f6892f-f86d-4154-89d5-dfeaef7cae2c", Description = "Standard content pages come with a Hero and Content Spot")] public class StandardContentPage: PageData, ICreateEvent { [Display( GroupName = SystemTabNames.Content, Name = "Main Content Area", Order = 320)] // dans mon cas, IStripeBlock et IPageContentBlock sont des types d'interface que la bibliothèque de blocs SCORE définit et implémente // cela nous permet de créer de nouveaux types de blocs qui devraient être disponibles pour être insérés partout, sans définir // les AllowedTypes dans tous les emplacements. IStripeBlock est pour le contenu de bord à bord, IPageContentBlock est pour le conteneur // éléments liés en CSS [AllowedTypes(typeof(IStripeBlock), typeof(IPageContentBlock))] ContentArea virtuel public MainContentArea {get; ensemble; } public void OnCreated (expéditeur de l'objet, ContentEventArgs e) { // dépendances var contentRepository = ServiceLocator.Current.GetInstance(); var contentAssetHelper = ServiceLocator.Current.GetInstance (); var blockService = ServiceLocator.Current.GetInstance (); // dossier où tous les blocs doivent être créés ContentAssetFolder folder = contentAssetHelper.GetOrCreateAssetFolder (ContentLink); // créer un emplacement de héros et de contenu var hero = blockService.CreateBlock (folder.ContentLink); var contentSpot = blockService.CreateBlock (folder.ContentLink); // ajouter des blocs à la zone de contenu var clone = CreateWritableClone () as StandardContentPage; if (clone.MainContentArea == null) clone.MainContentArea = nouveau ContentArea (); clone.MainContentArea.Items.Add (nouveau ContentAreaItem {ContentLink = hero.ContentLink}); clone.MainContentArea.Items.Add (nouveau ContentAreaItem {ContentLink = contentSpot.ContentLink}); // sauvegarder la page en arrière contentRepository.Save (clone, SaveAction.Default, AccessLevel.NoAccess); } public void OnCreating (expéditeur de l'objet, ContentEventArgs e) { } }
Et IBlockService est un service d'assistance simple pour supprimer un code standard:
public class BlockService: IBlockService { private en lecture seule IContentRepository _contentRepository; private readonly IContentTypeRepository _contentTypeRepository; public BlockService (IContentRepository contentRepository, IContentTypeRepository contentTypeRepository) { _contentRepository = contentRepository; _contentTypeRepository = contentTypeRepository; } public IContent CreateBlock(ContentReference parentFolder) { var type = _contentTypeRepository.Load (); var block = _contentRepository.GetDefault (parentFolder, type.ID); block.Name = type.DisplayName; _contentRepository.Save (bloc, SaveAction.Publish, AccessLevel.NoAccess); bloc de retour; } }
Désormais, chaque fois que nous créons des pages de ce type, nous recevons des blocs prédéfinis. Plus important encore, le héros n'est pas codé en dur sur la page, nous avons donc la possibilité de la personnaliser par groupe de visiteurs. Ceci est extrêmement puissant et je vous encourage à adopter cette approche pour tous les types de pages de votre système. Les auteurs de votre contenu vous remercieront!
Source link