IceFire Studios

IceFire Blog

Tips on using SharePoint in a multilingual environment

Script Files That Download Rather Than Executing

It started with an intermittent problem from a client.  In some cases their users were being prompted to download a JavaScript file that had our product's name somewhere in the file name.

That file was a localization file that SPFx uses.  When you create an SPFx webpart or application customizer, there is a "loc" folder in which you put files that contain the character strings that vary according to language.  You can find more details about SPFx localization here. Each file in that folder will have a name corresponding to the locale, for example "en-us.js" and "fr-fr.js".  These files will then be packaged under a longer name, consisting of

(the name in the project)_en-us_(some long hex string).js

It turns out that this file was the one that was sometimes downloaded. Looking more deeply at why it was being downloaded sometimes when other JavaScript files weren't, it turns out that there was a difference in the http headers that were being sent.


The major difference between the .js file that was sometimes being downloaded and the ones that weren't was that the ones being downloaded had a "content-disposition" header and the the others didn't.  In theory, a content-disposition of "attachment" with a file name means that this file should be downloaded, not sent to whatever is responsible for the MIME type represented in the Content-Type header.  In practice, browsers know that web servers often get the http headers wrong, so they look for other evidence of the intent.  Most of the time they look at the content-type and only download the file if its value is "application/octet-stream".  They apparently also look at the context in which is it being called.  

In the case of the client, the download usually came when the user had just logged out and logged back in again.  Their authentication was not the usual one, so it involved some redirection to and from their on premise identity management.  If the caching of this JavaScript file had expired but other files were in the cache, it could very well be the first file being fetched from the SharePoint Online domain, so no context is available for the browser to take into account.  In that case, it seemed, it respected the incorrect Content-Disposition header. Also, they were not using and did not want to use any CDN to serve these files, unlike most of our other clients with a similar architecture.  Files served by a CDN tend to have the correct http headers.

That behaviour is easily reproduced, by going directly to the appropriate folder of the App Catalog's ClientSideAssets library and clicking on the file name.  That file prompted the user to download it, while other .js files in the same folder did not.

I won't bore you with everything that we tried to figure this out.  As some point we were convinced that this happened to with application customizers but did not happen to webparts.  As it turns out, the problem was with our naming convention.  using the words "modern application customizer" in the name rather than "modern webpart" made a difference.

The difference was the name of the JavaScript file, specifically the length of the name.  The file name was already pretty long, but the difference between the words "webpart" and "application customizer" took it over some magic threshold.  Our naming convention sabotaged the attempt to reproduce the problem with a "hello, world" test.  If looks like a file with a name of 81 characters has the correct http header, but one of 87 has the wrong one.  I'm still not sure what is the exact limit, and whether it is a limit on the file name or the path or the full URL.  None of those lengths seem close to some magic number, but it doesn't matter since shortening the part of the file name that we are responsible for fixes the problem.





How to make SharePoint API calls language-independent

SharePoint's API has gone through several iterations, from the 2010 API, to the 2013 API, and now Graph API.  Throughout, it has struggled with being language-independent, particularly when dealing with lists and libraries.  Everything works fine when the site is in English and the user's language is English, but many things don't work like the examples when the API encounters a different language.  If you are writing software, or even a Power Automate flow that uses the API, you need to be conscious of the fact that that the API may stop working if the user is using a different language, or the site was created in a different language.

Let's use a simple problem to illustrate.  Suppose you want to know whether a user is a site administrator.  That information is kept in a handy hidden list on the site, called (in English) the User Information List.  Let's retrieve that information using the SharePoint 2010 API, the one that starts with "_vti_bin/ListData.svc/".  The REST API call would be:

{Site URL}_vti_bin/ListData.svc/UserInformationList(4)/IsSiteAdmin

Here, I am using a "4" to indicate a specific user's ID on this site.  This query returns a single line of xml with (in my case) the value "true".  Simple, right?

Unfortunately, that only works if the user's current UI language is English.  If it's French, that API call fails.  Instead you have to use this call 

_vti_bin/ListData.svc/ListeDInformationsUtilisateur(4)/EstLAdministrateurDuSite

 

This is because the list name and the column name used by the list webservice are localized by the MUI

In Dutch, it's 

_vti_bin/ListData.svc/LijstMetGebruikersgegevens(4)/IsBeheerderVanDeSite

 

In Hindi, 

