The locations plugin has a component called location-selector, which is essentially an autocomplete input for geocoding locations. It uses the Discourse autocomplete jQuery plugin, which requires a raw template.
As the raw templating system is not available in the wizard app (e.g. the Discourse.RAW_TEMPLATES constant is not pre-loaded), and I want this component to work across both apps, I’ve assigned the raw template to a constant in the component file and used the various RawHandlebars methods in discourse-common/lib/raw-handlebars, e.g.
This works fine in development (in both normal Discourse and the Wizard app), however it fails in production in the normal Discourse app with
n.default.compile is not a function
(you can see this error currently here if you compose a post and click “Add Location”). Note, importing specific functions (e.g. ‘compile’) doesn’t fix it.
For some reason, discourse-common/lib/raw-handlebars is not loaded or required the same in production as it is in development.
I’m sure there’s an obvious reason why this is not working in production, but I’m just not seeing it at the moment. Any ideas welcome.
Production includes handlebars.runtime.js instead of handlebars.js (see javascripts/template_include.js), which doesn’t include compile, as it is assumed the templates are pre-compiled (see here).
So I could just include handlebars.js in production, but that would be cheating. Rather I’ll need to figure out the best way to precompile raw templates for the wizard app…
We have extended versions of the compilers for some theme-specific functionality, but for basic use you can use Barber::Precompiler for raw templates, and Barber::Ember::Precompiler for ember templates.
It is indeed confusing that the compiler is loaded on the client in dev, but not production . It seems to me that it would be better to keep things the same, but maybe there is some reason for it.
The basic implementation of this in the custom wizard will be
Discourse.unofficial_plugins.each do |plugin|
plugin_name = plugin.metadata.name
if require_plugin_assets = CustomWizard::Field.require_assets[plugin_name]
plugin.each_globbed_asset do |f, is_dir|
if f.include? "raw.hbs"
name = File.basename(f, ".raw.hbs")
compiled = Barber::Precompiler.new().compile(File.read(f))
result << "
(function() {
if ('Wizard' in window) {
Wizard.RAW_TEMPLATES['#{name}'] = requirejs('discourse-common/lib/raw-handlebars').template(#{compiled});
}
})();
"
end
end
end
end
Which just requires a plugin to include ‘templates’ in the assets they add to the wizard asset pipeline, e.g.