3

We're trying to load some dynamic content (Component) to one of our pages, for most of the cases fetching the metadata based on tcmId and using WebComponentMetaFactory.getMeta(tcmid) would suffice, but now we need to also retrieve the whole component, to fetch some information that's not included as part of the metadata.

Attempt 1, using WebComponentPresentationFactory and the getComponentPresentation, getComponentPresentationWithHighestPriority, getComponentPresentationWithLowestPriority will always return null (it cannot find the ComponentPresentation for publication: {publicationID} Component: {itemID} and template: {itemID})

Attempt 2, using DD4T's ComponentPresentation is also returning always a null value (it cannot find the ComponentPresentation for publication: {publicationID} Component: {itemID} and template: {itemID})

Attempt 3, using WebTaxonomiFactory will execute the call to the backend, but it is searching to all components of that type, but it will return null anyhow.

What's the proper way to retrieve a component based on the tcm id's obtained after executing a broker query?

EDIT: Got the code from one of our Java developers

So this is the current implementation which works, this is to retrieve the component's metadata

protected List<ComponentMetadata> executeQuery(CorpSimpleBrokerQuery simpleBrokerQuery) throws SerializationException {
   BrokerQuery query = new QueryImpl(this.buildCriteria(simpleBrokerQuery));

   String[] ids = null;
   try {
       ids=query.executeQuery();
   } catch (StorageException var10) {
       LOG.warn("Exception while execution of broker query", var10);
       return Collections.emptyList();
   }

   int idListLength = (ids == null) ? 0 : ids.length;

   WebComponentMetaFactory cmf = new WebComponentMetaFactoryImpl(simpleBrokerQuery.getPublicationId());

    List<ComponentMetadata> results = new ArrayList();

   for(int i = 0; i < idListLength; i++) {
       ComponentMeta componentMeta = cmf.getMeta(ids[i]);

        //Fetching and parsing components appropiately
    }

Attempt 1 - Using WebComponentPresentationFactory

protected List<ComponentMetadata> executeQuery(CorpSimpleBrokerQuery simpleBrokerQuery) throws SerializationException {
BrokerQuery query = new QueryImpl(this.buildCriteria(simpleBrokerQuery));

String[] ids = null;
try {
    ids=query.executeQuery();
} catch (StorageException var10) {
    LOG.warn("Exception while execution of broker query", var10);
    return Collections.emptyList();
}

int idListLength = (ids == null) ? 0 : ids.length;

WebComponentPresentationFactory wcpf = new WebComponentPresentationFactoryImpl(simpleBrokerQuery.getPublicationId());

for(int i = 0; i < idListLength; i++) {

    //Presentation will be null
    ComponentPresentation presentation = wcpf.getComponentPresentation(ids[i], "tcm:0-0-0");
    Object giveMeSomething = presentation.getContent();
}
}

Attempt 2 - Using DD4T ComponentFactory

@Autowired
ComponentPresentationFactory dd4tComponentPresentationFactory;

protected List<ComponentMetadata> executeQuery(CorpSimpleBrokerQuery simpleBrokerQuery) throws SerializationException {
BrokerQuery query = new QueryImpl(this.buildCriteria(simpleBrokerQuery));

String[] ids = null;
try {
    ids=query.executeQuery();
} catch (StorageException var10) {
    LOG.warn("Exception while execution of broker query", var10);
    return Collections.emptyList();
}

int idListLength = (ids == null) ? 0 : ids.length;

WebComponentPresentationFactory wcpf = new WebComponentPresentationFactoryImpl(simpleBrokerQuery.getPublicationId());

for(int i = 0; i < idListLength; i++) {

    //Presentation will be null
    org.dd4t.contentmodel.ComponentPresentation presentation = dd4tComponentPresentationFactory.getComponentPresentation(ids[i], "tcm:0-0-0");
    Object giveMeSomething = presentation.getComponent();
}
}
5
  • Can you please share your current code? Also, do you wish to get the component as a model or json? If you wish for a model, then getting the presentation out of the broker is just the first step.
    – Atila Sos
    Commented Feb 28, 2018 at 12:57
  • If you cannot find the Component Presentation via a Broker query, then are you actually sure that CP is available in the Broker? It must be published as a Dynamic Component Presentation for a start. Commented Feb 28, 2018 at 13:41
  • Thanks for the hint, Bart. We since we are still running DXA 1.7 we have not yet switched to Dynamic Component Presentations yet, thats one change required for the 2.0 release as far as i understood. Migration to 2.0 will be a step in the near future for sure - but for now we need to finish the launch with 1.7, unfortunately.
    – S. Gabriel
    Commented Feb 28, 2018 at 14:11
  • No DCPs were possible since the beginning of DXA already, the only change DXA 2.0 brings there is the fact that a DCP will be loaded at request time and doesn't need to be published along with the page anymore (dynamic resolving of DCPs so to speak). I think this is a common misconception of DXA 2.0, it doesn't just work with DCPs, nor does it introduce them, it enhances working with DCPs. Commented Feb 28, 2018 at 14:20
  • Commented with the java code
    – S. Gabriel
    Commented Feb 28, 2018 at 14:49

2 Answers 2

3

Take a look at the ContentProvider.populateDynamicList method, this is how DXA does it for the out of the box query on the homepage.

This is using the DynamicList class which contains a few basic methods for Broker queries. If you need to do a more advanced query, you should implement a similar class. The idea behind this is to wrap around the Tridion Content Delivery API, and give the web application developers a more simple API to deal with.

Keep in mind, we are talking Dynamic Component Presentations here, so you need to have a Component with a Schema linked to a Dynamic Component Template, so that it can be published as a Dynamic Component Presentation.

2

Based on the suggestions from Bart's answer and having Dynamic Component Presentations, take a similar approach to the one on ContentProvider.populateDynamicList.

This is the approach I take to get the Components Dynamically.

@Autowired
private ModelBuilderPipeline modelBuilderPipeline;

@Autowired
private ComponentPresentationFactory cpf;

protected List<MyEntity> executeComponentQuery(SimpleBrokerQuery simpleBrokerQuery, Localization localization) throws ContentProviderException {

    BrokerQuery query = new QueryImpl(this.buildCriteria(simpleBrokerQuery));

    //Execute Entity Query not just Query
    Item[] items = null;
    items = query.executeEntityQuery();

    /*
    Get the content with WebComponentPresentationFactory and from there
    build the needed TCMUris to get the componentpresentation with DD4t
    and finally fetch entity with modelBuilderPipeline.createEntityModel
    */
    WebComponentPresentationFactory wpf = new WebComponentPresentationFactoryImpl(simpleBrokerQuery.getPublicationId());


    for(Item item : items) {
        ComponentPresentation compoPresentation = wpf.getComponentPresentationWithHighestPriority(item.getId());

        String componentUri = TcmUtils.buildTcmUri(compoPresentation.getPublicationId(), compoPresentation.getComponentId());
        String templateUri = TcmUtils.buildTemplateTcmUri(String.valueOf(compoPresentation.getPublicationId()), String.valueOf(compoPresentation.getComponentTemplateId()));

        org.dd4t.contentmodel.ComponentPresentation componentPresentation = null;
        componentPresentation = this.cpf.getComponentPresentation(componentUri, templateUri);

        usedComponents.add(this.modelBuilderPipeline.createEntityModel(componentPresentation, localization));
    }

    return usedComponents;
}

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.