Fermer

août 24, 2022

Livraison de contenu – Suppression des champs nécessaires et comment ajouter de nouveaux champs à la réponse de l’API


Qu’est-ce qu’un CMS sans tête ?

UN CMS sans tête est un système de gestion de contenu (CMS) back-end uniquement conçu à partir de zéro en tant que référentiel de contenu qui rend le contenu accessible via une API RESTful ou une API GraphQL pour un affichage sur n’importe quel appareil.

Le terme « sans tête » vient du concept consistant à couper la « tête » (le front-end, c’est-à-dire le site Web) du « corps » (le back-end, c’est-à-dire le référentiel de contenu). Un CMS sans tête reste avec une interface pour gérer le contenu et une API RESTful ou GraphQL pour fournir du contenu là où vous en avez besoin. En raison de cette approche, un CMS sans tête ne se soucie pas de savoir comment et où votre contenu est affiché. Il n’a qu’un seul objectif : stocker et diffuser du contenu structuré et permettre aux éditeurs de contenu de collaborer sur de nouveaux contenus.

Avec Optimizely, vous pouvez implémenter votre solution sans tête en utilisant le API de diffusion de contenu.

Pour filtrer la réponse de l’API et supprimer les champs dont vous n’avez pas besoin et/ou supprimer le champ nul pour obtenir la sortie plus agréable et plus claire dont vous avez besoin IContentApiModelFilter qui est expliqué dans le Documentation optimisée.

Mais, cela n’a pas fonctionné pour moi comme je le voulais.

Voici un exemple de réponse d’API par défaut au format JSON :

{
    "contentLink": {
        "id": 17,
        "workId": 0,
        "guidValue": "85d21fcb-6b86-47e2-8ac7-40561746f6b8",
        "providerName": null,
        "url": null,
        "expanded": null
    },
    "name": "Rich Text",
    "language": {
        "link": null,
        "displayName": "English",
        "name": "en"
    },
    "existingLanguages": [
        {
            "link": null,
            "displayName": "English",
            "name": "en"
        }
    ],
    "masterLanguage": {
        "link": null,
        "displayName": "English",
        "name": "en"
    },
    "contentType": [
        "Block",
        "RichTextBlock"
    ],
    "parentLink": {
        "id": 16,
        "workId": 0,
        "guidValue": "ff300114-39a2-469e-9304-3703317a4894",
        "providerName": null,
        "url": "http://perficient.local/contentassets/ff30011439a2469e93043703317a4894/",
        "expanded": null
    },
    "routeSegment": null,
    "url": null,
    "changed": "2022-08-05T14:59:05Z",
    "created": "2022-08-05T14:59:05Z",
    "startPublish": "2022-08-05T14:59:05Z",
    "stopPublish": null,
    "saved": "2022-08-11T12:33:39Z",
    "status": "Published",
    "category": {
        "value": [],
        "propertyDataType": "PropertyCategory"
    },
    "globalStyle": {
        "value": "",
        "propertyDataType": "PropertyLongString"
    },
    "mainBody": {
        "value": "<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia, molestiae quas vel sint commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit fugiat iusto fuga praesentium optio, eaque rerum! Provident similique accusantium nemo autem. Veritatis obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas aliquid. Reprehenderit, quia.</p>\n<p><img src=\"http://perficient.local/globalassets/crop.jpg\" alt=\"crop\" width=\"1280\" height=\"853\" /></p>\n<p>&nbsp;</p>\n<p><img src=\"http://perficient.local/contentassets/b20dbeb471b94ba18ba2f76cfdab5a05/caesars.png\" alt=\"caesars.png\" /></p>",
        "propertyDataType": "PropertyXhtmlString"
    }
}

Après avoir ajouté le Filtre de modèle d’API de contenu personnalisé comment est expliqué dans le Documentationvous obtiendrez quelque chose comme ceci :

