rocktemplates / rock

Generate file structures or project skeletons from predefined templates.
MIT License
14 stars 1 forks source link

Literals #24

Closed RyanZim closed 8 years ago

RyanZim commented 8 years ago

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.

jprichardson commented 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.

RyanZim commented 8 years ago

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.

jprichardson commented 8 years ago

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.

RyanZim commented 8 years ago

I feel like {{ is too verbose.

You mean switch to { all around? That would conflict with JSON. :frowning:

jprichardson commented 8 years ago

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?

RyanZim commented 8 years ago

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.

jprichardson commented 8 years ago

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.

RyanZim commented 8 years ago

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.

RyanZim commented 8 years ago

Just discovered, you can output }}, just not {{.

If you prefer, we could make {{ literal }} or {{ lit }} output {{.

jprichardson commented 8 years ago

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?

RyanZim commented 8 years ago

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

RyanZim commented 8 years ago

Fooling around with this, I don't think this is possible with string.js due to the regex-based matching.

Proposal:

I've been thinking that perhaps we should build a template engine tailored to our needs. Tweezers is sort of a hack IMO.

Feature List:

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?

jprichardson commented 8 years ago

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.

RyanZim commented 8 years ago

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!

RyanZim commented 8 years ago

@jprichardson ping?

jprichardson commented 8 years ago

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?

RyanZim commented 8 years ago

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.

jprichardson commented 8 years ago

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

RyanZim commented 8 years ago

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.

RyanZim commented 8 years ago

@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?

jprichardson commented 8 years ago

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.

RyanZim commented 8 years ago

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.