When you install additional languages into Telligent Community users have the option to choose one of those installed languages as their preferred language. This will mean all content not generated dynamically or by the community will be translated into that language. If someone is browsing the site and not logged in, the site will evaluate the Accept-Language HTTP Header sent by browser. By default Telligent Community ships with U.S English(en-US) as the language.
[toc]
When Would You Would Use ILanguageDetector?
As mentioned, a site uses the following logic to determine what language should be used:
There may however be scenarios where you would like alter the logic that determines what language to use.
Creating a Custom Language Detector
In the rare instance you want to create a new way of defining the site language you can do so by creating a new plugin implementing ILanguageDetector. It's also important know that ILanguageDetector is a singleton plugin, meaning a site can only have a single language detector enabled at a time. This means in order to use a custom ILanguageDetector you must first disable any other language detectors.
Required References:
- Telligent.Evolution.Platform.dll
- System.Web (.NET Assembly Reference)
Sample: Cookie Based Language Detector
We are going to create a sample that reads a cookie for authenticated users to get the language and for unauthenticated users browsing the site it will force the language to French(fr-FR).
We'll start by creating a new plugin called SampleLanguageDetection
that implements from ILanguageDetector. You will get the standard IPlugin members(omitted for brevity) and a DetectLanguage(ILanguageDetectionController)
method that returns a language code as a string. If you wish to defer to the user or anonymous user's chosen language, return null
. The DetectLanguage
is invoked whenever a request for a user's language is made and stored for the remainder of the request or process.
public string DetectLanguage(ILanguageDetectionController controller) { }
ILanguageDetectionController gives you access to several items you can utilize in your implementation:
- UserId - The user Id of the currently logged in user. If its null then its an anonymous(unauthenticated) request.
- HttpContext - The current HttpContext as HttpContextBase. If its null you are not in the scope of a web request and more than in likely in a job execution.
- SupportedLanguages - The current set of language packs installed in the community as a read only list of language code strings.
- IsLanguageSupported - A method that will tell you if a given language key is supported on this site. You cannot return a language key if that language is not currently installed.
Since our process mainly depends on the presence of a browser cookie, we only want to run when we are in the scope of a web request. To do this we see if HttpContext in the controller is null. If it is, its more than likely a job execution and we will defer to the language setting of the system account or user the process is running as.
if(controller.HttpContext == null) return null; //defer back to the user profile or system account setting
Next we need to know if a user is logged in by seeing if we received a user id on the controller. If they are logged in we are going to attempt to read a cookie with a name of "user_lang". The value of this cookie will be the language key to use for that user. If we cannot find a cookie or the value is not a supported language on the site we will defer to the user profile setting. If a user is not logged in, then we will always return French (fr-FR). We do make an assumption that french is installed on our community. We assume in this example the cookie is set by some custom process beyond the scope of this topic.
if (controller.UserId.HasValue) //User is logged in { var cookie = controller.HttpContext.Request.Cookies["user_lang"]; if(cookie != null && !string.IsNullOrEmpty(cookie.Value)) { var lang = cookie.Value; //We must make sure the site supports this language, meaning there is an installed language pack and //its defined in Web/Languages/languages.xml if(controller.IsLanguageSupported(lang)) return lang; } } else { //Not logged in, make it a french site return "fr-FR"; } return null; //Could not find a cookie or the value was not set
Here is the method implementation in its entirety.
public string DetectLanguage(ILanguageDetectionController controller) { if(controller.HttpContext == null) return null; //defer back to the user profile or system account setting //If a user is logged in we are going to read a cookie called user_lang. //For non-authenticated users we are going to force the entire site to French(fr-FR) if (controller.UserId.HasValue) //User is logged in { var cookie = controller.HttpContext.Request.Cookies["user_lang"]; if(cookie != null && !string.IsNullOrEmpty(cookie.Value)) { var lang = cookie.Value; //We must make sure the site supports this language, meaning there is an installed language pack and //its defined in Web/Languages/languages.xml if(controller.IsLanguageSupported(lang)) return lang; } } else { //Not logged in, make it a french site return "fr-FR"; } return null; //Falls back to user profile or system setting, we could not find a cookie }
Running the Sample
At the bottom of the article is the full source for this plugin that you can compile and deploy to your community. It does require a little extra setup to work since we are dealing with language packs in addition to the code. After deploying the DLL to your site, follow these steps to see it in action:
1. In your Telligent Community web installation locate the languages folder. Create a folder with the name fr-FR and copy the entire contents of the en-US folder into it. Because you need a fully installed language pack to work we are going to simulate this set of resources using the English ones just for testing. We will use a widget to show the language change.
2. In the same languages folder, edit the languages.xml file and add an entry for French(fr-FR):
<root> <!-- Specify enabled languages here --> <language name="U.S. English" key="en-US" /> <language name="French" key="fr-FR" /> </root>
3. Search for or locate a plugin named "Anonymous User Language Detector" in the Administration ->Extensions and disable it if its not already. Then in the same section locate(or use search) to find the new sample plugin "Sample Language Detector" and enable it.
4. Below is also an xml file of a test widget. In widget studio Working With Widget Studio. It will install a widget called "Language Test" you should publish for use on your site. It is designed to simply write Hello in English or French depending on our language detector.
5. Add the new widget to a page of your choosing.
If you are logged in and assuming you have English as your profile language, the widget should say "Hello". If you sign out, it should switch to "Bonjour". If you log back in you can test it sees the cookie by using a tool of your choice to create a cookie named "user-lang" with a value of "fr-FR" which will make it say "Bonjour" again. Using a language code not installed on the site will result in English. This plugin assumes a cookie is created by some custom process. Creating cookies is beyond the scope of this topic but there are many browser tools available to do this.
Source
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Telligent.DynamicConfiguration.Components; using Telligent.Evolution.Extensibility.Version1; namespace Samples { public class SampleLanguageDetection : ILanguageDetector { #region IPlugin public string Name { get { return "Sample Language Detector"; } } public string Description { get { return "Overrides The Language Setting For Users"; } } public void Initialize() { } #endregion #region ILanguageDetector public string DetectLanguage(ILanguageDetectionController controller) { if(controller.HttpContext == null) return null; //defer back to the user profile or system account setting //If a user is logged in we are going to read a cookie called user_lang. //For non-authenticated users we are going to force the entire site to French(fr-FR) if (controller.UserId.HasValue) //User is logged in { var cookie = controller.HttpContext.Request.Cookies["user_lang"]; if(cookie != null && !string.IsNullOrEmpty(cookie.Value)) { var lang = cookie.Value; //We must make sure the site supports this language, meaning there is an installed language pack and //its defined in Web/Languages/languages.xml if(controller.IsLanguageSupported(lang)) return lang; } } else { //Not logged in, make it a french site return "fr-FR"; } return null; //Falls back to user profile or system setting, we could not find a cookie } #endregion } }
Sample Widget
<scriptedContentFragments> <scriptedContentFragment name="Language Test" version="9.0.0.0" description="" instanceIdentifier="f6b3b73aeeea4cb599d8b17dd4e571c1" theme="" isCacheable="false" varyCacheByUser="false" showHeaderByDefault="true" cssClass="" provider="7bb87a0cc5864a9392ae5b9e5f9747b7"> <contentScript><![CDATA[<p><strong>$core_v2_language.Get("sayHello")</strong></p>]]></contentScript> <languageResources><language key="en-us"> <resource name="sayHello">Hello!</resource> </language></languageResources> </scriptedContentFragment> </scriptedContentFragments>