Updates to localization

This commit is contained in:
Elio Struyf
2023-11-06 15:11:00 +01:00
parent 046b24337d
commit 258c5fe670
8 changed files with 299 additions and 57 deletions
+41 -1
View File
@@ -28,6 +28,12 @@
"common.pin": "Pin",
"common.unpin": "Unpin",
"common.noResults": "No results",
"common.error": "Sorry, something went wrong.",
"common.yes": "yes",
"common.no": "no",
"notifications.outputChannel.link": "output window",
"notifications.outputChannel.description": "Check the {0} for more details.",
"settings.view.common": "Common",
"settings.view.contentFolders": "Content folders",
@@ -488,6 +494,40 @@
"commands.folders.get.notificationError.remove.action": "Remove folder",
"commands.folders.get.notificationError.create.action": "Create folder",
"listeners.dashboard.settingsListener.triggerTemplate.notification": "Template files copied."
"commands.preview.panel.title": "Preview: {0}",
"commands.preview.askUserToPickFolder.title": "Select the folder of the article to preview",
"commands.project.initialize.success": "Project initialized successfully.",
"commands.project.switchProject.title": "To which project do you want to switch?",
"commands.project.createSampleTemplate.info": "Sample template created.",
"commands.settings.create.input.prompt": "Insert the value of the {0} that you want to add to your configuration.",
"commands.settings.create.input.placeholder": "Name of the {0}",
"commands.settings.create.warning": "The provided {0} already exists.",
"commands.settings.create.quickPick.placeholder": "Do you want to add the new {0} to the page?",
"commands.settings.export.progress.title": "{0}: exporting tags and categories",
"commands.settings.export.progress.success": "Export completed. Tags: {0} - Categories: {1}.",
"commands.settings.remap.quickpick.title": "Remap",
"commands.settings.remap.quickpick.placeholder": "What do you want to remap?",
"commands.settings.remap.noTaxonomy.warning": "No {0} configured.",
"commands.settings.remap.selectTaxonomy.placeholder": "Select your {0} to insert.",
"commands.settings.remap.newOption.input.prompt": "Specify the value of the {0} with which you want to remap \"{1}\". Leave the input <blank> if you want to remove the {0} from all articles.",
"commands.settings.remap.newOption.input.placeholder": "Name of the {0}",
"commands.settings.remap.delete.placeholder": "Delete {0} {1}?",
"commands.statusListener.verifyRequiredFields.diagnostic.emptyField": "The {0} field is required. Please define a value for the field.",
"commands.statusListener.verifyRequiredFields.notification.error": "The following fields are required to contain a value: {0}",
"commands.template.generate.input.title": "Template title",
"commands.template.generate.input.prompt": "Which name would you like to give your template?",
"commands.template.generate.input.placeholder": "article",
"commands.template.generate.noTitle.warning": "You did not specify a template title.",
"commands.template.generate.keepContents.title": "Keep content",
"commands.template.generate.keepContents.placeholder": "Do you want to keep the contents for the template?",
"commands.template.generate.keepContents.noOption.warning": "You did not pick any of the options for keeping the template its content.",
"commands.template.generate.keepContents.success": "Template created and is now available in your {0} folder.",
"commands.template.getTemplates.warning": "No templates found.",
"commands.template.create.folderPath.warning": "Incorrect project folder path retrieved.",
"listeners.dashboard.settingsListener.triggerTemplate.notification": "Template files copied."
}
+6 -2
View File
@@ -24,6 +24,8 @@ import { WebviewHelper } from '@estruyf/vscode';
import { Folders } from './Folders';
import { ParsedFrontMatter } from '../parsers';
import { getLocalizationFile } from '../utils/getLocalizationFile';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
export class Preview {
public static filePath: string | undefined = undefined;
@@ -71,7 +73,9 @@ export class Preview {
// Create the preview webview
const webView = window.createWebviewPanel(
'frontMatterPreview',
article?.data?.title ? `Preview: ${article?.data?.title}` : 'FrontMatter Preview',
article?.data?.title
? l10n.t(LocalizationKey.commandsPreviewPanelTitle, article?.data.title)
: 'Front Matter Preview',
{
viewColumn: ViewColumn.Beside,
preserveFocus: true
@@ -393,7 +397,7 @@ export class Preview {
const folderNames = crntFolders.map((folder) => folder.title);
const selectedFolderName = await window.showQuickPick(folderNames, {
canPickMany: false,
title: 'Select the folder of the article to preview'
title: l10n.t(LocalizationKey.commandsPreviewAskUserToPickFolderTitle)
});
if (selectedFolderName) {
+10 -4
View File
@@ -21,6 +21,8 @@ import {
} from '../constants';
import { SettingsListener } from '../listeners/dashboard';
import { existsAsync, writeFileAsync } from '../utils';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
export class Project {
private static content = `---
@@ -66,7 +68,7 @@ categories: []
if (sampleTemplate !== undefined) {
await Project.createSampleTemplate();
} else {
Notifications.info('Project initialized successfully.');
Notifications.info(l10n.t(LocalizationKey.commandsProjectInitializeSuccess));
}
// Initialize the media library
@@ -89,10 +91,14 @@ categories: []
} catch (error: unknown) {
const err = error as Error;
Logger.error(`Project::init: ${err?.message || err}`);
Notifications.error(`Sorry, something went wrong - ${err?.message || err}`);
Notifications.errorWithOutput(l10n.t(LocalizationKey.commonError));
}
}
/**
* Project switcher
* @returns
*/
public static async switchProject() {
const projects = Settings.getProjects();
const project = await window.showQuickPick(
@@ -100,7 +106,7 @@ categories: []
{
canPickMany: false,
ignoreFocusOut: true,
title: 'Select a project to switch to'
title: l10n.t(LocalizationKey.commandsProjectSwitchProjectTitle)
}
);
@@ -136,7 +142,7 @@ categories: []
await writeFileAsync(article.fsPath, Project.content, {
encoding: 'utf-8'
});
Notifications.info('Sample template created.');
Notifications.info(l10n.t(LocalizationKey.commandsProjectCreateSampleTemplateInfo));
}
}
+41 -29
View File
@@ -5,6 +5,8 @@ import { EXTENSION_NAME } from '../constants';
import { ArticleHelper, FilesHelper } from '../helpers';
import { FrontMatterParser } from '../parsers';
import { Notifications } from '../helpers/Notifications';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
export class Settings {
/**
@@ -13,11 +15,11 @@ export class Settings {
* @param type
*/
public static async create(type: TaxonomyType) {
const taxonomy = type === TaxonomyType.Tag ? 'tag' : 'category';
const newOption = await vscode.window.showInputBox({
prompt: `Insert the value of the ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} that you want to add to your configuration.`,
placeHolder: `Name of the ${type === TaxonomyType.Tag ? 'tag' : 'category'}`,
prompt: l10n.t(LocalizationKey.commandsFoldersCreateInputPrompt, taxonomy),
placeHolder: l10n.t(LocalizationKey.commandsFoldersCreateInputPlaceholder, taxonomy),
ignoreFocusOut: true
});
@@ -25,9 +27,7 @@ export class Settings {
let options = (await TaxonomyHelper.get(type)) || [];
if (options.find((o) => o === newOption)) {
Notifications.info(
`The provided ${type === TaxonomyType.Tag ? 'tag' : 'category'} already exists.`
);
Notifications.warning(l10n.t(LocalizationKey.commandsSettingsCreateWarning, taxonomy));
return;
}
@@ -35,15 +35,16 @@ export class Settings {
TaxonomyHelper.update(type, options);
// Ask if the new term needs to be added to the page
const addToPage = await vscode.window.showQuickPick(['yes', 'no'], {
canPickMany: false,
placeHolder: `Do you want to add the new ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} to the page?`,
ignoreFocusOut: true
});
const addToPage = await vscode.window.showQuickPick(
[l10n.t(LocalizationKey.commonYes), l10n.t(LocalizationKey.commonNo)],
{
canPickMany: false,
placeHolder: l10n.t(LocalizationKey.commandsSettingsCreateQuickPickPlaceholder, taxonomy),
ignoreFocusOut: true
}
);
if (addToPage && addToPage === 'yes') {
if (addToPage && addToPage === l10n.t(LocalizationKey.commonYes)) {
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
@@ -54,7 +55,7 @@ export class Settings {
return;
}
const matterProp: string = type === TaxonomyType.Tag ? 'tags' : 'categories';
const matterProp: string = taxonomy;
// Add the selected options to the options array
if (article.data[matterProp]) {
const propData: string[] = article.data[matterProp];
@@ -83,7 +84,7 @@ export class Settings {
vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: `${EXTENSION_NAME}: exporting tags and categories`,
title: l10n.t(LocalizationKey.commandsSettingsExportProgressTitle, EXTENSION_NAME),
cancellable: false
},
async (progress) => {
@@ -146,7 +147,11 @@ export class Settings {
// Done
Notifications.info(
`Export completed. Tags: ${crntTags.length} - Categories: ${crntCategories.length}.`
l10n.t(
LocalizationKey.commandsSettingsExportProgressSuccess,
crntTags.length,
crntCategories.length
)
);
}
);
@@ -157,8 +162,8 @@ export class Settings {
*/
public static async remap() {
const taxType = await vscode.window.showQuickPick(['Tag', 'Category'], {
title: `Remap`,
placeHolder: `What do you want to remap?`,
title: l10n.t(LocalizationKey.commandsSettingsRemapQuickpickTitle),
placeHolder: l10n.t(LocalizationKey.commandsSettingsRemapQuickpickPlaceholder),
canPickMany: false,
ignoreFocusOut: true
});
@@ -168,15 +173,18 @@ export class Settings {
}
const type = taxType === 'Tag' ? TaxonomyType.Tag : TaxonomyType.Category;
const taxonomy = type === TaxonomyType.Tag ? 'tags' : 'categories';
const options = (await TaxonomyHelper.get(type)) || [];
if (!options || options.length === 0) {
Notifications.info(`No ${type === TaxonomyType.Tag ? 'tags' : 'categories'} configured.`);
Notifications.warning(
l10n.t(LocalizationKey.commandsSettingsRemapNoTaxonomyWarning, taxonomy)
);
return;
}
const selectedOption = await vscode.window.showQuickPick(options, {
placeHolder: `Select your ${type === TaxonomyType.Tag ? 'tags' : 'categories'} to insert`,
placeHolder: l10n.t(LocalizationKey.commandsSettingsRemapSelectTaxonomyPlaceholder, taxonomy),
canPickMany: false,
ignoreFocusOut: true
});
@@ -186,19 +194,23 @@ export class Settings {
}
const newOptionValue = await vscode.window.showInputBox({
prompt: `Specify the value of the ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} with which you want to remap "${selectedOption}". Leave the input <blank> if you want to remove the ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} from all articles.`,
placeHolder: `Name of the ${type === TaxonomyType.Tag ? 'tag' : 'category'}`,
prompt: l10n.t(
LocalizationKey.commandsSettingsRemapNewOptionInputPrompt,
taxonomy,
selectedOption
),
placeHolder: l10n.t(LocalizationKey.commandsSettingsRemapNewOptionInputPlaceholder, taxonomy),
ignoreFocusOut: true
});
if (!newOptionValue) {
const deleteAnswer = await vscode.window.showQuickPick(['yes', 'no'], {
canPickMany: false,
placeHolder: `Delete ${selectedOption} ${type === TaxonomyType.Tag ? 'tag' : 'category'}?`,
placeHolder: l10n.t(
LocalizationKey.commandsSettingsRemapDeletePlaceholder,
selectedOption,
taxonomy
),
ignoreFocusOut: true
});
if (deleteAnswer === 'no') {
+12 -5
View File
@@ -1,6 +1,7 @@
import { ParsedFrontMatter } from './../parsers/FrontMatterParser';
import {
CONTEXT,
EXTENSION_NAME,
NOTIFICATION_TYPE,
SETTING_SEO_DESCRIPTION_FIELD,
SETTING_SEO_DESCRIPTION_LENGTH,
@@ -16,6 +17,8 @@ import { DataListener } from '../listeners/panel';
import { commands } from 'vscode';
import { Field } from '../models';
import { Preview } from './Preview';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
export class StatusListener {
/**
@@ -135,12 +138,13 @@ export class StatusListener {
const diagnostic: vscode.Diagnostic = {
code: '',
message: `This ${fields
.map((f) => f.name)
.join('/')} field is required to contain a value.`,
message: l10n.t(
LocalizationKey.commandsStatusListenerVerifyRequiredFieldsDiagnosticEmptyField,
fields.map((f) => f.name).join('/')
),
range: new vscode.Range(posStart, posEnd),
severity: vscode.DiagnosticSeverity.Error,
source: 'Front Matter'
source: EXTENSION_NAME
};
requiredDiagnostics.push(diagnostic);
@@ -158,7 +162,10 @@ export class StatusListener {
Notifications.showIfNotDisabled(
NOTIFICATION_TYPE.requiredFieldValidation,
'ERROR_ONCE',
`The following fields are required to contain a value: ${fieldsToReport.join(', ')}`
l10n.t(
LocalizationKey.commandsStatusListenerVerifyRequiredFieldsNotificationError,
fieldsToReport.join(', ')
)
);
}
}
+22 -15
View File
@@ -16,6 +16,8 @@ import { PagesListener } from '../listeners/dashboard';
import { extname } from 'path';
import { Telemetry } from '../helpers/Telemetry';
import { writeFileAsync, copyFileAsync } from '../utils';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
export class Template {
/**
@@ -31,27 +33,30 @@ export class Template {
const clonedArticle = Object.assign({}, article);
const titleValue = await vscode.window.showInputBox({
title: `Template title`,
prompt: `What name would you like to give your template?`,
placeHolder: `article`,
title: l10n.t(LocalizationKey.commandsTemplateGenerateInputTitle),
prompt: l10n.t(LocalizationKey.commandsTemplateGenerateInputPrompt),
placeHolder: l10n.t(LocalizationKey.commandsTemplateGenerateInputPlaceholder),
ignoreFocusOut: true
});
if (!titleValue) {
Notifications.warning(`You did not specify a template title.`);
Notifications.warning(l10n.t(LocalizationKey.commandsTemplateGenerateNoTitleWarning));
return;
}
const keepContents = await vscode.window.showQuickPick(['yes', 'no'], {
title: `Keep contents`,
canPickMany: false,
placeHolder: `Do you want to keep the contents for the template?`,
ignoreFocusOut: true
});
const keepContents = await vscode.window.showQuickPick(
[l10n.t(LocalizationKey.commonYes), l10n.t(LocalizationKey.commonNo)],
{
title: l10n.t(LocalizationKey.commandsTemplateGenerateKeepContentsTitle),
placeHolder: l10n.t(LocalizationKey.commandsTemplateGenerateKeepContentsPlaceholder),
canPickMany: false,
ignoreFocusOut: true
}
);
if (!keepContents) {
Notifications.warning(
`You did not pick any of the options for keeping the template its content.`
l10n.t(LocalizationKey.commandsTemplateGenerateKeepContentsNoOptionWarning)
);
return;
}
@@ -60,14 +65,16 @@ export class Template {
const templatePath = Project.templatePath();
if (templatePath) {
const fileContents = ArticleHelper.stringifyFrontMatter(
keepContents === 'no' ? '' : clonedArticle.content,
keepContents === l10n.t(LocalizationKey.commonNo) ? '' : clonedArticle.content,
clonedArticle.data
);
const templateFile = path.join(templatePath.fsPath, `${titleValue}.${fileType}`);
await writeFileAsync(templateFile, fileContents, { encoding: 'utf-8' });
Notifications.info(`Template created and is now available in your ${folder} folder.`);
Notifications.info(
l10n.t(LocalizationKey.commandsTemplateGenerateKeepContentsSuccess, folder)
);
}
}
}
@@ -79,7 +86,7 @@ export class Template {
const folder = Settings.get<string>(SETTING_TEMPLATES_FOLDER);
if (!folder) {
Notifications.warning(`No templates found.`);
Notifications.warning(l10n.t(LocalizationKey.commandsTemplateGetTemplatesWarning));
return;
}
@@ -96,7 +103,7 @@ export class Template {
const contentTypes = ContentType.getAll();
if (!folderPath) {
Notifications.warning(`Incorrect project folder path retrieved.`);
Notifications.warning(l10n.t(LocalizationKey.commandsTemplateCreateFolderPathWarning));
return;
}
+27 -1
View File
@@ -1,8 +1,10 @@
import { SETTING_GLOBAL_NOTIFICATIONS_DISABLED } from './../constants/settings';
import { window } from 'vscode';
import { EXTENSION_NAME, SETTING_GLOBAL_NOTIFICATIONS } from '../constants';
import { COMMAND_NAME, EXTENSION_NAME, SETTING_GLOBAL_NOTIFICATIONS } from '../constants';
import { Logger } from './Logger';
import { Settings } from './SettingsHelper';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
type NotificationType = 'INFO' | 'WARNING' | 'ERROR' | 'ERROR_ONCE';
@@ -57,6 +59,30 @@ export class Notifications {
return Promise.resolve(undefined);
}
/**
* Show an error notification to the user with a link to the output channel
* @param message
* @param items
* @returns
*/
public static errorWithOutput(message: string, ...items: any): Thenable<string | undefined> {
Logger.info(`${EXTENSION_NAME}: ${message}`, 'ERROR');
if (this.shouldShow('ERROR')) {
return window.showErrorMessage(
`${EXTENSION_NAME}: ${message} ${l10n.t(
LocalizationKey.notificationsOutputChannelDescription,
`[${l10n.t(LocalizationKey.notificationsOutputChannelLink)}](command:${
COMMAND_NAME.showOutputChannel
})`
)}`,
...items
);
}
return Promise.resolve(undefined);
}
/**
* Show an error notification to the user only once
* @param message
+140
View File
@@ -115,6 +115,26 @@ export enum LocalizationKey {
* No results
*/
commonNoResults = 'common.noResults',
/**
* Sorry, something went wrong.
*/
commonError = 'common.error',
/**
* yes
*/
commonYes = 'common.yes',
/**
* no
*/
commonNo = 'common.no',
/**
* output window
*/
notificationsOutputChannelLink = 'notifications.outputChannel.link',
/**
* Check the {0} for more details.
*/
notificationsOutputChannelDescription = 'notifications.outputChannel.description',
/**
* Common
*/
@@ -1552,6 +1572,126 @@ export enum LocalizationKey {
* Create folder
*/
commandsFoldersGetNotificationErrorCreateAction = 'commands.folders.get.notificationError.create.action',
/**
* Preview: {0}
*/
commandsPreviewPanelTitle = 'commands.preview.panel.title',
/**
* Select the folder of the article to preview
*/
commandsPreviewAskUserToPickFolderTitle = 'commands.preview.askUserToPickFolder.title',
/**
* Project initialized successfully.
*/
commandsProjectInitializeSuccess = 'commands.project.initialize.success',
/**
* To which project do you want to switch?
*/
commandsProjectSwitchProjectTitle = 'commands.project.switchProject.title',
/**
* Sample template created.
*/
commandsProjectCreateSampleTemplateInfo = 'commands.project.createSampleTemplate.info',
/**
* Insert the value of the {0} that you want to add to your configuration.
*/
commandsSettingsCreateInputPrompt = 'commands.settings.create.input.prompt',
/**
* Name of the {0}
*/
commandsSettingsCreateInputPlaceholder = 'commands.settings.create.input.placeholder',
/**
* The provided {0} already exists.
*/
commandsSettingsCreateWarning = 'commands.settings.create.warning',
/**
* Do you want to add the new {0} to the page?
*/
commandsSettingsCreateQuickPickPlaceholder = 'commands.settings.create.quickPick.placeholder',
/**
* {0}: exporting tags and categories
*/
commandsSettingsExportProgressTitle = 'commands.settings.export.progress.title',
/**
* Export completed. Tags: {0} - Categories: {1}.
*/
commandsSettingsExportProgressSuccess = 'commands.settings.export.progress.success',
/**
* Remap
*/
commandsSettingsRemapQuickpickTitle = 'commands.settings.remap.quickpick.title',
/**
* What do you want to remap?
*/
commandsSettingsRemapQuickpickPlaceholder = 'commands.settings.remap.quickpick.placeholder',
/**
* No {0} configured.
*/
commandsSettingsRemapNoTaxonomyWarning = 'commands.settings.remap.noTaxonomy.warning',
/**
* Select your {0} to insert.
*/
commandsSettingsRemapSelectTaxonomyPlaceholder = 'commands.settings.remap.selectTaxonomy.placeholder',
/**
* Specify the value of the {0} with which you want to remap "{1}". Leave the input <blank> if you want to remove the {0} from all articles.
*/
commandsSettingsRemapNewOptionInputPrompt = 'commands.settings.remap.newOption.input.prompt',
/**
* Name of the {0}
*/
commandsSettingsRemapNewOptionInputPlaceholder = 'commands.settings.remap.newOption.input.placeholder',
/**
* Delete {0} {1}?
*/
commandsSettingsRemapDeletePlaceholder = 'commands.settings.remap.delete.placeholder',
/**
* The {0} field is required. Please define a value for the field.
*/
commandsStatusListenerVerifyRequiredFieldsDiagnosticEmptyField = 'commands.statusListener.verifyRequiredFields.diagnostic.emptyField',
/**
* The following fields are required to contain a value: {0}
*/
commandsStatusListenerVerifyRequiredFieldsNotificationError = 'commands.statusListener.verifyRequiredFields.notification.error',
/**
* Template title
*/
commandsTemplateGenerateInputTitle = 'commands.template.generate.input.title',
/**
* Which name would you like to give your template?
*/
commandsTemplateGenerateInputPrompt = 'commands.template.generate.input.prompt',
/**
* article
*/
commandsTemplateGenerateInputPlaceholder = 'commands.template.generate.input.placeholder',
/**
* You did not specify a template title.
*/
commandsTemplateGenerateNoTitleWarning = 'commands.template.generate.noTitle.warning',
/**
* Keep content
*/
commandsTemplateGenerateKeepContentsTitle = 'commands.template.generate.keepContents.title',
/**
* Do you want to keep the contents for the template?
*/
commandsTemplateGenerateKeepContentsPlaceholder = 'commands.template.generate.keepContents.placeholder',
/**
* You did not pick any of the options for keeping the template its content.
*/
commandsTemplateGenerateKeepContentsNoOptionWarning = 'commands.template.generate.keepContents.noOption.warning',
/**
* Template created and is now available in your {0} folder.
*/
commandsTemplateGenerateKeepContentsSuccess = 'commands.template.generate.keepContents.success',
/**
* No templates found.
*/
commandsTemplateGetTemplatesWarning = 'commands.template.getTemplates.warning',
/**
* Incorrect project folder path retrieved.
*/
commandsTemplateCreateFolderPathWarning = 'commands.template.create.folderPath.warning',
/**
* Template files copied.
*/