posthtml-expressions icon indicating copy to clipboard operation
posthtml-expressions copied to clipboard

[Feature request] set context in expressions

Open cossssmin opened this issue 5 years ago • 8 comments

Imagine we already had a page.title variable in context, and we could access it through {{ page.title }}. Would be cool if we could define a variable in the context on the fly:

{{ title = page.title }}

<!-- we can now use {{ title }} instead of {{ page.title }} -->
Title is {{ title }}

Currently, that outputs:

undefined
Title is [value of title]

Right now, it does kinda work, but it still outputs undefined where we've set the variable, as I've explained above.

Maybe we could use const to identify that we want to set a variable in context:

{{ const title = page.title }}

Title is {{ title }}

Result:

Title is [value of title]

This would be really useful when you need to access a deeply nested object and you can't use a scope (like inside attributes).

Nunjucks does it with a set keyword, they allow you to define a variable like this:

<p>{{ username }}</p>
{% set username = "Joe" %}
<p>{{ username }}</p>

If username was initially 'James', this would print:

<p>James</p>
<p>Joe</p>

What do you think?

cossssmin avatar May 01 '20 16:05 cossssmin

I think its a useful feature. +1 for this 👍

I do like the set thing more than const cause than users will think it has the complete js runtime and so on.

Will it affect posthtml-modules ?


on a different context (or may be in this)

I was thinking if we can pass an expression to posthtml-modules's modules ? just a rough idea 💡

anikethsaha avatar May 01 '20 16:05 anikethsaha

I'm ok with set, too 👍

posthtml-modules - since it accepts plugins, you can call it and pass posthtml-expressions as a plugin (with initial: true). Already doing it for components in Maizzle and works fine.

cossssmin avatar May 01 '20 16:05 cossssmin

I should mention that you can currently trick it into not outputting undefined by using an HTML comment:

<!--- {{ title = page.title }} -->

Title is {{ title }}

That will output Title is [value of title] just as you'd expect, without undefined above it.

However, I think it's not desirable: doing it inside a comment is not clear for the user whether we want to output this or not.

cossssmin avatar May 01 '20 16:05 cossssmin

I should mention that you can currently trick it into not outputting undefined by using an HTML comment:

Still It would be easy for dev to use set . We can have this feature.. Lets wait for @Scrum for this suggestion

anikethsaha avatar May 01 '20 16:05 anikethsaha

The offer is great, but here's the first thing that came to mind:

  1. I immediately thought that this could grow in patterns and it would have to be controlled in two places (I ran a chill on my back, I could smell the legacy of the projects)))
  2. {{ const title = page.title }} this is similar to aliasing, but we talked about default values in the absence of value?
  3. If we talked about default values, then I thought why not do this when interpolating {{ page?.title ?? 'Scrum' }}

In general, I like the idea, maybe I didn’t have to use it so often, or I didn’t consider its potential

Scrum avatar May 06 '20 07:05 Scrum

{{ page?.title ?? 'Scrum' }} - optional chaining is only available starting with Node 14.

Honestly I don't really care if we can use set, const, or simply {{ foo = bar }}, the last two already work so basically all that's needed is for it to not render undefined in the markup when assigning to a new variable.

cossssmin avatar May 06 '20 08:05 cossssmin

And then I suddenly thought about computed

{
  locals: { page: { title: 'scrum' } },
  computed: {
    get getPageTitle() {
      return this.page && this.page.title ? this.page.title : ''
    }
   }
}
Title is {{ getPageTitle }}

Stop me if I started raving))

Scrum avatar May 06 '20 09:05 Scrum

computed is actually cool and might come in handy! However, this is about being able to do that right in the template - the user might not have access to the plugin's options like that :)

cossssmin avatar May 06 '20 09:05 cossssmin