I'm trying to declare an alias within my YAML file and use it later on within a string. For example, I declare this:
en:
support_email: &support_email "[email protected]"
support_text: "Having a problem? Reach out to <a href="*support_email">*support_email</a>"
and want en.support_text
to evaluate to Having a problem? Reach out to <a href="[email protected]">[email protected]</a>
.
Is there a way to accomplish this? For context, this is within a RoR project.
Thanks for the help!
You can't do this with YAML itself, because the specification specificity excludes this:
7.1. Alias Nodes
Subsequent occurrences of a previously serialized node are presented as alias nodes. The first occurrence of the node must be marked by an anchor to allow subsequent occurrences to be presented as alias nodes.
An alias node is denoted by the “*” indicator. The alias refers to the most recent preceding node having the same anchor. It is an error for an alias node to use an anchor that does not previously occur in the document. It is not an error to specify an anchor that is not used by any alias node.
Note that an alias node must not specify any properties or content, as these were already specified at the first occurrence of the node.
Example 7.1. Alias Nodes
First occurrence: &anchor Foo Second occurrence: *anchor Override anchor: &anchor Bar Reuse anchor: *anchor
You can however use variable interpolation with I18n. Taking your example this would look like:
en:
support_email: '[email protected]'
support_text: 'Having a problem? Reach out to <a href="mailto:%{support_email}">%{support_email}</a>'
Then in your view:
<%= t('support_text', support_email: t('support_email')) %>
Note that the above is not marked as HTML safe, which can be done by adding the _html
suffix changing the last element to html
. Alternatively you can call .html_safe
on the result yourself or input as raw content using <%== ... %>
(instead of <%= ... %>
) or <%= raw ... %>
.
If you want to assign variables more dynamically consider changing the structure of the YAML file.
en:
support:
constants:
message: 'Having a problem?'
phone: '0123456789'
email: '[email protected]'
help_messages:
phone:
text: '%{message} Call us on %{phone}.'
html: '%{message} Call us on %{phone}.'
email:
text: '%{message} Reach out to %{email}.'
html: '%{message} Reach out to <a href="mailto:%{email}">%{email}</a>.'
Now do something like this:
<% vars = t('support.constants') %>
<%= t('support.help_messages.email.html', vars) %>
You could also move this to your own helper:
def t_with_constants(base, path, options = {})
options = t("#{base}.constants").deep_merge(options)
t("#{base}.#{path}", options)
end
Which allows you to use:
<%= t_with_constants('support', 'help_messages.email.html') %>
Note that if you're not in the view or helper you might need to use I18n.t
instead. Which will doesn't have the quality of life improvements that ActionView::Helpers::TranslationHelper#t
offers (like marking strings as HTML safe).
Of course you can give your own twist to this, but I suggest checking out the I18n guide and the documentation under ActionView::Helpers::TranslationHelper#translate
for additional info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With