adobe / htlengine

An HTL (Sightly) Interpreter/Compiler for Node.js
Apache License 2.0
47 stars 20 forks source link

data-sly-use with variable #99

Closed struct78 closed 4 years ago

struct78 commented 4 years ago

I am writing a HTL template that receives a data object with information about the page, and a component to include.

data passed to compiler:

{
  component: {
    path: 'src/components/button/button.htl',
    data: {
      text: 'This is a button'
    }
  },
  page: {
    title: 'This is the title'
  }
}

button.htl

<template data-sly-template.data="${@ data}">
    <button>${data.text}</button>
</template>

template.htl

<!DOCTYPE html>
<html lang="en">
  <title>${page.title}</title>
  <body>
      <h1>${page.title}</h1>
     <!-- this fails -->
      <div data-sly-use.lib="${component.path @ data=component.data}"/>      

      <!-- this also fails -->
      <div data-sly-use.lib="${component.path}" data-sly-call="${lib.data @ data=component.data}"/>

      <!-- this works --> 
      <div data-sly-use.lib="src/components/button/button.htl" data-sly-call="${lib.data @ data=component.data}"/>
  </body>
</html>

When I try to use a dynamic value, I get this error:

<template data-sly-template.data="${@ data}">
^

SyntaxError: Unexpected token '<'
    at Module._compile (internal/modules/cjs/loader.js:892:18)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Module.require (internal/modules/cjs/loader.js:849:19)
    at require (internal/modules/cjs/helpers.js:74:18)

    at Runtime.use (/Users/david/Dev/7-eleven/aem-frontend/frontend/node_modules/@adobe/htlengine/src/runtime/Runtime.js:110:17)
    at /Users/david/Dev/7-eleven/aem-frontend/frontend/build/output.js:64:25
    at Generator.next (<anonymous>)
    at onFulfilled (/Users/david/Dev/7-eleven/aem-frontend/frontend/node_modules/co/index.js:65:19)

So the path to the component is correct.

When I use a static value, I get this.

<!DOCTYPE html>
<html lang="en">
  <title>This is the title</title>
  <body>
      <h1>This is the title</h1>
      <div>src/components/button/button.htl</div>
    <button>This is a button</button>

  </body>
</html>

Is this supported? If not, is there another way I can include a HTL file and pass data to it without using use?

tripodsan commented 4 years ago

I think this should work. if not, this is a bug.

struct78 commented 4 years ago

I think this should work. if not, this is a bug.

Do you need anything from me to be able to flag it as a bug and get it fixed?

tripodsan commented 4 years ago

Do you need anything from me to be able to flag it as a bug and get it fixed?

I'll look into it this or next week. Pull requests welcome, of course :-)

tripodsan commented 4 years ago

Currently we only support static external templates, Since we can't compile them at runtime. Also, there is no way to pre-compile them, other than reference them statically.

but with your static example, it works for me. but I don't see this:

<div>src/components/button/button.htl</div>

if you really want dynamic rendering of components based on a variable, you can create some sort of template library: data

{
  component: {
    path: 'template_spec/button.htl',
    name: 'button',
    data: {
      text: 'This is a button',
    },
  },
  page: {
    title: 'This is the title',
  },
}

button.htl

<template data-sly-template.button="${@ data}">
    <button>${data.text}</button>
</template>

heading.htl

<template data-sly-template.heading="${@ data}">
    <h1>${data.text}</h1>
</template>

library.htl

<sly data-sly-use.comps="./button.htl"/>
<sly data-sly-use.comps="./heading.htl"/>
<template data-sly-template.lib="${@ name, data}">
    <sly data-sly-test="${name == 'button'}" data-sly-call="${lib.comps.button @ data=data}" />
    <sly data-sly-test="${name == 'heading'}" data-sly-call="${lib.comps.heading @ data=data}" />
</template>

template

<sly data-sly-use.lib="./library.htl"/>
<h1>${page.title}</h1>
<!-- here comes the heading -->
<div data-sly-call="${lib.lib @ name='heading', data=component.data}"></div>
<!-- here comes the button -->
<div data-sly-call="${lib.lib @ name=component.name, data=component.data}"></div>

output

<h1>This is the title</h1>
<!-- here comes the heading -->
<div>
    <h1>This is a button</h1>
</div>
<!-- here comes the button -->
<div>
    <button>This is a button</button>
</div>