Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Making resourceType property configurable using a variable

Avatar

Level 4

Hi All,

Whenever we create a new template we define some of the properties of template like below. A new page is created using this template on the jcr:content node of that page I would see the 

resourceType property as sling:resourceType="/apps/myapp/components/pages/test"

Now say later if I want to change my page component from test to test1, all my previously created page would be broken. Is there a way rather than storing a exact string I can store some variable constant which I can change any time without affecting my previously created content. Something similar to declaring a constant variable in java class, and using the constant at multiple places and whenever I want to change the value of constant I just upate at one place without impacting the places where it was used. Does JCR or Sling can do something similar to this?

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:description="Test template description"
    jcr:primaryType="cq:Template"
    jcr:title="Test Template"
    ranking="{Long}100">
    <jcr:content
        jcr:primaryType="cq:PageContent"
        sling:resourceType="/apps/myapp/components/pages/test"/>
</jcr:root>

Thanks!

Shehjad

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi,

Ok, I understand. The best solution would be to add enough flexibility into the components, so you don't need to replace them by new ones.  But this requires that you designed components in a way, which allows you to do this. Rewriting the resource types and using a completly new component should only be your last resort. In your example you could store the options somewhere in the site, so you can modify the options individually per site, without modifiying the code at all.
That is your problem.

And coming back to your original question: No, there's no way to send the resource type through another lookup, which the finally resolves to the right component in way, which satiesfies your needs.

kind regards,
Jörg

View solution in original post

8 Replies

Avatar

Employee Advisor

Hi,

Why do you want to change the value of sling:resourceType? And when you want to change the rendering of all templates, you can change this rendering at a single place already.

And no, you cannot introduce another layer of indirection without patching sling.

kind regards,
Jörg

Avatar

Level 9

You might be able to use sling:resourceSuperType as a way to implement indirection.  You create a test component that has no implementation, its implementation comes from what it inherits from its sling:resourceSuperType.

1) create component /apps/myapp/components/pages/test1

 this is an actual test containing the implementation of test1

2) create component /apps/myapp/components/pages/test

 the only thing test has is property sling:resourceSuperType = /apps/myapp/components/pages/test1

3) in test pages, reference /apps/myapp/components/pages/test

4) create  /apps/myapp/components/pages/test2

  this is an actual test containing the implementation of test2

5) in /apps/myapp/components/pages/test

   modify sling:resourceSuperType to be  /apps/myapp/components/pages/test2

  all test pages will automatically pick up test2

Hope this is helpful.

JK

PS: Apologies for the delay in answering - I ran this by an engineer first, but haven't explicitly tried it.

Avatar

Level 4

Hi Hoh,

Thank you for your quick reply, may be the use case I quoted is not the best to describe the problem.

Yes I want to change the rendering of my template from test to test1 (page component), problem is the content which has already been created. 10000 pages which I have already created and published on my production environment have on their jcr:content node property with value /apps/myapp/components/pages/test"  

Rather than been stored as '/apps/myapp/components/pages/test' on each and every page if it was stored as say template1ResourceType (a variable) which again would have reference to actual value /apps/myapp/components/pages/test I could have just went and update the value.

Even though I can write a simple java code to find and change this value from "/apps/myapp/components/pages/test" to "/apps/myapp/components/pages/test1", still if I have had one extra layer of indirection I could have simply changed at one location. I understand sling needs patching to support something like this, can JCR not support some different type of property whose value can be referenced from one single location?

Thanks!

Shehjad

Avatar

Level 4

Hi JK,

Thank you for your solution, I think what you are saying makes sense and would work perfectly fine. Only thing is in order to make our implementation more robust, we are adding extra components which might not be required in most of the cases. smiley

Thanks!

Shehjad

Avatar

Employee Advisor

Hi,

I understand your problem. But why don't you change the component which is located at /apps/myapp/components/pages/test instead of renaming the resource?

kind regards,
Jörg

Avatar

Level 4

Hi,

I completely agree to the solution you are suggesting, but my organisation have multiple websites and all of them are hosted on single code base (but on different servers) and use different design to change the look and feel of the site. On one of the server (or a site), I want my rendering component to point to test1 while on the other server I still want it to point to test. Still it is not a big problem we can solve it, but many times we change our components say I have a drop down in my component {"text": "Option1", value:"op1"} now if I want to change my option value from 'op1' to 'option1' I cannot do that without breaking the existing content.

If jcr did provided a kind of property, value of which can be referenced from a single location, may be we would be able to avoid these kind of problems, I am looking for a solution to a greater problem not just solving the rendering of templates smiley. Thanks for bearing with my confusing questions.

Thanks!

Shehjad 

Avatar

Correct answer by
Employee Advisor

Hi,

Ok, I understand. The best solution would be to add enough flexibility into the components, so you don't need to replace them by new ones.  But this requires that you designed components in a way, which allows you to do this. Rewriting the resource types and using a completly new component should only be your last resort. In your example you could store the options somewhere in the site, so you can modify the options individually per site, without modifiying the code at all.
That is your problem.

And coming back to your original question: No, there's no way to send the resource type through another lookup, which the finally resolves to the right component in way, which satiesfies your needs.

kind regards,
Jörg

Avatar

Employee

You can try leveraging http://adobe-consulting-services.github.io/acs-aem-commons/features/delegating-servlet.html . I feel..if you customize it appropriately, you can validate it for paths and apply per side using config factory