mustache / spec

The Mustache spec.
MIT License
364 stars 71 forks source link

Partials fallback to lookup by filename #56

Closed devinrhode2 closed 10 months ago

devinrhode2 commented 11 years ago

I wish we could have this cemented in the spec, specifically:

When the lookup of a partial named 'sidebar.mustache' fails, lookup would fallback to the file named 'sidebar.mustache'. If rendering is being done on the client, then this simply doesn't occur.

Of course we need to support full file paths like../../layout.mustachebut I think this is trivial for most languages. In PHP the path string is simply placed into a file_get_contents call. However, I'd like to hear the opinions of some implementors on this. When partials reference more partials, there's potential to mixup paths, for example:

/partials/one.mustache:

Here's one.mustache

/partials/two.mustache:

Here's two.mustache
{{> one.mustache}}

/final.mustache:

Here's final.mustache
{{> partials/two.mustache}}

Since references would be relative, implementations need to take care to look for the file relative to the file including it.

groue commented 11 years ago

In GRMustache, one must avoid explicitly writing the file extension in the partial tag. The goal is that a set of given templates and partials can fit in the file system as well as in a dictionary object in memory. Maybe this can help solving your issue, that I do not really understand (what kind of partial lookup are you talking about, for instance ? Does this issue belong here, or does it belong to the PHP Mustache implementation?). Please clarify your point.

devinrhode2 commented 11 years ago

For example in hogan.js, partials need to specifically be loaded in. You don't directly reference a file, with or without the file extension. First you need to read that partial by filename, and render the template with that compiled partial passed in.

The Mu implementation for node allows you to directly reference partials by file path. I don't know about other implementations, but it'd be nice if it was established that partials can be loaded in by file path, and with or without the file extension.

Does this clarify it enough?

The difference is having this 'just work' all the time with all implementations:

{{> partials/sidebar.mustache}}

Or having some inconsistency between implementations.

And when I say 'just work' the partial is read from the file system, there is nothing else to do before rendering.

groue commented 11 years ago

Thanks for your clarification.

My opinion on the subject is the following : since Mustache focuses on inter-language interoperability, a template that contains a tag {{> sidebar }} should work the same, whenever templates and partials and stored in the file system (base.mustache + sidebar.mustache), or stored in memory, addressable by name (base + sidebar). Some implementations would use the file system, some other would use the memory store, but the template contents could be strictly identical.

Hence the omission of the extension in GRMustache, and what I believe is a bug in implementations that require the extension to be explicitely written in the template (Mu, in your example). Those implementations do not pass the interoperability test.

Now, regarding file-system specifities like directory hierarchy: I agree that the specification could specify something here, still for the sake of interoperability, so that {{ > partials/sidebar }} and {(> ../../header }} work the same in all Mustache implementations that provide support for hierarchical partials storages (such as the file system).

My contribution on this issue can be summarized this way :

  1. never ever embed file extensions in templates, since it breaks interoperability.
  2. never ever force users to use specific extension, since some prefer .mustache, others .stache, others .whatever.
  3. let user specify file extensions at the API level, not from the templates. For instance, you can use the same extension as the rendered template (for instance, render("/path/to/base.mustache") would load partials with .mustache extension)

For inspiration, you can check GRMustache documentation on how it loads partials, at the bottom of https://github.com/groue/GRMustache/blob/master/Guides/templates.md. The library also provides support for any kind of template/partial store, hierarchical or not. This is documented at https://github.com/groue/GRMustache/blob/master/Guides/template_repositories.md.

devinrhode2 commented 11 years ago

Re-reading your response, I have to agree the spec should specifically state to NOT use file extensions - because sometimes there aren't any files, and thus no extensions, or mustache is used on a completely different type of file.

Therefore, what file extension to use is up to the implementation.

I suppose this is mostly a non-issue, except for my initial itch - hogan.js, while it doubles for the browser and node, it should at least support taking a file path in the node environment. Going to close this issue and put in a feature request with hogan.

groue commented 11 years ago

I think you should reopen this issue, since we've both agreed on something that is not in the spec, but should be.

groue commented 11 years ago

GRMustache has just shipped with support for templates stored in a hierarchy of directories, allowing both relative and absolute paths to partials.

Regular partial tags contain relative paths: {{> header }}, {{> partials/header }}.

Absolute paths start with a slash: {{> /path/to/partial }}.

Release notes and link to documentation: https://github.com/groue/GRMustache/blob/master/RELEASE_NOTES.md#v540

devinrhode2 commented 11 years ago

wow. Sweet! Love the work you're doing @groue. Means a lot to me.

groue commented 11 years ago

Thank you very much. Your positive feedback is quite encouraging :-)

bobthecow commented 10 years ago

This is an implementation specific issue. It's not defined by the spec, but that doesn't limit an implementation from doing it. In fact, the default configuration for mustache.php already does. Good call on taking it up with hogan :)

jgonggrijp commented 10 months ago

Closing as this does not seem to be a spec issue.