What is the right way to get Page object via Sling Model annotation

3.6k views Asked by At

I have a property with the path to required page in a content file

...
<some_block
    ...
    sling:resourceType="some_path_to_some_component"
    somePage="some_path_to_page"
    .../>
...

suitable HTL component some-component.html

<div data-sly-use.some_model="org.example.SomeModel">
    ...    
</div>

and model class SomeModel.java

package org.example;
...
import com.day.cq.wcm.api.Page;
...

@Model(adaptables = { SlingHttpServletRequest.class, Resource.class },
    defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED)
public class RelatedContentBlock {

    @ValueMapValue
    private Page somePage;

    ...
}

I easily can get the required Page object using @Inject and @Via annotations, but why can't I grab it with the @ValueMapValue annotation? I tried to use all the possible variants including via attribute and so on. And yes, I can get it from the pageManager, but what's wrong with @ValueMapValue?

Thanks in advance!

1

There are 1 answers

0
Jens On BEST ANSWER

The documentation that you linked of the @ValueMapValue annotation has the answer you are looking for:

Annotation to be used on either methods, fields or constructor parameter to let Sling Models inject a value from the ValueMap of the current resource.

The important part is:

inject a value from the ValueMap

A Page is not a ValueMap. Therefore, this annotation can not be used to inject a page.

This annotation is mainly used to inject page properties. Because page properties (or resource properties for that matter) are stored in a ValueMap. That is why you can use the @ValueMapValue annotation to inject the jcr:title of a page:

@ValueMapValue(name = "jcr:title")
private String title;

This is equivalent to (pseudo code):

final ValueMap pageProperites = Page.getProperties();
final String title = pageProperties.get("jcr:title", "" /* default */);