1

We are using DXA 2.2 on the .Net project

Need suggestions on how can we extend functionality to map DefaultModelBuilder.MappingData metadata field to Model.

we have this Model class

public class MediaDistribution : EclItem
{
public string HtmlTitle { get; set; }
public string HtmlInnerText { get; set; }
}

on mapping

"paragraph": {
"$type": "ContentModelData",
"description": {
    "$type": "RichTextData",
    "Fragments": [
        {
            "$type": "EntityModelData",
            "Id": "118640",
            "Namespace": "tcm",
            "Folder": {
                "Id": "74789",
                "Title": "F6D"
            },
            "BinaryContent": {
                "Url": "https://dxa.widen.net/content/gkjrtlknvcnx/original/2021dxa-Slavery-and-Human-Trafficking-Statement-for-Jan-2021-to-Dec-2021-_pw.pdf?u=cglmil&",
                "FileName": "【2021年度】dxa Slavery and Human Trafficking Statement (for Jan 2021 to Dec 2021) _pw.pdf",
                "FileSize": 0,
                "MimeType": "pdf"
            },
            "ExternalContent": {
                "Id": "ecl:19-wid-gkjrtlknvcnx-widenFile-file",
                "DisplayTypeId": "widenfile",
                "TemplateFragment": "<iframe src='https://dxa.widen.net/content/gkjrtlknvcnx' ></iframe>",
                "Metadata": {
                    "Title": "【2021年度】dxa Slavery and Human Trafficking Statement (for Jan 2021 to Dec 2021) _pw.pdf",
                    "LastAccessedDate": "2022-06-20T00:15:02.000",
                    "ContentType": "pdf",
                    "Tags": {
                        "$type": "String[]",
                        "$values": [
                            "gkjrtlknvcnx",
                            "18058e97-2607-4bc9-912f-36db0767ec7e",
                            "[]",
                            "Website",
                            "None",
                            "[\r\n  \"Other\"\r\n]"
                        ]
                    },
                    "Width": "0",
                    "Height": "0",
                    "Filename": "【2021年度】dxa Slavery and Human Trafficking Statement (for Jan 2021 to Dec 2021) _pw.pdf",
                    "CreatedAt": "2022-06-20T00:15:02.000",
                    "ThumbnailETag": "",
                    "CanUpdate": "False"
                }
            },
            "Metadata": {
                "html-title": "dxa dxa Systems Slavery and Human Trafficking Statement (For Financial Year Ended Dec 31, 2021)",
                "html-innerText": "Read \"dxa dxa Systems Slavery and Human Trafficking Statement (For Financial Year Ended Dec 31, 2021)\""
            },
            "SchemaId": "65530"
        }
    ]
}

we need to read html-title and html-innertext from the above graphql response, however dxa doesn't map this information to Model field if we apply semantics as ["html-title"] and ["html-innerText"].

We tried to add "html-title" field on stub schema metadata, and that is not showing on mappings/schemas.json even after publish the publish setting.

could someone please suggest how can we achieve this

1
  • For clarity: the JSON fragment you're showing is so-called DXA R2 JSON. It can indeed be returned from a Content Service GraphQL query, but it's just a JSON serialization of the DXA R2 Data Model; it's the input for Semantic Mapping in the DXA Web Application. Commented Apr 13, 2023 at 8:32

2 Answers 2

2

You can build the Custom Entity Model Builder based on IEntityModelBuilder to set this value to your model, In order to fetch to be available in the view a custom model builder was required to extract these from metadata created at publish time by DXA TBBs.

Example for the custom model builder:

namespace Sdl.Web.Modules.Core.Mapping
{
    public class HtmlMetaModelBuilder : IEntityModelBuilder
    {
        public void BuildEntityModel(ref EntityModel entityModel, EntityModelData entityModelData, Type baseModelType, Localization localization)
        {
            using (new Tracer(entityModel, entityModelData, baseModelType, localization))
            {
                if (entityModel == null)
                {
                    throw new DxaException($"The {GetType().Name} must be configured after the DefaultModelBuilder.");
                }

                // Only interested in MediaDistribution entities
                if (entityModel is MediaDistribution ecl)
                {
                    if (entityModelData.Metadata != null && (entityModelData.Metadata.ContainsKey("html-title") || entityModelData.Metadata.ContainsKey("html-innerText")))
                    {
                        if (entityModelData.Metadata.ContainsKey("html-title"))
                            ecl.HtmlTitle = entityModelData.Metadata["html-title"].ToString();

                        if (entityModelData.Metadata.ContainsKey("html-innerText"))
                            ecl.HtmlInnerText = entityModelData.Metadata["html-innerText"].ToString();
                    }
                }
            }
        }
    }
}

In the web.config Make sure to add this HtmlMetaModelBuilder to modelBuilderPipeline

<modelBuilderPipeline>
    <add type="Sdl.Web.Tridion.Mapping.DefaultModelBuilder, Sdl.Web.Tridion" />
    <add type="Sdl.Web.Tridion.Mapping.StronglyTypedTopicBuilder, Sdl.Web.Tridion" />
    <add type="Sdl.Web.Modules.Core.Models.HtmlMetaModelBuilder, Sdl.Web.Modules.Core" />
  </modelBuilderPipeline>

I hope it helps.

2
  • 1
    It seems the required data is actually already present in the DXA R2 JSON, so no need for custom Entity Model Builders. Commented Apr 13, 2023 at 10:07
  • Thank @Velmurugan, this solves the purpose. Commented Apr 14, 2023 at 10:00
3

What you want to do can be done with regular Semantic Mapping; no need for customizations.

Since your property names are different than the metadata field names in CM, you will need to put SemanticProperty annotations/attributes on those properties. Furthermore, you have to ensure that your View Model type has a mapping to the CM Schema, using a SemanticEntity annotation/attribute on the type. Since the CM Schema is a (ECL) Multimedia Schema, your Semantic Entity name should match the title of the Schema, excluding whitespace.

Here's an example of a View Model type which maps to an ECL Schema: https://github.com/RWS/dxa-modules/blob/develop/webapp-net/MediaManager/Models/MediaManagerDistribution.cs

For the Semantic Mapping to work, all metadata fields must be declared in the CM Schema. IIRC, html-title and html-innertext are pseudo-fields reflecting the original XHTML element's XML attributes and content. In order to be able to use those in Semantic Mapping, you will have to add fields with the same (XML) names to the CM Schema.

If for whatever reason the Semantic Mapping doesn't seem to work, set the log level to DEBUG and check the DXA log file; it contains useful diagnostic output that can help understand why the mapping doesn't work.

2
  • I prefer better not to create those dummy fields, as it will confuse the editors
    – Velmurugan
    Commented Apr 13, 2023 at 12:13
  • Hi @Rick, thanks for suggestion, I have tried adding field in StubSchema however for somereason, I am not able to get that in mappings/schemas.json. Commented Apr 14, 2023 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.