Expand my Community achievements bar.

SOLVED

Referencing a content node from within a component

Avatar

Level 2

Hi, all.

We're working on a site that will have some components with HTML fragments that will be re-used across dozens (maybe hundreds) pages. And the requirement is that I edit a fragment once, and this change reflects to all pages that are using it.

I could achieve this by placing a call on my template's jsp file with an absolute path attribute, like call below:

<cq:include path="/content/shared/HTMLTextFooter" resourceType="project-name/components/html-text"/>

But our requirement is a little bit more sophisticated: we should be able to, from the custom component (for which I am asking advice to develop) reference an existing node with content for this component. In other words, I think I should be able to inform the path "/content/shared/HTMLTextFooter" somehow on the edit window.

I know we can create N components with distinct jsp render files, each one pointing to a specific path, but this will lead us to the problem of creating a new component and deploying a package every time a re-usable fragment is identified.

Could you please share your insights/previous experiences regarding the scenario/questions above?

1 Accepted Solution

Avatar

Correct answer by
Level 8

Well perhaps I misunderstanding you design. How are you using your custom component? Do you drag onto a paragraph system on a page, or is it statically included in one of your templates. 

The widget in the reference component that displays the paragraphs (referenceparagraphs) leverages a servlet (the source of which you can read - http://localhost:4502/crx/de/index.jsp#/libs/foundation/src/impl/src/main/java/com/day/cq/wcm/founda...). You could extend the referenceparagraphs ExtJs widget to use a different selector and load the paragraphs differently (not just pulling from paragraph systems). 

The other possibility, if you have a well defined content structure is to just use the pathfield widget. 

  • Let's say for example that your custom component containing the XML fragment is always located at jcr:content/fragment on the pages that contain it. 
  • You use the pathfield widget in your custom reference component.
  • In your custom reference component you fetch the path to the selected page 
  • You do an sling include using the selected page path -  <sling:include path="${properties.path}/jcr:content/fragment.html" />

There are other variations on this - for example if used multiple components to manage the HTML fragment you could have a selector script in your template that handled the include and then you would just reference the selected page plus the selector  so something like  <sling:include path="${properties.path}.customscriptselector.html" />

View solution in original post

5 Replies

Avatar

Level 8

Unless I am misunderstanding your requirement you shouldn't have to do any development at all, the out of the box Reference component should do exactly what you are looking for. See http://dev.day.com/docs/en/cq/current/wcm/default_components/editmode.html#Reference for the documentation - you can play with it in the Geometrixx demo site as well. 

Avatar

Level 2

Hi, Orotas.

I think you got it, and I already did a try with the reference component. The problem with it is that I can only reference a paragraph using that, and in my case I need to reference a custom component I built based on the out-of-the-box Text component.

Do you know how can I reference a custom component instead of a paragraph?

Regards,

Rafael

Avatar

Correct answer by
Level 8

Well perhaps I misunderstanding you design. How are you using your custom component? Do you drag onto a paragraph system on a page, or is it statically included in one of your templates. 

The widget in the reference component that displays the paragraphs (referenceparagraphs) leverages a servlet (the source of which you can read - http://localhost:4502/crx/de/index.jsp#/libs/foundation/src/impl/src/main/java/com/day/cq/wcm/founda...). You could extend the referenceparagraphs ExtJs widget to use a different selector and load the paragraphs differently (not just pulling from paragraph systems). 

The other possibility, if you have a well defined content structure is to just use the pathfield widget. 

  • Let's say for example that your custom component containing the XML fragment is always located at jcr:content/fragment on the pages that contain it. 
  • You use the pathfield widget in your custom reference component.
  • In your custom reference component you fetch the path to the selected page 
  • You do an sling include using the selected page path -  <sling:include path="${properties.path}/jcr:content/fragment.html" />

There are other variations on this - for example if used multiple components to manage the HTML fragment you could have a selector script in your template that handled the include and then you would just reference the selected page plus the selector  so something like  <sling:include path="${properties.path}.customscriptselector.html" />

Avatar

Level 2

orotas wrote...

The other possibility, if you have a well defined content structure is to just use the pathfield widget. 

  • Let's say for example that your custom component containing the XML fragment is always located at jcr:content/fragment on the pages that contain it. 
  • You use the pathfield widget in your custom reference component.
  • In your custom reference component you fetch the path to the selected page 
  • You do an sling include using the selected page path -  <sling:include path="${properties.path}/jcr:content/fragment.html" />

 

Hi, Orotas.

It seems that the pathfield approach will fit my requirements. Once I get it working I'll post here the results so someone else may benefit in the future.

Right now I am just curious if is that a common scenario in other AEM/CQ5 projects.

Regards,

Avatar

Level 2

Just to document the steps needed to achieve the effect:

1 - Create your custom component

2 - Add a pathfield widget on the dialog, and name it "contentPath"

3 - On the JSP a code like the one below:

    <c:choose>
        <c:when test="${empty properties.contentPath}">
            <p>[Click "Edit" to select component]</p>
        </c:when>
        <c:otherwise>
            <sling:include path="${properties.contentPath}" />
        </c:otherwise>
    </c:choose>  

Thanks once again, Orotas.