How to handle interpolations?
bklang opened this issue · 12 comments
I18n#t
allows interpolating strings like:
en:
foo: Hello %{name}
t(:foo, name: "Ben") # => "Hello Ben"
This would be fine for TTS prompts but would be relatively difficult to manage for audio prompts. How should be handle this?
Pinging adhearsion/adhearsion#361
Follow the simple case for basic strings, and defer more complex cases to SSML templating.
@CodeMangler brought up a use-case I had not thought of: using the string interpolation within audio files for constructing their source URL. I think this supports what @benlangfeld said. I will document this in the README:
- Interpolation is available with I18n
- However, Best Practices dictate that you should not use interpolation for variables that contain strings to be read to the user if you are using audio prompts. Instead, use SSML for that, or something like:
play t(:hello, server: "server1"), name
And your YAML like this:
en:
hello:
text: "Hello"
audio: "http://%{server}/hello.wav"
This form allows mixed TTS + recorded audio.
@bklang The variables we had to interpolate were ENV variables. Specifically, S3 bucket for the audio files. We had to support audio file URLs like: "https://%{s3_bucket}.s3.amazonaws.com/file.mp3"
in our I18n yml files, where s3_bucket
is configured in ENV. For this, we use a custom wrapper over I18n that passes the necessary ENV parameters to I18n.t
transparently.
Can adhearsion-i18n
support this? What's the recommended way to handle this?
/cc @benlangfeld
@CodeMangler If you look at the example in my previous comment, it should be pretty straightforward. It would look something like this:
play t(:hello, bucket: ENV['EC2_BUCKET_NAME']), name
And your YAML like this:
en:
hello:
text: "Hello"
audio: "http://%{bucket}.s3.amazonaws.com/hello.wav"
@bklang true. But that got noisy pretty quickly. Every call to I18n.t
needed these variables explicitly passed in, which we didn't like. We ended up having a wrapper around I18n that did this for us.
Though ours was a custom solution, built to solve a specific case, I was hoping for a generic feature similar to it (i.e. transparently passing in a selected list of variables to t
).
All you need to do is define a base call controller for your application and have all your call controllers inherit from it:
class ApplicationCallController < Adhearsion::CallController
def t(key, options)
options.merge! bucket: ENV['EC2_BUCKET_NAME']
super
end
end
class MyController < ApplicationCallController
def run
play t(:hello)
end
end
If you don't like inheritance, this could also be done as a mixin.
Updated previous example to fix typo (MyController
inherits from ApplicationCallController
)
@bklang yep. We have something similar.
So is there still an issue? Or is this solved?
Our solution works (it's similar to defining a method in the base controller), so, it's not really a pressing issue.
The reason I brought this up was because I felt having this feature in the framework, instead of the application code is better. But I don't really have a reason why adhearsion-i18n
should support this. I'm not sure if anyone else would have similar requirements, so, you can consider this solved.
Thanks for your input on this.
I'd prefer to have the adhearsion-i18n implementation not stray too far from the upstream i18n implementation. If it's important to you, perhaps you could raise it as an feature request (support default interpolations) on the i18n library?
I've added notes from our conversation to the README as well. Thanks!