Living a nomadic lifestyle as I do, I often need to quickly translate words between languages as I travel. I use a couple of different translation apps on my phone, but they involve either typing in a word or phrase, or (somewhat less accurately) viewing or speaking the words. Knowing that PowerApps offers a connection to the Microsoft Translator service, I thought I'd try creating an app that allows you to press a button to learn how to spell and speak a word in any of the supported languages.
My concept is to have a main menu screen where you select the language, and with buttons for categories of words I've found I often need to know quickly. Each category button takes you to a screen containing further buttons for specific words in that category - for example, the Numbers button takes you to a screen with buttons for numbers from 1 to 10. When you press one of the buttons, the word is displayed in your selected language, and you can play an audio clip of the word's pronunciation. In addition, there's a general Translation screen which allows you to type in a word or phrase in any language, and it's translated into the originally selected language in both text and speech.
Following is a walkthrough of creating this app, to demonstrate how to use the various methods supported by the Microsoft Translator connector. Our beginning point is the PowerApps documentation on the Translator connector, which includes some of the following steps, and is a good reference on the Translator methods.
First, you need to add a connection to the Translator service, using your O365 credentials (i.e. the same ones you're using for PowerApps). I like to add any necessary connections before beginning to create an app, though you can also do it within the app creation process.
Create a New blank app using the phone layout.
On the Data Source tab, add the connection you made to Microsoft Translator.
Main Menu - Select a language
The first screen will be the Main Menu screen. Its default name will show up as Screen1, but I like to rename objects in PowerApps as soon as I create them, both for later reference by other controls and just to be able to know where I am when I'm clicking on things. I also like to name objects with a prefix related to the type of object, so I can easily search for them later, and also easily see the type of object being referenced. So I've named this screen scrMainMenu.
At this point, I'd recommend saving the PowerApp, so you can name it before you go much further. I've named mine "Quick Translator", and just used the basic World icon. We'll get more fancy later with our app's buttons.
The first control to add is the Drop Down menu which will allow you to select the language to translate into. On the Insert tab, select Controls, then Drop down, and place it near the top of the screen. Rename the control to something like ddLangChoice. Select the Items property of the drop down control, and enter:
Sort(Filter(MicrosoftTranslator.SpeechLanguages().Name,Not("(" in Name)),Name)Completed Drop Down control
Let's break this down, as we're doing a lot here.
MicrosoftTranslator.Languages() will populate the drop down with all of the available language codes (such as de for German and tlh for Klingon). However, only a subset of these languages is available for Text-to-speech translation, which is something I want my app to do. Using MicrosoftTranslator.SpeechLanguages() instead populates the drop down with only the languages supported by the TextToSpeech method.
Next, I don't think the language codes are very user-friendly - a user wouldn't necessarily know that es-es means Spanish as used in Spain, versus es-mx for Mexican Spanish. So appending .Name after the () will cause the language name to display rather than the code. The problem with this, though, is that the Translate and TextToSpeech methods we're going to use later (to actually translate the given text) only accept a language code as input. To get around this, I added two hidden controls (that is, their Visible property is set to false) for some intermediate steps:
- I added a Gallery control (galFilteredLang) to contain both the Name and Code fields of the language I select in the drop down, so I can reference the Code of the language whose Name was selected. The Items property is set to:
This essentially creates a Gallery containing only one card, because the Languages are filtered such that the Name equals the Selected.Name from the ddLangChoice drop down. I found that this filter didn't work with language Names that included parentheses, such as Spanish (Spain), so that's why I added a Filter to the drop down control:
Filter(MicrosoftTranslator.SpeechLanguages().Name,Not("(" in Name))
This filters out any language Names containing a "(", which means I won't get the nuances between Spanish and Mexican Spanish, but I decided that's alright for my purposes.
- The second hidden control I added was a Text label (txtSelectedLangCode), to get the Code associated with the selected language Name - i.e. the one that's now in the hidden Gallery. The Text property of this control is:
And then it will be the value of txtSelectedLangCode that I'll use on the other screens.
Returning once more to the Drop Down control, the final (outermost) piece of the formula is a Sort by the Name field, because otherwise it's sorted by the Code - so German (de) would come before Dutch (nl), which I don't want.
Completed Main Menu
Next we're going to add "word category" buttons on the Main Menu screen, to take the user to further screens with more buttons. First I created a new blank screen, and named it scrNumbers. All it needs is a name right now - we'll add functionality to it shortly.
I created the category buttons in PowerPoint so I could use rounded-corner rectangles with bevel effects, and easily add colors and text or icons. I then saved them as Pictures (.png files), and used Content > Media to browse and upload them as Images into PowerApps. On the Main Menu screen, I used Insert > Media > Image, and set its Image property to the name of my first image file (NumbersButton). After renaming it to btnNumbers (it's technically not a Button control, but it's being used as one), I sized it the way I wanted it, and then entered the following in the OnSelect property:
The function of the "button" is to Navigate to the Numbers screen. But before doing that, I'm updating a Collection called WordChoice, to contain the text "Numbers". ClearCollect will either create the Collection if it doesn't already exist, or if it does exist, it'll clear whatever was in it, and place the text Numbers into the WordChoice field. This is basically acting as a gobal variable in my app, so my Translate and TextToSpeech controls can always just reference WordChoice, no matter what screen I'm on.
Now that the first button is named, sized, and has an action associated with it, I copied it 6 times to create additional buttons, and just modified the Image property for each one, to reference the word category it represents. Later after creating the other screens, each image's OnSelect property can be changed to navigate to the appropriate page, and with the appropriate WordChoice value.
Here are the categories I'm using for my app, just things I find useful to know:
Numbers (numbers 1-10)
Safety (hospital, doctor, accident, etc)
Basics (hello, good-bye, please, thank you, etc)
Questions (who, what, where, when, how)
Food & Drink (beer, wine, restaurant, etc)
Places (city, town, house, country, etc)
And then a button to translate manually entered words.
Translate and TextToSpeech
Completed Numbers screen
Now, on to the first category screen (scrNumbers), where the translation will happen. Each screen (except the last one) will have two controls plus a button for each word to be translated, and a navigation control.
I've added the navigation control first, in the upper left, so you have a way to get back to the Main Menu screen. It's just an arrow (Insert > Icons > Back arrow), with its OnSelect property set to Navigate(scrMainMenu,ScreenTransition.None)
The first translation control is a Text label (txtTranslated), to contain the translated text based on the button pressed on this screen. Its Text property is set to:
The Translate method requires two inputs: a query, which is the text to translate, and the code of the language to translate to. When the screen appears, the translation of the word Numbers will appear in the Text box, because I had placed the word Numbers into the Collection field WordChoice when the Numbers button was selected on the Main Menu. In this Text property, First(WordChoice).Value is what retrieves the text from the WordChoice Collection. txtSelectedLangCode is the value in that hidden text box on the Main Menu, which contains the language code associated with the language Name selected by the user. I also set the Border property of the Text label to 2, so it has a border. (I've also played with Fill colors on my screens, as you can see.)
Next up is the control to speak the word. Use Insert > Media > Audio to add an Audio control, and set the Media property to:
This turned out to be a bit complex, because there's currently a glitch in the MicrosoftTranslator connection (being worked on by the team, I understand), whereby the TextToSpeech method errors due to a blank query value (I think in the split second where the txtTranslated.Text is being evaluated). So the formula for the Audio control says to only initiate the TextToSpeech method if the txtTranslated.Text is not blank. Aside from that, the TextToSpeech method takes two inputs similarly to the Translate method: the translated text to be spoken, and the language code to speak it in. Pressing the 3 button when the selected language is German
And lastly, I've added more PowerPoint-generated buttons created as on the Main Menu, each of which has its OnSelect property set to:
That is, each button's OnSelect property sets the WordChoice collection to the English word for what the button represents: one, two, three, etc. To do this quickly, I created the first button, named and sized it, and added the above OnSelect action. Then I copied the control twice horizontally, and then copied the row of three controls (by using Ctrl-click on each one to select all three) twice vertically to create a grid (and then copied one button for the number 10). Then I went back and just changed the OnSelect property's WordChoice value for each button.
Now when you press one of the buttons, you should see the text in the Text box at the top change to the translation of that number.
After the Numbers screen was working the way I wanted it to, I duplicated it (using the ... menu in the screen's thumbnail) for each of my word categories, named each screen (e.g. scrSafety, scrFood, etc), and modified the OnSelect property of the Main Menu buttons to navigate to the appropriate screen and set WordChoice to the appropriate word (Safety, Food and Drink, etc). Then on each screen the Image property of each button would need changed to represent various words to be translated, and the OnSelect property changed similarly.
Detect a language
Translating a Spanish phrase to the selected language
There's one more MicrosoftTranslator method I want to demonstrate, so we'll do that on the last screen. I'd like to be able to translate any word or phrase (not just the limited buttons I've created) into the language I've selected on the Main Menu screen. I also want to be able to enter a word or phrase in any language, not just English - so, for example, I could select English on the Main Menu, type in a word on this screen that I see on a menu or sign in whatever country I'm in, and have it detected and translated into English.
So on the Translate screen (a new blank screen), I first (after adding the Back button as before) added a Text Input control (inpTransText) so the user can enter any text. I set the Default property to "Enter text to translate", so the control won't be blank. You can also enter Hint Text which says this, but the text box would still actually be blank, which the Translator methods don't like.
Next I added a Text label with a Border, to display the language of the text the user entered. This is done with the Detect method in the label's Text property:
This formula detects the language of the text you entered, and displays its name - in the screenshot, que pasa was correctly detected as Spanish. I also added a small Text label just above the box, to show the user what's being displayed here.
To create the final two controls, I copied them from one of the other pages, because they're essentially the same: a translated text box, and an Audio control to speak the translated text. The Translation box has as its Text property:
That is, inpTransText from this screen is used as the query, but the rest is the same. The Audio control's Media property is identical to the other screens, other than referring to this screen's TranslatedText control. In the screenshot, you can see that que pasa has been translated into German, and the audio will be the German translation. Pretty nifty.
So I now have a cool little translator app which I do intend to use in my travels. Of course, you don't need to go into this much detail just to see how the MicrosoftTranslator functionality works, but I hope this walkthrough gives you some ideas beyond the PowerApps documentation.