Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] set context in expressions #73

Open
cossssmin opened this issue May 1, 2020 · 8 comments
Open

[Feature request] set context in expressions #73

cossssmin opened this issue May 1, 2020 · 8 comments

Comments

@cossssmin
Copy link
Member

cossssmin commented May 1, 2020

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?

@anikethsaha
Copy link
Member

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 💡

@cossssmin
Copy link
Member Author

cossssmin commented May 1, 2020

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
Copy link
Member Author

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.

@anikethsaha
Copy link
Member

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

@Scrum
Copy link
Member

Scrum commented May 6, 2020

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

@cossssmin
Copy link
Member Author

{{ 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.

@Scrum
Copy link
Member

Scrum commented May 6, 2020

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))

@cossssmin
Copy link
Member Author

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants