5

My Java DXA application renders dynamic component presentations across the site, similar to 'Teaser' functionality in the Reference implementation of DXA.

One of the Rich text field of DCP contains component (links) which are used on more than one page. So I'm expecting Tridion dynamic linking to resolve links to the 'closets' page using proximity logic(see docs: https://docs.sdl.com/783502/395189/sdl-tridion-sites-9-1/component-link-resolving-logic).

However, links are not resolved as I expected as it is ignoring the page context. Initially, I thought it is a DXA issue similar to the earlier reported one with the static CPs: https://github.com/sdl/dxa-web-application-java/issues/104.

After doing some more investigation, I seems that it is not necessarily a DXA issue but a issue with GraphQL api itself (which is used by DXA ContentProvider).

As GraphQL query which deals with component presentations doesn't accept 'page context/id' at all.

componentPresentation(
    namespaceId: Int!
    publicationId: Int!
    componentId: Int!
    templateId: Int!
    contextData: [InputClaimValue]
)

Whereas CIL API seems to take page id into account as you could invoke ComponentPresentationAssemblerwith it:

ComponentPresentationAssembler cpa = new ComponentPresentationAssembler(publicatinId, pageId);
String result = cpa.getContent("tcm:5-3716", "tcm:5-3718-32");

I am wondering is it a issue with GraphQL api or am I missing something?

Any thoughts?

2
  • Maybe submit a ticket to be sure. If resolving links yourself, the GraphQL component link query includes a parameter for the source page. There's an option for dynamic Component Links, but for when you know the page already. Otherwise, the options to resolve links covers the page use case, but the component presentation might be "missing" a page parameter... maybe.
    – Alvin Reyes
    Jan 29 at 0:21
  • It is indeed calls for a support ticket. It is something missed or intentionally not implemented in API. Jan 29 at 13:12
2

As Alvin correctly points out, there is not currently a componentPresentation root query that takes a page parameter. The nearest would be the items query, which when returning pages, can include the componentPresentations contained within that page, and they will have the associated page context in those results. E.g.

{
    items(filter: {itemTypes: [PAGE], namespaceIds: [1]}) {
        edges {
            node {
                ... on Page {
                    title
                    containerItems {
                        ... on ComponentPresentation {
                            id
                            rawContent(renderContent: true) {
                                content
                            }
                        }
                    }
                }
            }
        }
    }
}

Suggest raising a ticket to correct this feature.

3
  • Thanks. I'm afraid, this would not retrieve Dynamic Component Presentations Jan 29 at 13:25
  • Correct me if this isn't quite right, but I think the items query (or some version of it) should get all the Component Presentations CPs for a Page, regardless if they're dynamic or not. Otherwise, it'd be strange to be missing CPs in a Page that have "dynamic" templates without a way to at least identify them. But this doesn't cover the original question on dynamic linking behavior when getting a CP directly over GraphQL.
    – Alvin Reyes
    Jan 30 at 0:08
  • Well in my use case, the 'items query' (which is added as a static CP on the page) is responsible for collecting metadata for broker query, which is then used by a custom Entity Controller to dynamically retrieve the DCPs and populate the model(list). So my page technically has only one Static Component Presentations. By the way, even for static Component Presentations , GraphQL query for items(or page) returning null for the rawConent (of ComponentPresentation) property. But this is something to investigate on some other day... Jan 30 at 22:33
2

As suggested, Support ticket is indeed required to correct this feature/issue.

A possible workaround could be to resolve component links yourself in your application code. This can done as Alvin mentioned, using separate GraphQL queries (instead of relying on DXA Model Extension/Service).

This would roughly translate to following steps for a DXA-based application.

i) Disable link resolving for Rich text format area in DXA Model Extention/Serive.

Make sure following properties are set in the dxa.properties of your DXA Model Service/Extension

dxa.defaults.rich-text-xmlns-remove = false
dxa.defaults.rich-text-resolve = false

(See SDL docs: Rich-text link handling by the DXA Model Extension or standalone Model Service)

In RTF, the links would be unresolved with link tags.

For example: <a xlink:href="tcm:1-11">link text</a>

ii) Parse and resolve links in RTF using PCA Client (for GraphQL queries)

@Autowired
private ApiClientProvider pcaClientProvider;

String resolvedLink = pcaClientProvider.getClient().resolveDynamicComponentLink(ContentNamespace.Sites, publicationId, pageId, componentId, templateId, true);

1

As mentioned, do follow up with Support. For a little more context here is the GraphQL requests to render links documentation that describes how you can also use the contextData argument to control how links resolve.

If you're managing or resolving the links yourself (e.g. in DXA or other application), the GraphQL requests to resolve links documentation describes options to resolve links to Pages (less likely from a rich text format area), Components, and "dynamic" Component Presentations. These should resolve links to URLs following the same dynamic linking logic as the CIL.

Note you also have control over getting a relative link by setting renderRelativeLink to true or false.

The component link query does include a parameter for the page ID:

{
  componentLink(namespaceId: 1, publicationId: 11, sourcePageId: 92, targetComponentId: 757, excludeComponentTemplateId: 4521) {
    url
    itemId
    type
  }
}

For Dynamic Component Links, we have the following, which includes targetPageId as the ID of the Page that has that particular DCP. But again, this is when managing the link yourself and you have the page already.

{
  dynamicComponentLink(namespaceId: 1, publicationId: 8, targetPageId: 723, targetComponentId: 116, targetTemplateId: 646) {
    url
    itemId
    type
  }
}

These don't directly address your original question about the ComponentPresentation query, so I'll mark this as a community wiki and vote up and recommend Ben's answer. Thanks for raising the behavior.

1
  • Thanks @Alvin for explaining some context around GraphQL requests. Feb 1 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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