To render dynamic contents, using broker query to get related components tcmuri. Now using these component tcm-uri's need to get the Component Template Id. Since we need both Component Id and Component Template Id to get the Content and Metadata of the component. Below is the code currently used, but not sure if this is a correct approach. Please advice the best way to achieve this and also welcome to advice on this whole approach of getting the dynamic content. Thanks in Advance.

public void PopulateDynamicList(DynamicList dynamicList, Localization localization)
    {
        using (new Tracer(dynamicList, localization))
        {
            SimpleBrokerQuery simpleBrokerQuery = dynamicList.GetQuery(localization) as SimpleBrokerQuery;
            if (simpleBrokerQuery == null)
            {
                throw new DxaException($"Unexpected result from {dynamicList.GetType().Name}.GetQuery: {dynamicList.GetQuery(localization)}");
            }
            BrokerQuery brokerQuery = new BrokerQuery(simpleBrokerQuery);
            string[] componentUris = brokerQuery.ExecuteQuery().ToArray();
            if (componentUris.Length > 0)
            {
                Type resultType = dynamicList.ResultType;
                ComponentPresentationFactory cpf = new ComponentPresentationFactory(localization.GetCmUri());
                IList cpList = null;
                string componentTemplateId = string.Empty;
                foreach (var compUri in componentUris)
                {
                    cpList = cpf.FindAllComponentPresentations(compUri);
                }
                if (cpList.Count == 1)
                {
                    ComponentPresentation compPresentation = (ComponentPresentation)cpList[0];
                    componentTemplateId = localization.GetCmUri(compPresentation.ComponentTemplateId.ToString());
                }
                dynamicList.QueryResults = componentUris
                    .Select(c => ModelBuilderPipeline.CreateEntityModel(CreateEntityModelData(cpf.GetComponentPresentation(c, componentTemplateId), localization), resultType, localization))
                    .ToList();
            }
            dynamicList.HasMore = brokerQuery.HasMore;
        }
    }
up vote 2 down vote accepted

This logic seems to have some flaws, and does a lot of database operations in order to find a component template.

foreach (var compUri in componentUris)
{
        cpList = cpf.FindAllComponentPresentations(compUri);
}
if (cpList.Count == 1)
{
        ComponentPresentation compPresentation = (ComponentPresentation)cpList[0];
        componentTemplateId = localization.GetCmUri(compPresentation.ComponentTemplateId.ToString());
}

First of all, the cpList will contain all componentpresentations of the last component in the componentUris list, as it will be overwritten by the cpf.FindAllComponentPresentations() function.

Secondly, it might be possible there are more than 1 dcps for the same component presentation, so if (cpList.Count == 1) might be false in some cases. In that case, the componentTemplateId will never be filled, resulting in some errors.

It's way more effective to do something like this:

 string[] componentUris = brokerQuery.ExecuteQuery().ToArray();
 if (componentUris.Any())
 {
    foreach(var uri in componentUris)
    {
       string entityId = "123-456" // this would be a concatenation of the component id and the template id
       var entity = ContentProvider.GetEntityModel(entityId)
       //do some null-checks, add entity to the dynamicList 
    }
 }

The only complexity is indeed : which Template ID to use.

The easiest way to get this is to add a dxa configuration component, and add the ID to this configuration component, so DXA can retrieve it (see https://docs.sdl.com/LiveContent/content/en-US/SDL%20DXA-v10/GUID-216696B0-073F-4188-9584-6112CD15729B for some more explanations on this subject).

  • Wanted to get the Component Template ID dynamically if that is not possible, then will use configuration component to update the ID. Thank you for suggesting the alternate approach. – SRajeshK Oct 29 at 7:35

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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