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 as the language(en-US).
[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 display. You can implement a custom ILanguageDetector plugin to completely change the logic that is used to make this decision. ILanguageDetector is an ISingletonPlugin type, therefore you can only have 1 enabled at a time.
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 existing ones which includes the default one that ships in Telligent Community. It is called "Anonymous User Language Detector" and can be found in Administration under the Extensions menu option.
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 logged in users to get the language and for unauthenticated users browsing the site it will be in 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.
public string DetectLanguage(ILanguageDetectionController controller) { }
ILanguageDetectorController gives access to several items we can use in our 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 readonly 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.
For our example we only want to process web requests so if there is no HttpContext we are going to rely on profile language settings. The biggest reasoning is in our case there is no web request to get a cookie from so we will rely on user profile settings and the system service account setting.
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. If they are we are going to attempt to read a cookie with a name of "user_lang". The value of this cookie is the language key. 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.
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 whole method
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 yo your community. It does require a little extra setup to work. 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 languages.xml and add a node for French like so:
<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 under Administration->Extensions a plugin named "Anonymous User Language Detector" 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 import the attached xml file. 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 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>