_vti_bin/ListData.svc/उपयोगकर्ताजानकारीसूची(4)/साइटव्यवस्थापनहै

 

Don't forget to URLencode those Hindi Devanagari characters! 

_vti_bin/ListData.svc/%E0%A4%89%E0%A4%AA%E0%A4%AF%E0%A5%8B%E0%A4%97%E0%A4%95%E0%A4%B0
%E0%A5%8D%E0%A4%A4%E0%A4%BE%E0%A4%9C%E0%A4%BE%E0%A4%A8%E0%A4%95%E0%A4%BE%E0%A4%B0
%E0%A5%80%E0%A4%B8%E0%A5%82%E0%A4%9A%E0%A5%80(4)/%E0%A4%B8%E0%A4%BE%E0%A4%87%E0%A4%9F
%E0%A4%B5%E0%A5%8D%E0%A4%AF%E0%A4%B5%E0%A4%B8%E0%A5%8D%E0%A4%A5%E0%A4%BE%E0%A4%AA
%E0%A4%A8%E0%A4%B9%E0%A5%88

 (line breaks added for formatting)

All of that means that your code has to be ready with 50 different versions of that API call depending on the language of the end user.

It's a little better when you are using the 2013 API.  You still have to give it the list's title, but it's the list's internal name, not the display title for the current language.  To get the list, the 2013 API call is 

/_api/web/lists/getbytitle('<list title>')

 

Better, right?  Unfortunately, the internal name of this and many other standard lists and libraries still depends on the language in which the site has been created.  When you create a new site, whether classic or modern, the site has a base language.  So if the site was created in English, you can get the information with this call 

_api/web/lists/getByTitle('User Information List')/items(4)/IsSiteAdmin

 

That call will work no matter what the user's current language is.  But getByTitle() is still not language-independent.  Using getByTitle is always a bad idea unless you know that no one is creating sites in other languages, but there aren't a lot of other options.  If your site was created in Hindi, the call has to be 