{
    "contentLink": {
        "id": 17,
        "workId": 0,
        "guidValue": "85d21fcb-6b86-47e2-8ac7-40561746f6b8",
        "providerName": null,
        "url": null,
        "expanded": null
    },
    "name": "Rich Text",
    "language": {
        "link": null,
        "displayName": "English",
        "name": "en"
    },
    "existingLanguages": [
        {
            "link": null,
            "displayName": "English",
            "name": "en"
        }
    ],
    "masterLanguage": {
        "link": null,
        "displayName": "English",
        "name": "en"
    },
    "contentType": [
        "Block",
        "RichTextBlock"
    ],
    "parentLink": null,
    "routeSegment": null,
    "url": null,
    "changed": "2022-08-05T14:59:05Z",
    "created": null,
    "startPublish": null,
    "stopPublish": null,
    "saved": null,
    "status": null,
    "contentTypeGuid": "3c2ed8a86f1a41459d4498cfeb8a5652",
    "globalStyle": {
        "value": "",
        "propertyDataType": "PropertyLongString"
    },
    "mainBody": {
        "value": "<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia, molestiae quas vel sint commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit fugiat iusto fuga praesentium optio, eaque rerum! Provident similique accusantium nemo autem. Veritatis obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas aliquid. Reprehenderit, quia.</p>\n<p><img src=\"http://perficient.local/globalassets/crop.jpg\" alt=\"crop\" width=\"1280\" height=\"853\" /></p>\n<p>&nbsp;</p>\n<p><img src=\"http://perficient.local/contentassets/b20dbeb471b94ba18ba2f76cfdab5a05/caesars.png\" alt=\"caesars.png\" /></p>",
        "propertyDataType": "PropertyXhtmlString"
    }
}

Pour cet exemple, j’ai mis les valeurs nulles pour ces champs :

contentApiModel.StartPublish = null;
contentApiModel.StopPublish = null;
contentApiModel.ParentLink = null;
contentApiModel.RouteSegment = null;
contentApiModel.Created = null;
contentApiModel.Saved = null;
contentApiModel.Status = null;

Vous pouvez voir dans la réponse JSON précédente que ces champs sont toujours là mais avec la valeur nulle.

Pour réellement supprimer ces champs annulés, vous devez ajouter une option de paramètres dans Startup.cs services dans la section Livraison de contenu.

// remove null values from serialized data
services.ConfigureContentDeliveryApiSerializer(settings =>
{
     settings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
});

La seule chose ici est que le ConfigureContentDeliveryApiSerializer est dans le Interne espace de noms, mais cela n’ira nulle part de si tôt.

Nous avons maintenant cette réponse JSON agréable et propre :

{
    "contentLink": {
        "id": 17,
        "workId": 0,
        "guidValue": "85d21fcb-6b86-47e2-8ac7-40561746f6b8"
    },
    "name": "Rich Text",
    "language": {
        "displayName": "English",
        "name": "en"
    },
    "existingLanguages": [
        {
            "displayName": "English",
            "name": "en"
        }
    ],
    "masterLanguage": {
        "displayName": "English",
        "name": "en"
    },
    "contentType": [
        "Block",
        "RichTextBlock"
    ],
    "changed": "2022-08-05T14:59:05Z",
    "globalStyle": "",
    "mainBody": "<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia, molestiae quas vel sint commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit fugiat iusto fuga praesentium optio, eaque rerum! Provident similique accusantium nemo autem. Veritatis obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas aliquid. Reprehenderit, quia.</p>\n<p><img src=\"http://perficient.local/globalassets/crop.jpg\" alt=\"crop\" width=\"1280\" height=\"853\"></p>\n<p>&nbsp;</p>\n<p><img src=\"http://perficient.local/contentassets/b20dbeb471b94ba18ba2f76cfdab5a05/caesars.png\" alt=\"caesars.png\"></p>"
}

Par exemple, pour une raison quelconque, je souhaite avoir un GUID de type de contenu en tant que champ dans la réponse JSON.

Ajoutez simplement ce code à la fin de votre Filtre de modèle d’API de contenu personnalisé.

contentApiModel.Properties[CONTENT_TYPE_GUID] = Guid.Empty.ToString("N");
if (contentApiModel.ContentLink.Id != null && contentApiModel.ContentLink.Id.HasValue)
{
    var content = contentLoader.Get<IContent>(new ContentReference(contentApiModel.ContentLink.Id.Value));
    var contentType = content.ContentTypeID;
    var type = contentTypeRepository.Load(contentType);

    if (type != null && type.GUID != Guid.Empty)
    {
        contentApiModel.Properties[CONTENT_TYPE_GUID] = type.GUID.ToString("N");
    }
}

