What is the specific reference of the first parameter in NLS localize?

Regarding the question on localizing VSCode extensions, I am also curious why the localize function requires two parameters.

When it comes to localizing settings, it's a simple process of replacing literal values with tokens surrounded by percent signs, which are then replaced using a dictionary from a file based on the current locale.

However, the localize function demands at least two parameters - a key and a message. It can also accept an unspecified number of subsequent parameters of any type, referred to as "args."

The lack of documentation on this topic is quite noticeable.

Initially, the sample code won't even compile until you update the package.json to require a minimum vscode version of 1.34 instead of 1.32 in order to accommodate updates to the TS typing files. Once this modification is made, the sample compiles and launches, but does not appear to work as expected (the activate function does not run; I am still investigating this issue).

The sample includes a call to localize with the key "sayHello.text," but I couldn't find a corresponding string in the localization resources. The use of arbitrary args suggests dynamic composition at runtime, although this is not demonstrated in the sample code. Due to the lack of documentation, it's difficult to understand the functionality fully.

Can anyone provide insight into the parameters?

After examining the vscode-nls repository, I came across the following code snippet.

export function localize(_key: string | LocalizeInfo, message: string, ...args: any[]): string {
    return format(message, args);
}

Despite the appearance that it does not utilize _key, there is a localizeFunc with a similar signature that does make use of it. I suspect a configuration function call may be manipulating names behind the scenes.

Answer №1

The configuration function works its magic in mysterious ways. It's a prime example of the distinction between clever and intelligent. This function adds an extra layer of satisfaction to working with webpack.

Let's say you want to add support for French.

In the i18n directory of your project, create a folder named fra. Just three letters, following the standard for three-letter country codes. A quick search engine query will guide you.

You're probably already aware that you need to create a package.i18n.json file inside this folder, containing key-value pairs like this:

{
    "extension.sayHello.title": "Bonjour",
    "extension.sayBye.title": "Au revoir"
}

The values in this file will be used to replace the corresponding placeholders in the package.json values, enclosed in percent signs.

If you create an out directory next to the package.i18n.json file, and add an extension.i18n.json file inside the out directory with the following content:

{
    "sayHello.text": "Bonjour from extension.i18n.json"
}

the key to use for localization is "sayHello.text". The second parameter acts as a fallback if a matching key is not found for the current display language.

Before this setup can function correctly, you need to complete three additional steps.

  1. Update the gulpfile.js to include the languages you want to support.
    const languages = [
     { folderName: 'jpn', id: 'ja' },
     { folderName: 'fra', id: 'fr' }
    ];
    
  2. Install Gulp and run the gulp build command.
  3. Change your display language to French.

By calling

localize("sayHello.text", "default value")
, you will receive "Bonjour from extension.i18n.json" when using French as the display language and "default value" for other languages.

The optional arguments supposedly allow for placeholder replacement in the return value, but documentation on this feature is lacking, and its usage is rare.

Note: If you have imports of classes nested in folders, the folder structure of the localization dictionaries must match. Adjustments may be necessary if you are not building into an out directory.

For a basic example provided by Microsoft, check out this minimal worked example. While it lacks detailed explanations, you can use this answer as a guide to understand the sample better.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve the value of a property with a generic type

Within our angular6 project, we encountered an issue while using the "noImplicitAny": true setting. We realized that this caused problems when retrieving values from generic types. Currently, we retrieve the value by using current['orderBy'], bu ...

Utilizing conditional types for type narrowing within a function's body: A comprehensive guide

I created a conditional type in my code that constrains the second argument of my class constructor based on the type of the first argument. Although the type checker correctly limits what I can pass to the constructor, I am struggling to get the compiler ...

custom field component for react-hook-form

I have been working on creating a form field component that can be utilized at both the root form level and as a nested field. export type FirstNameField = { firstName: string; }; type GenericFormType<T, NS extends string | never = never> = NS ext ...

Create a function that takes advantage of a Promise to resolve its actions

