Showing posts with label language. Show all posts
Showing posts with label language. Show all posts

Friday, January 11, 2019

Translating Text in Sitecore using Microsoft Cognitive Services and PowerShell


Microsoft Cognitive Services is an impressive set of powerful, easy to integrate APIs for developers. With AI at its core, Cognitive Services strives to solve business problems using Vision, Speech, Knowledge, Search, and Language service offerings.  Recently announced, it's now easier than ever to start using Cognitive Services with a simplified key mechanism.

Creating a Cognitive Service in Azure itself is dead simple. It take less than 5 minutes to spin up a Cognitive Service resource and you're ready to develop. The above video will help get you started.☝

So, what can we do with these services in Sitecore?

Cognitive Services Is Not That New

We've seen folks across the Sitecore community utilising this technology since its inception in 2016 - specifically the Computer Vision API. From bulk image alt tagging using Computer Vision and PowerShell and automatic image alt tag generation module, to a fully integrated Cognitive Services module from the infamous Mark Stiles.

These are really great adaptations of these APIs, but I wanted to explore these services myself.

Translator Text API

The Translator Text API is easy to integrate in your applications, websites, tools, and solutions. It allows you to add multi-language user experiences in more than 60 languages, and can be used on any hardware platform with any operating system for text-to-text language translation.
The Translator Text API is part of the Azure Cognitive Services API collection of machine learning and AI algorithms in the cloud, and is readily consumable in your development projects.
What is Translator Text API?

Being completely obsessed with PowerShell, I figured I'd give it a go.  For my demo, I want to allow content authors to right-click on a Sitecore item, select a Translate Text Fields PowerShell script, configure some option in a dialog and click Continue.



The script should create a new language version in the target language selected and translate all text fields selected.

Pricing

Before starting, it should be noted that the Free tier for translations is 2 million characters per month. 
Since we're keeping this integration simple, it's not likely we'll hit the limit.



Let's Script It

Building the dialog is pretty straightforward. Get the context item, grab the applicable languages and fields (Single-Line and Multi-Line only for simplicity and API restriction avoidance), and set the dialog options:

We'll need a function that we can call to process the item after obtaining the selections from the dialog.  We expect to call it like this:

Translate-Item -TargetItem $item -FromLang $selectedFromLanguage -ToLang $selectedToLanguage -FieldsList $fieldSelectionArray

The function should issue an authentication token from the Cognitive Service, generate a new language version for the item in the target language, and call another function to translate the original field value to the target language:

The Issue-CognitiveApiToken in the above function issues the authentication token we need to send with our request to the translation API.

We can send a request to the translation API with the issued token in a new function that will be responsible for processing the actual translation:

Putting It All Together

Now that we've got commands to interact with the Translation API, we can build out the contextual PowerShell script to provide some options for our content author.

Adding this script to one of the Context Menu (PowerShell Script Library) folders (eg. /sitecore/system/Modules/PowerShell/Script Library/SPE/Core/Platform/Content Editor/Context Menu) will allow the script to be executed contextually.


Final Result


I can see this being a good use-case for Dictionary items specifically as there are some restrictions for content length size that the API will reject.  However, this is simply a demo of what is possible here (definitely not production-ready 🤪).



Feel free to take and use any part of the script here and build something cool!

Monday, February 6, 2017

Experience Editor Language Flags in Sitecore 8

After upgrading to Sitecore 8, you may notice that the Experience Editor (formally Page Editor) no longer displays flag icons when selecting a language from the Experience Ribbon tab.
For language-heavy sites where multiple language names may be present – this change makes it difficult for Content Authors to distinguish between en-EN, en-US, en-GB, and en-AU, and all other region-based languages while in this mode.

Sitecore 7


Sitecore 8

The absence of the flag icons in Sitecore 8 is reportedly by-design in several areas due to the frequency in changes of flags. Sitecore has opted out of showing any flags to avoid the maintenance involved in keeping the list updated.

Goal

We want the flag indicators back!
But also, the related ISO code.

Our goal is to ensure:
  1. The language flag icon for the Change Language button in the Ribbon is swapped correctly.
  2. The language flag icons are displayed to the left of the Language name.
  3. The language code Iso label is displayed.


To override the default Sitecore request code, we need to determine which files are related to the original feature.
In this particular scenario, we know we’re dealing with the Experience Editor and the Languages chunk in the ribbon.
Inspecting the button element reveals a corresponding request name:
  • data-sc-iconlabelrequest="ExperienceEditor.Language.IconLabel"
  • data-sc-retrievelistitemsrequest="ExperienceEditor.Language.GetLanguageItems"
  • data-sc-require="/-/speak/v1/ribbon/LargeDropDownButton.js
