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] : Filters #60

Open
cossssmin opened this issue Mar 12, 2020 · 16 comments
Open

[Feature Request] : Filters #60

cossssmin opened this issue Mar 12, 2020 · 16 comments
Labels

Comments

@cossssmin
Copy link
Member

Would be awesome if posthtml-expressions offered support for filters, like Nunjucks does.

So you could do stuff like:

locals: { greeting: 'hello there' }
<p>
  {{ greeting | capitalize }}
</p>
<p>
  Hello there
</p>

...or:

<div>{{ [1,2,3] | first }}</div>
<div>1</div>
@anikethsaha
Copy link
Member

I am +1 for this.
Just a question, does any other template lang provides similar features ?

@cossssmin
Copy link
Member Author

It would be even better if you could register your own filters.

So the plugin would come with built-in fitlters, but you could pass in a filters option:

require('posthtml-expressions')({
  filters: {
    upper: (str) => str.toUpperCase(),
    trim:  (str) => str.trim(),
    join: (array, separator) => array.join(separator)
  }
})

@cossssmin
Copy link
Member Author

I am +1 for this.
Just a question, does any other template lang provides similar features ?

Besides Nunjucks and Jinja (which the former is inspired from), Liquid also has this. There might be others that I don't know of...

@anikethsaha
Copy link
Member

Seems like a good feature to add !

@anikethsaha anikethsaha changed the title Filters [Feature Request] : Filters Mar 12, 2020
@Scrum Scrum added the chore label Mar 13, 2020
@Scrum
Copy link
Member

Scrum commented Mar 23, 2020

@cossssmin I like this idea and approach, there is a true feeling that we are creating our own Jinja or Django template

@cossssmin
Copy link
Member Author

Glad to hear it! 😊

Now, regarding development, I haven't looked into it, and I have a feeling it'll be pretty complicated (for me, at least) to get it working with that {{ variable | filterName }} syntax. Can you help with that?

For starters maybe we could do a <filter name="filterName"> tag, which you could use like so:

<filter name="uppercase">lorem ipsum</filter>

Result:

LOREM IPSUM

I can totally help with writing the built-in filters that it would include, I guess we could decide on what to port over from Liquid and Nunjucks?

Speaking about built-in filters, these will definitely not cover all needs, so I think the filters option mentioned above would be really, really useful.

@Scrum
Copy link
Member

Scrum commented Mar 23, 2020

<filter name="filterName"> it seems very cumbersome considering that there may be several filters - it will clog HTML

{{ variable | filterName }} - I will make sketches in this direction, but most likely tomorrow))

@cossssmin
Copy link
Member Author

Forgot about multiple filters, so this needs to be taken into account.

For example:

{{ "foo\nbar" | striptags(true) | escape | nl2br }}

I think the <filter name=""> tag might still be useful:

  • allow using just one filter name and execute only that
  • instead of applying on a string, user could use this tag and apply a filter on an entire block of HTML

Thoughts?

@Scrum
Copy link
Member

Scrum commented Mar 23, 2020

Thoughts?

So far vague

simple

<filter name="">string</filter>

nested 1

<filter name=""><filter name="">string</filter></filter>

nested 2

<filter name="">string<filter name="">string</filter></filter>

I think the filter to the line will be better

@anikethsaha @voischev What do you think ?

@cossssmin
Copy link
Member Author

Yep, I get someone could do that, but you wouldn't have to if we have both {{ var | filterName }} and the <filter> tag. You use the inline one on objects/strings, but for something like this you'd still need a tag, I think:

<filter name="capitalize">
  <section>
    <article>
      <h1>article title</h1>
      <p>lorem ipsum dolor sit amet</p>
    </article>
  </section>
</filter>

Result:

<section>
  <article>
    <h1>Article title</h1>
    <p>Lorem ipsum dolor sit amet</p>
  </article>
</section>

I think this is also why Jinja (docs) Nunjucks (docs) have a filter block. This way, you can apply a filter not just to your own markup, but to stuff that you include with posthtml-include or with posthtml-modules :)

@anikethsaha
Copy link
Member

i think , <filter> can have more control over the HTML I guess. (not sure though)

I think we can have PoC for either or both so that we can discuss it with the implementation with just the built-in ones!

@cossssmin
Copy link
Member Author

i think , <filter> can have more control over the HTML I guess. (not sure though)

I think both are useful, as there are situations where you can't use the tag, and vice-versa - remember the @{{ }} + <raw> discussion we had? 🙂

@anikethsaha
Copy link
Member

yes, seems like we need both ! 👍

@anikethsaha
Copy link
Member

let's start with the tag just for the sake of simplicity ? or with the other one !

@Scrum
Copy link
Member

Scrum commented Mar 24, 2020

Ok, let's try with tags,

  1. what will the filter chain look like?
  2. In what order to apply?
  3. Ignoring applied filters?
<filter name="capitalize | striptags(true) | escape | nl2br">
  <h1></h1>
  <filter name="!escape"><p></p></filter> // ignore filter escape ?
</filter>

left to right or right to left?

or

<filter name="capitalize">
  <filter name="striptags(true)">
    <filter name="escape">
      <h1></h1>
    </filter>
    <filter name="!capitalize"> // ignore filter capitalize
      <p></p>
    </filter>
  </filter>
</filter>

top to bottom or bottom to top?

@cossssmin
Copy link
Member Author

My feedback:

  1. If we go for the first one (multiple filters split by |), the second one would also be possible. I think it would be awesome to be able to call multiple filters on a block with a single filter tag, so I'm all for the first approach 👍

  2. I would say in order of appearance. So, apply the first filter in the attribute, then the next, and so on. I'm not saying LTR or RTL, as that might depend on the user's language and some editors support RTL. In order of appearance would also make it top to bottom or outside to inside, when nesting filters - I suppose this would be easier, instead of going up the tree?

  3. Really cool idea, didn't think of that! Would be very useful for opting out of applying some filter. I can imagine a loop block where you have several filters that format content, and you need to do it in an alternating fashion - so instead of doing double the work (applying another filter to undo the previous parent one; might not even be possible), it actually does less work. +1 for this!

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

No branches or pull requests

3 participants