Closed RyanZim closed 8 years ago
How about if {{ {{ }} something {{ }} }} outputs {{ something }}? This would be fairly simple, just predefine values for the {{ and }} tokens.
How do other systems handle this? Do they just escape (\
) them? Prob should research what both Khaos and Yeoman are doing.
Khaos uses handlebars.js under the hood. As far as I am aware, you can't directly output a literal (correct me if I'm wrong).
Yeoman uses https://github.com/mde/ejs. This uses erb-style tags. <%%
outputs a literal <%
; %%>
outputs a literal %>
. EJS is very powerful, but a bit too powerful (and verbose) for rock IMO.
I feel like {{
is too verbose. Maybe we should switch to {
? And if you want to actually include it, maybe you'd escape it with \
? I'm not sure. I'm trying to think of cases that may involve React. There may be no easy answer here.
I feel like {{ is too verbose.
You mean switch to {
all around? That would conflict with JSON. :frowning:
Eeks. You're right. Maybe we should get clever on file extension and allow people to use whatever they want via https://github.com/tj/consolidate.js?
Naw, that would make things too complex. Sometimes you have to be opinionated. This is one of those times IMO.
I don't have a problem with {{
, except for the fact that it conflicts with running https://github.com/Qard/onchange in an npm script. Right now, I'm setting tokens
in .rock/rock.json
, but if you make a complex rock and then decide to add something that requires a literal {{
, porting everything could be a pain.
Naw, that would make things too complex. Sometimes you have to be opinionated. This is one of those times IMO.
Definitely agree.
{{
is fine. I'm just not a fan of {{ {{ }}
... not sure \{\{
is any better... maybe slightly. No easy answer here.
I'm just not a fan of
{{ {{ }}
I agree it's a bit verbose, but how often do you use it? Also easier to implement than a backslash-based solution.
Just discovered, you can output }}
, just not {{
.
If you prefer, we could make {{ literal }}
or {{ lit }}
output {{
.
I agree it's a bit verbose, but how often do you use it? Also easier to implement than a backslash-based solution.
Good points.
If you prefer, we could make {{ literal }} or {{ lit }} output {{.
I'm not sure that I follow here?
I'm not sure that I follow here?
Instead of {{ {{ }}
outputting {{
, we could use {{ literal }} or {{ lit }}. Not personally in favor of it, just something I thought of.
I'd say to go with {{ {{ }}
.
Fooling around with this, I don't think this is possible with string.js due to the regex-based matching.
I've been thinking that perhaps we should build a template engine tailored to our needs. Tweezers is sort of a hack IMO.
{{
and }}
for delimiters by default.locals
but also:prompt
function. If a token cannot be found in the locals
object, it calls prompt
.
prompt
could either take a callback or return a promise (or we could allow both).prompt
function to use a CLI prompt library, use prompt()
on the browser-side, make an http request to an API endpoint, or whatever you want. Just somehow get a value!prompt
function, then add the result to the locals
(so repeated tokens don't trigger a re-prompt), and continue parsing the template.locals
object for reuse for another template.This prompting architecture could allow us to implement conditionals and only prompt for tokens used inside the conditional if the conditional passes, etc.
I propose we call this new template engine prompt-tmpl
or similar.
@jprichardson thoughts?
Fooling around with this, I don't think this is possible with string.js due to the regex-based matching.
I have no problem ditching string.js
I've been thinking that perhaps we should build a template engine tailored to our needs. Tweezers is sort of a hack IMO.
Could we use an existing template package that is asynchronous and has a callback for when a variable is undefined? This would allow us to call prompt
then.
I think the rest of what you're proposing looks good.
Could we use an existing template package that is asynchronous and has a callback for when a variable is undefined?
Yeah, we could; I just don't know of any template engine that supports that. If you know of such a template engine, tell me about it!
@jprichardson ping?
I'd strongly recommend modify an existing implementation and bring it into this repo to solve the goals. Creating a new templating engine and creating a new repo with documentation feels a bit like yak shaving if you ask me. What are your thoughts?
I'd strongly recommend modify an existing implementation
What implementation would you recommend?
bring it into this repo
I sorta prefer the "modularize everything" approach, but whatever.
What implementation would you recommend?
Mustache.js maybe? IDK. It's been awhile since I've dug into them.
I sorta prefer the "modularize everything" approach, but whatever.
I do too. I was trying to save the maintenance burden. The reason is because what if you build it up and it's implemented, and then you realize it doesn't quite meet your requirements like you thought it would after a bit of usage?
Regardless, you picked up the baton on this project and as far as I'm concerned, you're the project leader. Therefore you can have full flexibility and latitude to do and choose what you like and I'll support that decision :)
In all probability, I won't get around to this in the near future.
FWIW, I'm not sure if strict mustache-compatible templates are very subtable for this use-case; will think about this more.
@jprichardson We've strayed pretty far from the original topic. Mustache.js doesn't even support directly outputting a literal.
Another idea: keep string.js and use {{ literal }}
to output {{
. The only issue with that is that it could cause collisions with existing templates.
Perhaps we should develop a "reserved" prefix to put in front of all predefined locals (date-year
, file
, etc.). That way, we can predefine a local without breaking backwards compatibility.
How about -date-year
, -file
, -literal
, etc?
How about -date-year, -file, -literal, etc?
I'm good with that. Although, I don't think breaking backwards compatibility at this point is a huge deal because I don't think this is being used much. Your call though.
Yeah, so now is the time to break it in a way that we don't have to break it later. I'll get a PR when I can.
Currently there isn't any way to output a literal
{{
or}}
without changing the delimiter rock-wide.How about if
{{ {{ }} something {{ }} }}
outputs{{ something }}
? This would be fairly simple, just predefine values for the{{
and}}
tokens.Edit: you can output
}}
, but not{{
.This would be a breaking change.
While we're at it, how about limiting valid tokens to
/[a-zA-Z0-9\-_]*/
(letters, numbers,-
, and_
)? That way future functionality could be added without breaking changes.