InspectOrginal.png
A quick config search also reveals that the Sitecore.ExperienceEditor.Speak.Requests.config file contains the definition for this (and other related) request(s).
To reach our end result, we’ll need to override the following lines:
SitecoreRequestsConfigDefault.png
These files are related to this enhancement:
  1. \App_Config\Include\Sitecore.ExperienceEditor.Speak.Requests.config
  2. \sitecore\shell\client\Sitecore\Speak\Ribbon\Controls\LargeDropDownButton\LargeDropDownButton.js

Config

To override the language requests, I created a custom config file which should be placed into the App_Config/Include/ folder.

Note that the name of the config file should be prefaced with a ‘z’ so the config can properly patch after the original requests config is rendered: zGetLanguagesExperienceEditor.config
I used “patch:instead” to replace the two requests:

<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
   <sitecore>
      <sitecore.experienceeditor.speak.requests>
         <!-- ExperienceEditor.Language.IconLabel Overrides -->
         <request patch:instead="request[@type='Sitecore.ExperienceEditor.Speak.Ribbon.Requests.ChangeLanguage.LanguageIconLabelRequest, Sitecore.ExperienceEditor.Speak.Ribbon']" name="ExperienceEditor.Language.IconLabel" type="ExperienceLanguageFlags.SitecoreExtensions.ExperienceEditor.LanguageIconLabelRequestCustom, ExperienceLanguageFlags" />
         <!-- ExperienceEditor.Language.GetLanguageItems Overrides -->
         <request patch:instead="request[@type='Sitecore.ExperienceEditor.Speak.Ribbon.Requests.ChangeLanguage.GetLanguages, Sitecore.ExperienceEditor.Speak.Ribbon']" name="ExperienceEditor.Language.GetLanguageItems" type="ExperienceLanguageFlags.SitecoreExtensions.ExperienceEditor.GetLanguagesCustom, ExperienceLanguageFlags" />
      </sitecore.experienceeditor.speak.requests>
   </sitecore>
</configuration>

Code

After obtaining the correct name and type, we can utilize a reflection software to grab copies of the GetLanguages and LanguageIconLabelRequest code within the Sitecore.ExperienceEditor.Speak.Ribbon.dll.
I created a new class in a location within our solution, gave it a relevant name, inherited from the original classes, and copied the code structure from the reflection in order to customize it.
  1. GetLanguagesCustom.cs
  2. LanguageIconLabelRequestCustom.cs

Requests.ChangeLanguage.GetLanguages

When you click on the button to /-/speak/request/v1/expeditor/ExperienceEditor.Language.GetLanguageItems and builds out the following JSON response:
FiddlerGetLanguageItemsDefault.png
This response already contains a path to a flag image file - ‘IconPath’ - however, there is no label available for us to utilize on the front-end.
We need to add a new variable for the language code label:


Within my custom GetChildItems() method used to provide the list of Languages in JSON format, I added the LanguageCode variable which attempts to get and set the “Regional Iso Code” (or “Iso” if not available) field from the language item in Sitecore.
GetLanguagesClickDebug.png


The request now includes the LanguageCode field and value:
FiddlerGetLanguageItemsAltered.png


Requests.ChangeLanguage.LanguageIconLabelRequest

I noticed that the flag icon does not change according to the selected language by default.
In the screenshot below, I’ve selected French and while the URL reflects the language change, the flag remains set to the original US icon.
FrenchWithUSFlag.png



Overriding the Requests.ChangeLanguage.LanguageIconLabelRequest request will allow us to provide the correct language data (Icon and Label) for the current item request:
IconLabelLoadDebug.png




Presentation

The location of the inner Sitecore files responsible for this and made a custom modification to display the flags:
\sitecore\shell\client\Sitecore\Speak\Ribbon\Controls\LargeDropDownButton\LargeDropDownButton.js
This change is specific to the Experience Editor and does not extend to the Content Editor.
  1. Force the showIcon variable to 1 (true).  This variable is used when generating the popup HTML.
JS-forceShowIcon.png

2) Create a new variable for the LanguageCode variable now available from the Requests.ChangeLanguage.GetLanguages request and JSON response:
JS-AddLanguageCode.png

3) Generate HTML elements (icon image, span element to house LanguageCode) and append them into the popup container.
JS-createElements.png




Final Result

Our final result will now display the flag icon, language name, and language Iso code value:
FinalResult.png
You can find the source code used in this post on GitHub or download and install the package.
* Please note that this has only been confirmed using Sitecore 8.0 Update-1.

Let me know what you think of this solution and feel free to leave comments or suggestions!