_api/web/lists/getByTitle('%E0%A4%89%E0%A4%AA%E0%A4%AF%E0%A5%8B%E0%A4%97%E0%A4%95
%E0%A4%B0%E0%A5%8D%E0%A4%A4%E0%A4%BE%20%E0%A4%9C%E0%A4%BE%E0%A4%A8%E0%A4%95%E0%A4%BE
%E0%A4%B0%E0%A5%80%20%E0%A4%B8%E0%A5%82%E0%A4%9A%E0%A5%80')/items(4)/IsSiteAdmin

(line breaks added for formatting) 

It's only a little better than the 2010 API.  The API call depends on the site, not the user, and the "IsSiteAdmin" column is not localized.  Why the internal name of a hidden list, something that only programmers will ever see, is localized is anybody's guess.  So compared to the 2010 API, you're not much better off.  You still need to have 50 different versions of the API call, even though it's based on the site language and not the user language.


How do you make the API call independent of language?  One way is to find the list using another characteristic that is not language-dependent. One such characteristic is the EntityTypeName, essentially the template for the list or library.  There will only be one User Information List per site, and its Entity Type is "UserInfo".  There could be several pages libraries, but there typically is only one, similarly for Site Assets and so forth.  So the trick it to find the list using an OData filter like 

/_api/web/lists?$filter=EntityTypeName%20eq%20%27UserInfo%27

 

and use the result to retrieve the list Id, which is a GUID, and then use that GUID to retrieve the information from the list, for example 

_api/web/lists('0040809f-5e97-4920-9068-0b36e2aa4b16')/items(4)/IsSiteAdmin

 

That's two API calls rather than just one, which is unfortunate if you're trying to cut down on queries, but at least you don't have to code 50 different possibilities.

For this specific list, the User Information List, there is also a second solution.  It's based on the fact that this particular list also has a fixed URL that does not include the list name, at "_catalogs/users/detail.aspx".  We use this trick to retrieve the list by URL, using the less well known GetList method.  On my ”/sites/Hi” Hindi site, the API call could be

_api/web/GetList(@listUrl)/?@listUrl=%27%2Fsites%2FHi%2F_catalogs%2Fusers%2Fdetail.aspx%27&FilterField1=ID&FilterValue1=4

 

Neither of those tricks is completely general for all lists and libraries, but I haven't found one that applies in every case.

How about the Graph API?  The Graph API suffers from the same problems as the 2013 API, but does not support the same solutions to those problems.  So for instance after you retrieve the Site ID, you can use it to retrieve the list by name in the same way as for the 2013 API.  If the site is in English, it would be

https://graph.microsoft.com/v1.0/sites/{Site ID}/lists('User Information List')


If it’s in Hindi, you would have to use

https://graph.microsoft.com/v1.0/sites/{Site ID}/lists('उपयोगकर्ता जानकारी सूची')


or you can use

lists?$filter=displayName eq 'उपयोगकर्ता जानकारी सूची'

 

I have not yet succeeded in getting it to filter by EntityTypeName (Graph API  calls it “list/template”) or by URL, or even to find the isSiteAdmin property.  I have only succeeded in collecting an impressive set of OData filter expressions that aren't supported, so I'm afraid I don't yet have a good solution for the Graph API.  Maybe someone more clever than me will find one.

SharePoint Conferences in October - See You There!


Photo by Samuel Pereira on Unsplash


October is a busy month for SharePoint lovers. While much awaited in person events had to be postponed due to COVID-19, the virtual conference world is taking over, and October seems to be an especially active month.


The PointFire team is getting all geared up for the 10+ conferences we’re sponsoring, and Martin Laplante will be giving quite a few sessions you might want to attend. The good news? A lot of them are free of charge and you can get access to very interesting learning sessions.


We’ve compiled a breakdown of the conferences we’re attending as well as sessions we're giving and linked them to their respective sites so that you can easily look into the details and, if you haven’t done so already, get your tickets.



10 October: CollabDays - Lisbon

Session: Multilingual Features of SharePoint: What's New, What's Missing


17 October: M365 Saturday - Ottawa

Session: The New Multilingual Page Publishing Feature and Beyond

Schedule will be announced here


16,17 October: CollabDays - Barcelona

Session: Multilingual Features of SharePoint: What's New, What's Missing


26 October: CollabSummit Learning Day

This is an especially interesting half-day learning session. Register early as attendance is free or charge and seats are limited.

Session: Making SharePoint Online Multilingual, With PointFire and Without

Session details here



14 November: M365 Chicago

Session: Details to be announced soon!


Other conferences we're sponsoring:


14-15 October:  European SharePoint Conference Online


24 October: CollabDays - Benelux


27 October: CollabSummit Sponsor Day


30 October:  Virtual HOU365 Friday - Houston


We'd be happy to see you there.

Feel free to reach out to our sales team and book an appointment: sales@icefire.ca.


A few new languages

Because of recent changes to the Azure Translator Text API, a few new languages in the Western Iranian language group are being added to PointFire Translator.


Two versions of Kurdish are being introduced, Kurdish (Central), language code "ku", also called Sorani,  and Kurdish (Northern), language code "kmr", also called Kurmanji.

In addition, two languages of Afghanistan are being added.  
Dari (prs) and Pashto (ps).  PointFire Translator had already supported Dari and Persian, and Dari is also supported by PointFire 365 and SharePoint.  However, we had been using the same language code and translation engine for both of them, because they are so similar.  
Now Dari will use "prs" and Persian will use "fa" for Farsi, another name for the same language.

SharePoint 2019 Machine Translation Service is back!

When SharePoint 2019 was first released, its Machine Translation Service did not work.  The service could be installed and was running, but most attempts to use of it would result in the error message "The service application required to complete this request is unavailable. Try this operation again later. If the problem persists, contact your administrator."

The ULS log would have a message of "Unimplemented method" with a stack trace in Microsoft.Office.Web.Conversion.Framework.

Microsoft  has now resolved that error!  If you install the July 2020 or later Cumulative Update for SharePoint 2019 then the service is working again.

The Machine Translation Service is used by two optional features of PointFire 2019: the machine translation of user interface elements and the translation of classic pages and documents in SharePoint libraries.


These functions now work as expected.  The next release of PointFire 2019 will have some performance improvements that were delayed because of the difficulty in testing improvements to a feature that very few could use.

Because of the ongoing problem, all users of PointFire 2019 have been able to get free annual licenses for PointFire Translator, which can translate documents, pages, lists, and UI elements in SharePoint 2019 with higher quality than the free Machine Translation Service (although check out this secret setting).  PointFire Translator can also translate modern pages Excel, PowerPoint, and PDFs, which the Machine Translation Service cannot do, and covers more languages.  This free license program will soon end. If your free PointFire Translator license is expiring, contact us about transitioning to the Machine Translation Service or renewing the license.

How Microsoft Forms Sets the Display Language for Multilingual Forms


Microsoft Forms supports multilingual forms.  How do you create these forms, how do you know what language the form will be in, and what happens when the forms are in a Microsoft Forms web part in SharePoint ?

Creating a form in multiple languages is easy.  You can find detailed instructions on this page Send a form in multiple languages

Note that it must be a form not a quiz.  Quizzes cannot be multilingual.  Create the form in the default language first.  Then click on the three dots at the top right corner of the screen, and select multilingual. You can change the Primary language if it got it wrong, or you can add new languages.


If users are not going to be using a SharePoint webpart to fill it out, you have to be very careful with the choice of languages. Language codes have to be an exact match.  For example you get to choose between "français (France)" and "français (Canada)"  However you have to choose carefully because later on you will need an exact match with the browser language.

Then for each language, hover over the language name to make the pencil and trash can appear, and click on the pencil.


That will let you edit the text in that language, including the title and the questions.


Let's try the form in different languages now.  If your browser's language preference, or one of the list of preferences, matches one of the languages of the form then the form's user interface and content will be in the selected language.  However this must be an exact match.  If the form language is "français (France)", which means language code "fr-FR", and your browser is "français (Canada)" (fr-CA) or even "français" (fr), it WILL NOT MATCH and the form will be in English.  If the form language is "Deutsch", which means  language code "de", and your browser is "Deutsch (Deutschland)" (de-DE), it WILL NOT MATCH and the form will be in English, or in whatever is the Primary language of the form.

You can override the user's language preference by adding the "lang" parameter with a language code to the URL, for example adding "&lang=de" for German.  Again, an exact match is needed.  It will then ignore the user's browser configuration and show the form UI and content in German.  If you set your language preference in your Office 365 user profile, it always ignores that.

When the form is on the user's screen they can always click on the language toggle in the upper right hand corner of the form.  Selecting a language from that dropdown will override the browser language and the URL parameter and show the form UI and content in that selected language.


In SharePoint modern pages, you can add a Microsoft Forms webpart to the page.  In what language will the form display?  If your user profile does not have a language preference set, then it will follow the browser settings, otherwise it will follow the user profile settings, the same thing as what SharePoint's user interface does.  Good news! It does not need to match exactly, "fr" or even "fr-CA" browser setting will match "fr-FR" if that is the MS Forms language.  Bad news! The forms language code must exactly match the SharePoint language code.  So for instance the language code for French in SharePoint is "fr-FR".  There is no way to match "fr-CA" in MS forms.  Even worse news.  MS Forms supports one version of German, apparently with language code "de", while SharePoint supports one version of German, with language code "de-DE".  They don't match, and there is no way to make them match.  It's a bit hit or miss, for some languages both products use the same language code, and for some they don't. For example both support Welsh, and in both cases they happen to use the language code "cy-UK", even though the language code "cy" would have been perfectly standards compliant.

If you put a "&lang=de" in the URL that is provided to the Microsoft Forms webpart, it makes no difference, it ignores the parameter.

When the form is on the user's screen they can always click on the language toggle in the upper right hand corner of the webpart.  Selecting a language from that dropdown will override the browser and the profile and show the form UI and content in that language, without changing the language of the UI of the rest of the SharePoint page.

All of this would be easily fixed if MS Forms were to try a little harder to match the browser language or the SharePoint language.  The best way would be if the exact match doesn't work, try to match the neutral culture ancestor of the languages (in most cases a two-letter language code).  If the neutral culture of the form were to ba matched with the neutral culture of the Browser language for standalone forms, or the thread's current UI culture in the case of SharePoint webparts, then "de" would match "de-DE" and "fr-CA" would match "fr-FR".

If you agree, you can vote for the User Voice idea to that effect.


I Know What I’m Doing, But…

One of my colleagues suggested to me that I should try Collab365’s MicroJobs and then write a review about it.  I subscribe to some Collab365 mailing lists, they have daily summaries of all the important news and blogs, and they organize some great conferences.  It’s one of the few automated emails from outside my company that I read carefully every day, motivated by FOMO.

The newsletters and the site mention MicroJobs all the time and I keep thinking that sounds like a good idea but it’s not for me.  But my colleague insisted I should do it and Fraser Beadle of MicroJobs joined her in gently coaxing me to try it.

I’ve been working in the SharePoint and Office 365 space for over 10 years.  I run a SharePoint product company with all sorts of SharePoint experts working for us, I give talks at conferences, I write blogs, I Know What I’m Doing.  Any issue that comes up I can just search for some blogs and follow the instructions.  I don’t need hand-holding.

And yet when I tried to think of current nagging problems that might be solved in 30 minutes, I could think of several of them.  I couldn’t decide which one to try, so I signed up for two of them, very different types of problems.  In both cases the format was a 30 minute Expert Call.  MicroJobs offers a whole range of other formats, and a lot of fixed-price deliverables, for in all sorts of Microsoft areas, but for me the short Expert Call format was what suited me best.

Can the problems really be solved in 30 minutes?  If not, the site has a useful feature, “Custom extra” where I can ask for more time if required.  Bad news for them, good news for me, in both cases the experts solved my problems in a few minutes, walked me carefully through the solution, and then had time left over within the 30 minutes to solve a second problem.

The first problem I had was for an internal SharePoint site, used by our company's Marketing and Sales staff, with one list in particular where they wanted to change the order of the columns in the New and Edit forms, and to hide some columns.  I don’t think it’s a good use of company resources to use our developers’ time or our client support staff to do this sort of thing for our marketing and sales staff, which would mean they have less time for our customers.  Typically Sales & Marketing fend for themselves or I do it for them myself.

I had tried to do it myself.  There were complications and the usual way to do it didn’t work.  Sometimes they use Modern view and sometimes they use Classic, so that limits how it can be done and there were issues with content types and site columns.

I could have researched it myself and spent a lot of time reading blogs, found solutions for slightly different problems that may or may not apply to me, or looked up some relevant conference slides or a YouTube video.  But why do that when someone who wrote the blog or gave the conference talk or recorded the video is probably on MicroJobs and willing to do this for me?

In this case an experienced MVP was willing to do this for less than what I would pay a taxi driver for the same amount of their time.  I don’t know why they do it.  When I was a freelance consultant, I charged a lot more than that and I wouldn’t have agreed to do 30-minute assignments, not worth the overhead.  Take advantage of it before they realize they should charge more!

I headed to jobs.collab365.community and gave it a shot.

The MicroJobs site is easy to use.  I use other freelancer sites for other things, and this one is easier, and the level of experience of the freelancers on the site is noticeably high.  Log in using a Microsoft account, or LinkedIn, or Google, or Facebook, or an email.  Then search for what you’re looking for.  You’ll see offers that some of the experts have posted.  You can also post a request and have people offer to help you, or you can find the right person first and ask them whether they could do the task that you need done.

I contacted Nick through the site, which has a handy chat interface.  We discussed it a bit, then set a time, and later on we changed that time a bit.  The MicroJobs site has a built-in videoconferencing and screen sharing tool (based on Jitsi Meet it looks like) that works really well right in the browser, and lets you talk and share your screen.

I shared my screen and Nick understood right away what I wanted to do, a list of about 10 changes.  It had to be done in classic mode.  We ran into a couple of small difficulties, which reassured me that the problem was not obvious, and they were solved right away.  I’m not particularly fast in doing the "click there", "type this", and yet we were done in 15 minutes.  Pro tip: have a second problem ready.  OK, I said, if there is more time here is something else I was planning to do: add a new content type to the list, with a subset of the columns and the ability to promote a record from one content type to the other.  That turned out to be a bit more difficult.  None of the columns were site columns but this would have to be a site content type.  No problem.  Nick guided me in creating a site content type that inherits from the same parent as the other, then modifying its instance within the list.  He reassured me that we could omit a required column.  Within a few minutes we were all done and had 5 minutes left to test that it worked for new and edit forms in both classic and modern mode, and that we could promote an item to a different content type.

Verdict, on a tricky problem that I couldn’t figure out, we got twice as much done as I expected, and I had to compromise on nothing.  The payment gateway released the money when he and I agreed that the work was completed.  After it was all settled, the invoice came straight from the expert, not the site.

The second problem was one that had to do directly with one of our products, so I am being be less specific as to the details.  For our machine translation product for modern pages, we provide instructions as to how to call it from a Power Automate flow so that a page can be translated as soon as it’s published.  But I wasn’t sure whether the instructions we planned to provide would follow best practice in terms of security and good governance.  Through the MicroJobs site I found Matthew, an expert in Power Automate, another MVP, who also knew a lot about Azure app registration including the less common authentication method that we were using.

Chatting with Matthew prior to giving him the task, he seemed to understand quickly and he asked me whether I knew about a different feature of Power Automate, and said we should have a chat about it.  I knew a bit about that other feature and I didn’t think it applied to this. I dismissed the suggestion.  I didn’t want to change the software, I just wanted best practices for deployment.  Perhaps we could look at that other feature later if there is time.

Matthew accepted the job, he set it up with Teams and we started the call at the appointed time.  He started out saying "I just want to show you this feature, I think it will help you."  OK, I thought, let’s have a look at it for a few minutes and see why he’s so keen on it.  It turns out it was exactly what we needed.  We didn’t have to explain away the security issues, this just solved them and we didn’t have to change a single line of code.  It was also a lot more flexible and scalable.  This is way beyond my expectations.  This is why it’s useful to speak with experts, they don’t just answer your question, they solve the underlying problem, and combine their knowledge and experience to analyze it and to think of the best way to solve it.  I would never have thought of this by just Googling answers to my how-to questions.  We started implementing his advice right away.

Just before the part where he was showing a sequence of steps with a detailed example, Matthew asked whether he could record the part of the session so he could send it to me.  Very thoughtful, I can use it for later reference if I forget some of the steps.

This MicroJob had a significant impact at very little cost.  This is definitely something I would do again.

You get to rate the freelancer.  These ratings are made public.  The freelancer also gets to rate you.  That is not public as far as I know, but might be available to other freelancers.  Apparently I’m “laid back” and “easy to work with”.  Nice to know.

But what happens if things do not go as well?  Thanks to my mistakes I got a tour of the dispute resolution and order cancellation process.  Apparently, I ordered the same MicroJob twice.  Not only that, but I marked it as delivered  twice, I convinced the consultant to mark the second one as delivered, thinking that he had forgotten and it was the same job, and I even paid for it twice.

I don’t think anyone had ever done all of that before, so when I contacted the freelancer to cancel it after realizing my mistake, he wasn’t certain how to fix this, and tried the dispute resolution mechanism.  

The dispute resolution mechanism is nicely thought out and goes to the dispute resolution team.  In this case, they apparently thought there was a better way to handle this.  They cancelled the dispute to reinstate the job and then the freelancer initiated a cancellation by mutual consent.  

Cancellation by mutual consent is very straighforward.

I received an email, followed the link to the site, and consented to the cancellation.  The money was immediately refunded to my credit card.  


The final verdict is that the process is well thought out, the people and service are high quality, it is a bargain, and it is essentially risk free.  Some day they will figure out that they could be charging higher rates, but for the time being take advantage of it.

Disclaimer:  I am not being paid for this review, but the people at Collab365 encouraged me to try it and to review it.  They offered to reimburse me for my first MicroJob but I declined.

Supporting another 12 Languages

In the most recent version of PointFire Translator (beta) we are introducing new or enhanced support for 12 new languages.

Of these, four are languages that are supported by SharePoint.  Irish and Kazakh languages are now supported for machine translation.  That means if your SharePoint site supports Irish or Kazakh, PointFire Translator can now translate its pages, documents, and lists, and PointFire 365 will automatically filter and/or redirect as appropriate.  If you want to translate the user interface, contact us, one of the steps is different for those languages than for other languages.

PointFire Translator now supports European Portuguese and Brazilian Portuguese as two separate languages.  Before this, the same translation engine was used for both, a neutral Portuguese that was actually closer to the Brazilian version.

Several new languages have been added to PointFire Translator which are not supported by SharePoint, including Māori (New Zealand), and five languages from India and Pakistan: Marathi, Gujarati, Punjabi, Malayalam and Kannada.  PointFire Translator will happily translate to or from those non-SharePoint languages, but PointFire 365 will be unable to filter by that language code.

All of those new languages have Neural Network engines behind them.  Irish, Brazilian Portuguese, Marathi, Gujarathi, and Māori have a customizable engine, meaning you can re-train it with your own documents to improve the translation quality.


The other two languages, or rather one language and two scripts, are ones that PointFire Translator had supported before and which had stopped working and discontinued.  In preparation for the Galactic Collaboration Summit we decided to brush off our Klingon translator.  This is where we discovered that there had been an undocumented change to Microsoft's Klingon language codes.  So we are happy to announce that we have reinstated Klingon (Latin script) and Klingon (pIqaD script).  If you choose the pIqaD script, make sure that you download a font that supports it, and change the font on the document.  This language only has a statistical translation engine, not a neural translation engine, so the quality is not very good.  But to paraphrase Samuel Johnson, it is like a dog's walking on his hind legs. It is not done well, but you are surprised to find it done at all.

If you're keeping count, that is 73 languages in total.

Changes to Serbian language codes in SharePoint Online

One of the changes that went into general availability last week was the retiring of the "sr-Latn-CS" language code, Locale ID 2074.

"Serbian (Cyrillic, Serbia)" [LCID=10266, language code "sr-Cyrl-RS"] was renamed "Serbian (Cyrillic)" and 
"Serbian (Latin, Serbia)" [LCID=9242, language code "sr-Latn-RS"] was renamed "Serbian (Latin)"


"CS" in the sr-Latn-CS was the former country code for the State Union of Serbia and Montenegro until it was dissolved in 2006 and Serbia and Montenegro became separate countries.  "RS" is the code for "Republic of Serbia" not to be confused with Republika Srpska. I have never noticed any UI difference between sr-Latn-CS and sr-Latn-RS, they were probably identical.  Many users in countries other than Serbia where Serbian is used, such as Montenegro or Bosnia and Herzegovina, tended to use the code because it did not mention Serbia in the name.  In case you're wondering, yes the versions of Serbian used in Bosnia and in Montenegro are different from the one used in Serbia, in fact there are a few more letters in the alphabet.  However they are not supported as distinct languages in SharePoint.


The locale IDs sr-Latn-RS and sr-Latn-BA  still exist in Delve, labelled with the country name for display language and for locales, and if you choose one there is a mapping done to the supported version of Serbian that uses the same script.

SharePoint Multilingual Page Publishing Feature in Detail

The new multilingual page publishing feature for Modern sites is now available in Targeted Release.  This is a good time to go through its main features in a bit more detail.

This SharePoint Online feature enables the publishing and consumption of pages and news in multiple languages in a modern SharePoint communication site. Multi-lingual page publishing means that on modern communication sites, site owners can determine in what languages they want to translate individual pages and news posts. This is different from Variations in that the translated pages are on the same multilingual site, but similar in that it copies pages and you have to translate them to the other language.


Turning it on

This feature must be turned on before it has any effect.  The activation is not, as you might think, in the site features section, but in Language settings.



Language settings was there before, this is where you used to set the Alternate languages for a site.  You can still do that more or less like before if you don't turn the feature on, by clicking on "Show advanced settings"

The new option is called "Enable pages and news to be translated into multiple languages"

The switch to turn on that feature appears on Communication sites, either new ones or existing ones.  It does not appear on Classic sites and it does not even appear on Modern Team sites.


If you click on "Show advanced settings" without enabling the feature, you can pick the list of alternate languages like before, and like before they are all turned on by default.


Parenthesis, what is Overwrite translations at the bottom?  It’s the same as before, with a different wording.  It has to do with what happens when you change MUI-enabled text in the site default language when it has has already been translated, will it leave the translations alone, or will it overwrite them with the new text in the original language as an indication that they need to be re-translated.

The second that you turn on the feature, even if you immediately turn it off again, all the site alternate languages are unselected.  You have to turn them on again one by one, using a different interface if the feature is activated.



 

The list of languages is the same as it was before with one exception, Serbian (Latin) has been dropped.

To select alternate languages, you can type a few letters of the language name or select it from the dropdown list



Selecting a language has two effects: it adds it to the list of alternate languages which determines the languages supported by the multilingual user interface (MUI), and it adds it to the list of languages to which site pages can be translated.

For each language you can select one or more "translator".  These are accounts that are notified by email whenever a page on this site should be translated to that language.  Naming someone as the translator does not give them rights to edit the pages, it simply sends them the email that contains a link to the page.  It is possible to send the email to external users, and it is possible to send it to people with no access to the list or to the site.  Sending it to a group works as well.

However if you type an email that’s not in AAD, then it gives a message when you save “Can’t save setting now.  Try again later”.  Always remember to hit save.



Adding pages

Since this is a Communication site, pages in the site default language can be added to the Site Pages library like before using Add a Page or by creating a News post.  Jumping ahead, creating a page, even with a different language selected, or using a language-specific News web part will always create pages that are assumed to be in the site default language and are in the root directory of the Site Pages library. 



"Translate" pages

You notice in the page menu bar that there is a "translation" button.  This will open a translation pane on the right.


As it clearly explains, this does not actually translate (unless you have PointFire Translator), it creates a nearly exact copy of the page either in all languages or in one language at a time.  You can do this with a draft or a published version, but keep in mind who can and cannot see drafts.  If you do not create them all at once, you can create the others individually or for all remaining languages at once.


All created pages are drafts initially.  It is then possible to get to that page in at least four ways.

1) Follow the "view" link
2) Follow the email link in the email that is sent to translators when the page is created


