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

API method for "registered extensions" #228

Open
nyarly opened this issue Jan 24, 2014 · 13 comments
Open

API method for "registered extensions" #228

nyarly opened this issue Jan 24, 2014 · 13 comments
Labels
Milestone

Comments

@nyarly
Copy link

nyarly commented Jan 24, 2014

A tool I've been writing uses Tilt to manage it template handling, but needs to route method calls to it based on file extension. I was using the keys of Tilt::mappings before 2.0, and am looking at Tilt::default_mappings.template_map/lazy_map now.

What I'm hoping for is a stable API for accessing the registered template mappings. I only need the extensions that Tilt expects, but I imagine it might also be useful to know what template types Tilt can handle as well.

@judofyr judofyr modified the milestone: 2.1 Jul 7, 2015
@judofyr
Copy link
Collaborator

judofyr commented Jul 7, 2015

Public methods for already-available-template-classes and attempt-to-load-everything-that's-lazy-loadable will come it Tilt 2.1.

@judofyr
Copy link
Collaborator

judofyr commented Jun 27, 2016

@nyarly do you still need this?

@nyarly
Copy link
Author

nyarly commented Jun 27, 2016

The use case is https://github.com/nyarly/valise/blob/master/lib/valise/adapters/tilt.rb#L81

I'm more than happy to make use of whatever interface is available to provide the functionality - it sounds like "load everything" followed by "iterate available template classes, mapping to their extensions" would do the job. The existing solution I knew was digging into Tilt's guts, which was what motivated the original question.

@judofyr
Copy link
Collaborator

judofyr commented Jun 27, 2016

What's a sensible API?

I was thinking:

  • Tilt::Mapping#registered_templates => { "erb" => Tilt::ErbTemplate, … }
  • Tilt::Mapping#load_lazy_templates

Not sure about the name of the last one.

@nyarly
Copy link
Author

nyarly commented Jun 27, 2016

I'd be fine with that.

By analogy to Rails, maybe Tilt::Mapping#eager_load_templates

@judofyr
Copy link
Collaborator

judofyr commented Jun 27, 2016

I'd accept a pull request for this feature. Otherwise I'll queue it up for later OSS work.

@mojavelinux
Copy link
Contributor

mojavelinux commented Dec 3, 2017

The API that is currently used for this is Tilt.default_mapping#extensions_for. Middleman uses it to determine which extensions to process for a given extension class. Something like:

template_class = Tilt[ext]
all_exts = Tilt.default_mapping.extensions_for(template_class)

The problem with this approach is that for mappings that are loaded lazily, this returns duplicate values. Take the AsciiDoc extensions for example:

require 'tilt'
Tilt.default_mapping.extensions_for(Tilt::AsciidoctorTemplate)
=> ["ad", "adoc", "asciidoc"]
Tilt['adoc']
=> Tilt::AsciidoctorTemplate
Tilt.default_mapping.extensions_for(Tilt::AsciidoctorTemplate)
=> ["adoc", "ad", "adoc", "asciidoc"]

I think the extensions_for method should return a uniq result. I plan to file a PR with this change. See #324.

@jkowens
Copy link

jkowens commented Aug 20, 2019

Would love to see this API added in a 2.1 release as it would be really useful for Sinatra. See sinatra/sinatra#1172.

@jkowens
Copy link

jkowens commented Aug 21, 2019

After further investigation, I think what is needed is a method that returns a Tilt class name (String) for a particular template engine without loading the file. It looks like we can do that with something like this:

Tilt.lazy_map[engine].fetch(0, [])[0]

@judofyr
Copy link
Collaborator

judofyr commented Aug 21, 2019

After further investigation, I think what is needed is a method that returns a Tilt class name (String) for a particular template engine without loading the file.

What's the input and output here? What are you trying to solve? I can imagine multiple different APIs:

  • Give it an extension (e.g. ".adoc") and show what files will be attempted to be required: loading_strategy("adoc") # => [[:load, "tilt/asciidoctor "], [:load, "other-thing"]]
  • Give it a filename, and show what extension it provides: provides("tilt/asciidoctor") => ["adoc"].

@jkowens
Copy link

jkowens commented Aug 21, 2019

Input would be an engine, and output the string name of a template class. Similar to Tilt.template_for but without class loading.

lookup_template_for("erubis") # => "Tilt::ErubisTemplate"

@jeremyevans
Copy link
Contributor

Considering you can already get this via Tilt's public API (#228 (comment)), I think we should close this. However, be aware that just because there is an entry in lazy_map, doesn't mean the entry is usable (#331 (comment)).

@judofyr
Copy link
Collaborator

judofyr commented Aug 4, 2022

Note that the lazy_map is private (from an API breakage point of view):

tilt/lib/tilt.rb

Lines 16 to 19 in 686cafa

# @private
def self.lazy_map
default_mapping.lazy_map
end
. The main reason we expose it is for testing the ordering they are registered. I'd prefer to provide a proper API (through a method) than making users use lazy_map directly.

Input would be an engine, and output the string name of a template class. Similar to Tilt.template_for but without class loading.

lookup_template_for("erubis") # => "Tilt::ErubisTemplate"

However, I'm kinda struggling to see the use case here. This will always return the first entry in the lazy map and you have no idea if that is the actual template class which is going to be used. I'd understand if it returned all possible template classes it would attempt to load, but returning the first one doesn't seem useful.

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

6 participants
@judofyr @jeremyevans @mojavelinux @nyarly @jkowens and others