Maintenant, la réponse sera comme ceci :

{
    "contentLink": {
        "id": 17,
        "workId": 0,
        "guidValue": "85d21fcb-6b86-47e2-8ac7-40561746f6b8"
    },
    "name": "Rich Text",
    "language": {
        "displayName": "English",
        "name": "en"
    },
    "existingLanguages": [
        {
            "displayName": "English",
            "name": "en"
        }
    ],
    "masterLanguage": {
        "displayName": "English",
        "name": "en"
    },
    "contentType": [
        "Block",
        "RichTextBlock"
    ],
    "changed": "2022-08-05T14:59:05Z",
    "contentTypeGuid": "3c2ed8a86f1a41459d4498cfeb8a5652",
    "globalStyle": "",
    "mainBody": "<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia, molestiae quas vel sint commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit fugiat iusto fuga praesentium optio, eaque rerum! Provident similique accusantium nemo autem. Veritatis obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas aliquid. Reprehenderit, quia.</p>\n<p><img src=\"http://perficient.local/globalassets/crop.jpg\" alt=\"crop\" width=\"1280\" height=\"853\"></p>\n<p>&nbsp;</p>\n<p><img src=\"http://perficient.local/contentassets/b20dbeb471b94ba18ba2f76cfdab5a05/caesars.png\" alt=\"caesars.png\"></p>"
}

Voici notre champ ajouté.

Champ Json

Et c’est tout!

Voici la liste de code pour cet exemple.

CustomContentApiModelFilter.cs

using EPiServer;
using EPiServer.ContentApi.Core.Serialization;
using EPiServer.ContentApi.Core.Serialization.Internal;
using EPiServer.ContentApi.Core.Serialization.Models;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.ServiceLocation;
using System;

namespace Perficient.Web.Middleware.ApiModelFilter
{
    [ServiceConfiguration(typeof(IContentApiModelFilter), Lifecycle = ServiceInstanceScope.Singleton)]
    public class CustomContentApiModelFilter : ContentApiModelFilter<ContentApiModel>
    {
        private readonly IContentLoader contentLoader;
        private readonly IContentTypeRepository contentTypeRepository;
        private const string CONTENT_TYPE_GUID = "ContentTypeGuid";

        public CustomContentApiModelFilter(IContentLoader contentLoader, IContentTypeRepository contentTypeRepository)
        {
            this.contentLoader = contentLoader;
            this.contentTypeRepository = contentTypeRepository;
        }

        public override void Filter(ContentApiModel contentApiModel, ConverterContext converterContext)
        {
            // To remove values from the output, set them to null.
            // thus the response output will not contain these "out of the box" fields
            contentApiModel.StartPublish = null;
            contentApiModel.StopPublish = null;
            contentApiModel.ParentLink = null;
            contentApiModel.RouteSegment = null;
            contentApiModel.Created = null;
            contentApiModel.Saved = null;
            contentApiModel.Status = null;

            // remove category as we don't need it at the API level
            contentApiModel.Properties.Remove("Category");

            #region Add Content Type GUID to output
            // add a field called contentTypeGuid which has the ID of the content type in the output, this will be
            // useful for keying off of to understand what type of content is being delivered
            contentApiModel.Properties[CONTENT_TYPE_GUID] = Guid.Empty.ToString("N");
            if (contentApiModel.ContentLink.Id != null && contentApiModel.ContentLink.Id.HasValue)
            {
                var content = contentLoader.Get<IContent>(new ContentReference(contentApiModel.ContentLink.Id.Value));
                var contentType = content.ContentTypeID;
                var type = contentTypeRepository.Load(contentType);

                if (type != null && type.GUID != Guid.Empty)
                {
                    contentApiModel.Properties[CONTENT_TYPE_GUID] = type.GUID.ToString("N");
                }
            }
            #endregion
        }
    }
}






Source link