3) follow the little "Available languages" page navigation dropdown in the top right corner


Notice how this page navigation reminds you which page is published and which is a draft.

4) Navigating to the folder


When a translation page is created, it is put in a language-specific folder, with the same file name.  These folders use the PointFire naming convention, a two-letter code for languages where SharePoint supports only one variant, and language-dash-country or language-dash-script where there are more variants.

When you first visit the language-specific copy, you will notice that the title is changed to “Translate into {Language name}: {Original title}”.  You will also notice a message at the top, "This page has not been translated into {Language name} yet.  Edit to start translation"


This message remains until the page has been Saved once, even if you went in edit mode and changed nothing and it autosaved.  You (or someone else) are responsible for translating the content of the page, its title and the title and content of every webpart.  Remind translators to delete, not translate, the “Translate into {Language name}: ” part of the title.


User Language and Issue with Right-to-Left languages

Depending on the user's SharePoint language, there is a possibility of the user being redirected to the version of the same page in the user's language.  This redirection is not persistent, it is easy to navigate to pages in other languages without changing your own language.

When you go to a page in a right-to-left language while your current language is one that has left-to-right layout, you will see it with a left-to-right layout while editing.  The letters are RTL but the layout is LTR


If your current language is a right-to-left one, then you will see a right-to-left layout.  The layout depends on the user’s language, not the language of the page or of the site.   For those interested in the technical details, the "lang" and "dir" properties of the page's html element follow the user language settings.


