Calling Javascript from Ruby


(Jens Maier) #1

I would like to call the JavaScript function Discourse.Utilities.getUploadMarkdown from my SMF2 script. I’ve found and adapted the PrettyText module, but ran into a few problems with localization.

In particular, I can’t figure out how to load the proper locale inside the V8 context:

upload = ... #some instance of Upload
ctx = PrettyText.create_new_context
ctx['upload'] = upload
ctx.eval("Discourse.Utilities.getUploadMarkdown(upload);")
# raises V8::Error: Object has no method 'toHumanSize'

ctx.load(Rails.root + "app/assets/javascripts/locales/i18n.js")
ctx.eval("Discourse.Utilities.getUploadMarkdown(upload);")
# => "<a class=\"attachment\" href=\"/uploads/default/29/89e6bafcc13c84a2.txt\">thing.txt</a> (149.2[en.number.human.storage_units.units.kb])"

Any hints? :slight_smile:


(Jens Maier) #2

FWIW, if anyone’s interested, I found a solution:

ctx = PrettyText.create_new_context
PrettyText.decorate_context(ctx)
ctx.load(Rails.root + "app/assets/javascripts/locales/i18n.js")
helper = PrettyText::Helpers.new
ctx['I18n']['t'] = proc {|_,key,opts| helper.t(key, opts) }
ctx.eval(<<-'end')
  var oldI18ntoHumanSize = I18n.toHumanSize;
  I18n.toHumanSize = function(number, options) {
    options = options || {};
    options.format = I18n.t("number.human.storage_units.format");
    return oldI18ntoHumanSize.apply(this, [number, options]);
  };
end
@get_upload_markdown = ctx.eval("Discourse.Utilities.getUploadMarkdown")

#later:
@get_upload_markdown.call(upload)

Basically, loading i18n.js for toHumanSize also replaces I18n.t with the default that doesn’t work outside of a browser.