1

Using CustomLabels, we are able to use the {!format($Label.myNamespace.myLabelName, v.myAttribute} in lightning component markup where $Label.myNamespace.myLabelName looks like:

<?xml version="1.0" encoding="UTF-8"?>
<CustomLabels xmlns="http://soap.sforce.com/2006/04/metadata">
  <labels>
    <fullName>myLabelName</fullName>
    <language>en_US</language>
    <protected>true</protected>
    <shortDescription>my label</shortDescription>
    <value>Label text with a parameter {0}</value>
  </labels>
</CustomLabels>

This works well for simple string values.

However, in the case of a link that looks like

Click <a href="http://example.com">here</a>!

how would we pass the anchor tag into the format function, or more generally, how do we handle internationalization (i18n) properly in lightning components with link text? other I18n frameworks outside of Salesforce have allowed passing in component markup as a parameter.

the two requirements would be

  1. changing the custom label for a different translation should not break the link (as long as the parameter {0} is maintained
  2. translators looking at the custom labels should understand that the link parameter {0} can be moved around in the markup to satisfy different grammatical language needs

if anyone has solved this issue already, would greatly appreciate some pointers towards a solution

0

Utilizing details found in generating dyanamic components, I was able to do a very complex implementation that satisfies the above requirements:

I18nLink.cmp

<aura:component>
  <aura:attribute name="customLabelMessage" type="String" />
  <aura:attribute name="customLabelLinkText" type="String" />
  <aura:attribute name="url" type="String" />
  <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
  {!v.body}
</aura:component>

I18nLinkController.js

({
  doInit: function(component, event, helper) {
    helper.doInit(component);
  }
})

I18nLinkHelper.js

({
  doInit: function (component) {
    var componentDefinitions = [];
    var labelToTranslate = component.get('v.customLabelMessage');
    var parameterSyntaxToFind = '{0}';
    var indexOfLink = labelToTranslate.indexOf(parameterSyntaxToFind);
    if (indexOfLink > 0) {
      componentDefinitions.push(['lightning:formattedText', {
        value: labelToTranslate.substring(0, indexOfLink)
      }]);
    }
    componentDefinitions.push(['lightning:formattedUrl', {
      label: component.get('v.customLabelLinkText'),
      value: component.get('v.url')
    }]);
    if (indexOfLink < labelToTranslate.length - parameterSyntaxToFind.length) {
      componentDefinitions.push(['lightning:formattedText', {
        value: labelToTranslate.substring(indexOfLink + parameterSyntaxToFind.length)
      }]);
    }
    $A.createComponents(componentDefinitions, function (components, status, errorMessage) {
      if (status === 'SUCCESS') {
        var parentComponent = component.get('v.body');
        components.forEach(function (dynamicComponent) {
          parentComponent.push(dynamicComponent);
        });
        component.set('v.body', parentComponent);
      } else if (status === 'INCOMPLETE' || status === 'ERROR') {
        // do what you need to do
        // console.error(errorMessage);
      }
    });
  }
})

example usage

<myNamespace:I18nLink
  customLabelMessage="{!$Label.myNamespace.myMessage}"
  customLabelLinkText="{!$Label.myNamespace.myLinkText}"
  url="https://example.com"
/>

CustomLabels.labels-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<CustomLabels xmlns="http://soap.sforce.com/2006/04/metadata">
  <labels>
    <fullName>myMessage</fullName>
    <language>en_US</language>
    <protected>true</protected>
    <shortDescription>message containing a link parameter from myLinkText</shortDescription>
    <value>Click {0}!</value>
  </labels>
  <labels>
    <fullName>myLinkText</fullName>
    <language>en_US</language>
    <protected>true</protected>
    <shortDescription>link text used in myMessage</shortDescription>
    <value>here</value>
  </labels>
</CustomLabels>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.