Open sc0ttj opened 5 years ago
BTW...
I would also ideally like my project to have more filters for arrays, like liquid does.. such as limit
, sort_by
, exclude
, etc..
But aside form not knowing how to make filters work inside iterators, I also don't don't know how to implement filters on the iterators themselves:
For example.. something like this would be very, very useful to me:
{{#ITEMS | sort_by 'age' 'asc' | limit 10}}
Name: {{ITEM.name}}
Age: {{ITEM.age}}
{{/ITEMS}}
^ would show the 10 oldest people.. or whatever...
..Essentially, I guess I'd like to know how to run the array (in this case ITEMS
, an array of hashes) through the filters, before actually running the iterator in mo
..
Obviously I'm not asking for you guys how to implement the filters, but your thoughts or advice on passing the array to them would be greatly appreciated - you're obviously bigger shell experts than me, and it must be do-able.
EDIT: BTW, if anyone cares, I have most of this working fine now - not including custom iterators (see above) - except sort_by
.. I have sort_array [asc|desc]
, so I just need to write some code that goes down into the hashes of the array, if that is what it contains, then re-orders the main array based on hash contents :+1:
Thanks.
EDIT: I've moved this last comment to a new "feature request" issue
It asks for:
I am lost in the amount of detail that was provided. It looks like you implemented pipes (shell terminology - I you call them liquid filters) and that you're asking about how to manipulate the array that's used in the template. The point of mustache templates is that the data is prepared ahead of time and the templates are logic-less, as seen by the first three words on mustache.github.io. When I came initially to the project, I also wanted to blend very simple logic into the templates. There's iteration and conditionals, so those also seem like logic to me. However, the point of mustache is that it's simple and intentionally provides only basic operations.
Ok, 'nuff of that. Let's get to two related problems. I've wanted to also implement arrays and pipes, but continually hit a snag. With the custom functions that are used by mo
, there are two inputs. The first input is the environment variables and the second is stdin for the template fragment, if one was captured. So, when you run a series of piped commands in the shell, you would do something like this:
cat filename | grep -v "exclude_this_keyword" | tr a-z A-Z
With mo
, I would expect the functions to work like that too, but they can also alter the environment. Here's my imaginary template.
{{ myList | sort }}
The part that always stumps me is how I parse the text inside the braces. Right now I assume it's a variable, which I'm sure you have noticed. I'd like to support the piped syntax, but then again I would also want to do something like this:
{{ myList | join " | " | uppercase }}
There should be a way to escape the pipe symbol, but that starts to open a whole can of worms because I'd have to handle quoted strings, escape sequences, and probably start to tokenize everything. And, of course, someone will want to use crazy syntax.
{{ myList | join " }} | {{" | uppercase }}
{{ myList param="one | two | three" }}
{{ functionName --name John\ Doe }}
{{ myList | join '"'\\"'" }}
{{ functionName --param1="{{some_var_or_func}}" }}
That last one is extra tricky because I'd have to build a recursive parser, which means I'd have to rewrite mo
entirely. I have not yet decided that investing in a tokenizer for bash-like syntax would be beneficial, but your request is starting to make me reconsider. Having this would allow me to also offer the possibility for partials, as mentioned in #31.
I hope this ramble gives you more insight into the problem. Let me know your thoughts.
Well, I am satisfied that I have implemented it OK now in my project, including the filters working on custom iterator functions/arrays.
My implementation is not something I would try to put into mo
... Cos it doesn't take into account the "crazy syntax" examples, nor does it do any real error checking, nor does it limit people to using only the custom filters I defined (might do that next).. And I have no tests inlcluded ;)
But if you are interested, here is the PR in my project with the mo
changes I made.
When I was talking about "crazy syntax", I was thinking of times I wanted that same feature in mo
. :-)
Thanks for linking to the PR. I am going to leave this issue open. Maybe I will have an idea, build a tokenizer, or will find another way to solve the same issue.
As an update, the content within braces is now parsed and tokenized.
This doesn't mean I'm even thinking of starting the work to allow pipes. It's an intriguing idea but hasn't appeared to have significant demand over the past few years.
Hi all,
Thanks for making
mo
, first of all.. I'm using it in a shell-based static site generator called mdsh.I'd like some help using
mo
, if that is alright..Specifically, for a PR on my own project, I have done some little hacks to make
mo
support a liquid-like syntax for filters, like this:and a more complex one:
As in
However, whenever I use a custom iterator, as defined in your examples, I am really struggling to make
mo
respect these filters (I.E, evaluate "the var piped to the filter(s)" and return that).In my project, outiside the
mo
script itself, I have the following custom iterator (derived from your demos), which I re-use in various places, by way of resetting and re-defining the ITEMS array it uses before runningmo
:^ that is the iterator in which my custom liquid-style filters don't work - they get ignored if I use something like this:
^ the value of variable
ITEM.name
is not converted to upper case :(...I have a few different custom iterators similar to
{{#ITEMS}}
, and so I would love to make the filters work inside these iterators by making changes inside mymo
script - so that things stay DRY, and I don't need re-code filter support every time I make an iterator.So far, these are the dumb little hacks I did to
mo
itself to make it support the filters stuff:Around line 745, end of main case statement, when processing regular
{{things}}
, I set aliquid_filter
boolean to true if a pipe was detected in the args:And later in the
moShow
function, we do the evaluation, to support filters for variables like{{var}}
:Lastly, I added the following, so calling a function, like
{{some_func}}
, also supprots filters:I don't really understand
mo
s internals.. but these changes seem to be enough to getmo
to evaulate and return the piped filter stuff most of the time, but NOT with{{ITEMS.foo}}
, inside a custom iterator, or with iterators themselves (see my comment below)...I would love for that to be sorted, so that the experience (that "filters work in Mustache templates") is consistent in my project ..
Any advice would be greatly appreciated.