ractivejs / ractive

Next-generation DOM manipulation
http://ractive.js.org
MIT License
5.94k stars 396 forks source link

Question: Do we have a flag to selectively render the Ractive script on the server side? #3426

Closed ceremcem closed 1 year ago

ceremcem commented 1 year ago

We might need some part of our template to be rendered on the server side and the rest on the client side. Do we have such a flag?

For example, we don't actually need for the following options to be rendered on the client side each time:

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
      <script type="text/ractive" id="template">
      {{hello}}
      <label for="time">Pick a time:</label>
      <select id="time">
        {{#each Array.from(Array(24).keys()) as h}}
          {{#each Array.from(Array(2).keys()) as m}}
            {{#with h.toString().padStart(2,'0') + ':' + (m*30).toString().padStart(2,'0') as hour}}
              <option value="{{hour}}">{{hour}}</option>
            {{/with}}
          {{/each}}
        {{/each}}
      </select>
      </script>
  </body>
</html>

We want {{hello}} to be rendered on the client side and the options on the server-side. How can we do this?

evs-chris commented 1 year ago

I would probably approach this with a macro that looks at some global/shared state to determine where it's being rendered. Since it's a macro, it's a good deal lighter than a component, and it stays pretty simple. If your server side is node/node-like, you can cue off the presence of something like process. But if it's not, it's still pretty easy to change up, since the logic lives in exactly one place.

Ractive.partials.on = Ractive.macro(function(ctx, attrs) {
  if (attrs.server && globalThis.process) {
    ctx.setTemplate(ctx.partials.content);
  } else if (attrs.client && !globalThis.process) {
    ctx.setTemplate(ctx.partials.content);
  } else {
    ctx.setTemplate([]);
  }
}, { attributes: ['client', 'server'] });

// var process = {}; // uncomment me to pretend to be a node process
<on server>
  I'm only shown on server<br/>
</on>
<on client>
  I'm only shown on client<br/>
</on>

I don't care where I am
ceremcem commented 1 year ago

That looks pretty and handy. I'll give it a try ASAP. Thank you.

Should we consider adding this into the official documentation as it - I think - is one of the common requests from a template engine?