Language of the user interface

This may be a good time to point out that while the feature will let you translate and navigate to pages in other languages, what you will see is only the page content in that language, the entire user interface will not switch to that language.  That's why in the first Arabic picture above you see the UI in one language and the content in the other language.  In the second Arabic picture, the content language and the UI language match, because the user's language setting matches the page language.  Changing your own SharePoint language is no easy feat.

Does this feature translate the UI?  No.  There are a number of UI elements that support MUI, and out-of-the-box elements are mostly populated with localized elements, but any customization that you do, for example to the navigation, will not be translated unless you translate it manually.  Here is how to localize your SharePoint navigation, but the same technique should be used for all localizable UI elements, including title/description of sites, lists, columns, content types, and views.

Can you translate custom SPFx web parts?  Almost never.  Whoever developed the webpart might have given you the ability to change certain strings on the page, but developers should probably also follow the guidance to localize the webpart.  This localization will follow the user's language, not the page or site language.
 

Deleting pages

What if you make a change to the original page?  Can you re-copy it to the translations? No (again, unless you have PointFire Translator).  However now is a good time for human translators to discover the new SharePoint page version comparison feature to highlight what has changed and determine what need to be re-translated.

It won’t re-copy unless you delete the translated copy.  The feature adapts well to deleting the translated copy. The “Available languages” menu adapts, as does the translation pane.

If you delete the original, the copies stay.  However they feel some distress.  If you click on the “Available languages” menu while on one of the orphaned copies, it spins and never returns

 

If you turn off the feature, all the pages stay, but most of the language functionality is removed.  The functionality returns if the feature is turned back on again.


 News Webpart language filtering

One cool automatic feature I'm still trying to find the limits of is the filtering of News and Highlighted Content webparts by language.  If you have a News webpart on a default language page, it will only show published news items that are in the default language.  However if that same webpart is on a translated language page, the webpart only shows published news items that are in that language.  The filtering is automatic, there are no explicit filter conditions that are added or can be modified.  If you turn off the feature, then the filtering stops.  Does it work with Hub news or on the SharePoint home page?  Stay tuned, not certain yet.

  

How PointFire Translator completes the functionality

For more details see the blog post about machine translation for multilingual page publishing.  Here is a video that shows how this automatic machine translation works


Essentially, the machine translation process can be completely automated.  When you view the new page for the first time, what you will see is not a copy of the original page for you to manually translate, but a translated page for you to approve and publish.  This saves huge amounts of time and money.
Office365™ - office.microsoft.com IceFire Studios is a Microsoft Partner SharePoint™ 2013 - Microsoft.com