2

can I use variables in another file that I'm including?

in my HTL (file1.html) I have:

<sly data-sly-test.myVar="${properties.myVarFromDialog}"></sly>
<sly data-sly-include="/file2.html"></sly>

Can I use myVar in file2.html ? I'm not getting any value. Is there a way of getting that value from file1.html to use in file2.html

Vlad
  • 10,602
  • 2
  • 36
  • 38
fernando
  • 814
  • 1
  • 9
  • 24

2 Answers2

5

You should use data-sly-template for this. You can define templates in a separate file and can pass in parameters. For an explanation on templates check the following documentation link http://docs.adobe.com/docs/en/aem/6-0/develop/sightly.html#template

iusting
  • 7,850
  • 2
  • 22
  • 30
  • thanks, I know that I can use templates.. but is there anything else? – fernando Jul 26 '17 at 13:02
  • 1
    What else should there be? Imagine having a template called templateFile.html and a consumer rendering script where you use it: ` . You can receive the data inside the called rendering script like – iusting Jul 26 '17 at 13:18
  • It looks that HTL developers decided that something else should be available anyway: [SLING-5812](https://issues.apache.org/jira/browse/SLING-5812). It does not change the fact that for the example from this question passing properties is not required at all! Check my post for more info. – Kamil Ciecierski Jul 31 '17 at 08:55
  • Only for accessing the node properties the global.jsp introduced `properties` variable is the way-to-go, but if the data comes from a Sling Model IMHO it's better to use templates than global variables. – iusting Aug 01 '17 at 06:55
1

Firstly, for the given example it is not necessary to pass the property to variable to make it available in included file2.html - properties is request scope object so that you can access your it and its value ${properties.myVarFromDialog} in file2.html without the need to pass this variable. The previous answer about calling template is then applied to the cases when needed value is not present in global objects. For example, the data might come by calling data-sly-use (from Java WCMUse, Sling Model or JS Use API) and then it has current file scope only.

Secondly, HTL is per acronym "HTML Template Language", which suggests that its main purpose (like for other popular templating languages) is creating templates - patterns that are reusable in the different contexts. Despite the fact that some of the templating languages allow creating or extending global/request scope variables and that is also possible using JSP for a component implementation, generally it is recognized as a bad practice and it might be the reason why it is limited in HTL: Why are global variables evil?

It is not explicitly said anywhere, however, if you take this as a Sling/AEM application development principle, then it would be better if your file2.html would not depend on any global or request scope variables except the ones that are defined in Sling (request, resource, properties and so on).

Finally, as we can see that Sling is not fully following the rule of not having global objects or variables (and cannot do that as implementation would be then quite tricky), in some of the cases it might be worth to take use of one of these objects, request, and set custom attribute to it by using Use API. In the cases that the data needs to be passed and templating would be overkill, it is possible to implement a simple and generic mechanism for setting request scope variable by writing simple WCMUse class:

package yourpackage;   

public class RequestScopeParameter extends WCMUse {

    String paramName;

    @Override
    public void activate() throws Exception {  
        paramName = get("name", String.class);
        final Object paramValue = get("value", Object.class);
        if (paramName != null && paramValue != null) {
            getRequest().setAttribute(paramName, paramValue);
        }
    }

    public String getValue() {
        return paramName != null ? getRequest().getAttribute(paramName) : "";
    } 

}

Then for a setting value, you can do:

<sly data-sly-use="${'yourpackage.RequestScopeParameter' @ name='myVar', value=myVarValue}" />

For getting value in another file:

<sly data-sly-use.param="${'yourpackage.RequestScopeParameter' @ name='myVar'}" />
${param.value}

You can also find a similar solution with JS Use API: AEM 6.0: Additional parameters when using data-sly-resource?

Most importantly, please note that it is not worth to overuse that solution as global variables comes with the danger that they will be accessible in the context where it should never occur or accessed by mistake. In most of the cases, the better solution is creating logic-less templates or splitting logic, by creating separate WCMUse classes, Sling Models, USe API JS scripts for each of included HTL file.

EDIT:

It is worth to mention that there were also some steps made to allow passing parameters with data-sly-include and data-sly-resource so that the solution below might also work for you depending on your AEM Sightly compiler version:

<sly data-sly-include="${'script.html' @ requestAttributes=helper.attributesMap}"/>

https://issues.apache.org/jira/browse/SLING-5812