In the asynchronous function provided below: export default async function getUserNames(id: string[]): Promise<string[]> { let userNames: string[] = []; // Additional actions such as service calls are performed here... return userNames; ...

What is the implication when Typescript indicates that there is no overlap between the types 'a' and 'b'?

let choice = Math.random() < 0.5 ? "a" : "b"; if (choice !== "a") { // ... } else if (choice === "b") { This situation will always be false because the values 'a' and 'b' are completely disti ...

What TypeScript syntax is similar to Java's "? extends MyClass" when using generics?

How can we indicate the TypeScript equivalent of Java's ? extends MyClass? One possible way to achieve this is: function myFunc <TComponent extends MyBaseClass>(param: ComponentFixture<TComponent>) {} Is there a more concise alternative ...

Guide on integrating external libraries with Angular CLI

I've been working on incorporating external libraries into my project, and I've been following the instructions provided here. While I know it's possible to use CDNs in my index.html, I'm interested in learning how to do it using TypeS ...

Tips for selecting objects based on property in Typescript?

Consider this scenario: import { Action, AnyAction } from 'redux'; // interface Action<Type> { type: Type } and type AnyAction = Action<any> export type FilterActionByType< A extends AnyAction, ActionType extends string > ...

Issue with Bot framework (v4) where prompting choice in carousel using HeroCards does not progress to the next step

Implementing HeroCards along with a prompt choice in a carousel is my current challenge. The user should be able to select options displayed as HeroCards, and upon clicking the button on a card, it should move to the next waterfall function. In the bot fr ...

Transforming FormData string key names into a Json Object that is easily accessible

Recently, I encountered an issue where my frontend (JS) was sending a request to my backend (Node Typescript) using FormData, which included images. Here is an example of how the data was being sent: https://i.stack.imgur.com/5uARo.png Upon logging the r ...

Deeply nested .map function to update state value

The current state value const [settings, setSettings] = useContext(SettingsContext) Utilizing the .map method on the settings state {settings[categoryIndex]?.config?.map((item: ConfigItem, index: number) => ...

Strategies for passing multiple props to a function in React using TypeScript, such as useState([]) and useState(boolean)

Dealing with API Structure { "default": [ { "id": 1, "name": "A" }, { "id": 2, "name": "B" }, { "id": 3, "name" ...

Implementing a NextJS client component within a webpage

I am currently working with NextJS version 14 and I am in the process of creating a landing page. In one of the sections, I need to utilize the useState hook. I have specified my component as "use-client" but I am still encountering an error stating that " ...

Sending data to a parent component from a popup window in Angular Material using a button click while the window is still open

How can I retrieve data from an Angular Material Dialog Box and send it to the Parent component? I am able to access data after the dialog box is closed. However, I am wondering if there is a way to retrieve data while the dialog box is still open, especi ...

Incorporating TypeScript's internal references

I am currently working on defining my own model interface that extends the Sequelize model instance. However, I am encountering difficulties in referencing the Sequelize interface within my code. Specifically, I receive an error stating "Cannot find name ...

Unused Default Resource.resx file detected

In my WPF application, I have implemented localization. Recently, I encountered an issue where changing the Format to Hindi(India) in Control Panel -> Region -> Formats seems to affect the way my WPF application reads the CultureInfo.CurrentCulture, ...

I can't find my unit test in the Test Explorer

I'm currently working on configuring a unit test in Typescript using tsUnit. To ensure that everything is set up correctly, I've created a simple test. However, whenever I try to run all tests in Test Explorer, no results are displayed! It appear ...

Reactive form allows you to easily format dates

Currently, the date displayed is 1/4/2022. We need it to display in the format 01/04/2022. Can we achieve this formatting using reactive forms with the sample Model form provided below? Thank you. How can we format it when starting from transactionStartD ...

How can the values from the scale [-60, -30, -10, 0, 3, 6, 10] be converted to a decimal range of 0-1 through

Thank you for helping me with so many of my issues. <3 I'm certain that someone has already solved this, but I'm unsure of the specific mathematical term (I've attempted reverse interpolation and others, but with no luck) so I am present ...

How to modify the background color within the mat-menu-panel

Incorporating angular 9 and less into my current project, I have encountered an issue with a mat-menu-panel where my mat-menu-item is located. While I have successfully changed the color of my mat-menu-item, I am now faced with the challenge of changing th ...