From 39ad0e034e851d9c982460c908023b29df29e771 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Mon, 6 Nov 2023 13:26:45 -0800 Subject: [PATCH] Localization updates --- l10n/bundle.l10n.json | 82 +++++++ src/commands/Template.ts | 18 +- src/commands/Wysiwyg.ts | 50 ++--- src/helpers/ArticleHelper.ts | 26 ++- src/helpers/ContentType.ts | 102 ++++++--- src/helpers/CustomScript.ts | 40 +++- src/helpers/DataFileHelper.ts | 12 +- src/helpers/Extension.ts | 55 +++-- src/helpers/MediaHelpers.ts | 28 ++- src/localization/localization.enum.ts | 300 ++++++++++++++++++++++++++ 10 files changed, 599 insertions(+), 114 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index c6fad772..e8f22c9b 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -31,6 +31,7 @@ "common.error": "Sorry, something went wrong.", "common.yes": "yes", "common.no": "no", + "common.openSettings": "Open settings", "notifications.outputChannel.link": "output window", "notifications.outputChannel.description": "Check the {0} for more details.", @@ -528,6 +529,87 @@ "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.", + "commands.template.create.noTemplates.warning": "No templates found.", + "commands.template.create.selectTemplate.title": "Select a template", + "commands.template.create.selectTemplate.placeholder": "Select the content template to use", + "commands.template.create.selectTemplate.noTemplate.warning": "No template selected.", + "commands.template.create.selectTemplate.notFound.warning": "Content template could not be found.", + "commands.template.create.success": "Your new content is now available.", + + "commands.wysiwyg.command.unorderedList.label": "Unordered list", + "commands.wysiwyg.command.unorderedList.detail": "Add an unordered list", + "commands.wysiwyg.command.orderedList.label": "Ordered list", + "commands.wysiwyg.command.orderedList.detail": "Add an ordered list", + "commands.wysiwyg.command.taskList.label": "Task list", + "commands.wysiwyg.command.taskList.detail": "Add a task list", + "commands.wysiwyg.command.code.label": "Code", + "commands.wysiwyg.command.code.detail": "Add inline code snippet", + "commands.wysiwyg.command.codeblock.label": "Code block", + "commands.wysiwyg.command.codeblock.detail": "Add a code block", + "commands.wysiwyg.command.blockquote.label": "Blockquote", + "commands.wysiwyg.command.blockquote.detail": "Add a blockquote", + "commands.wysiwyg.command.strikethrough.label": "Strikethrough", + "commands.wysiwyg.command.strikethrough.detail": "Add strikethrough text", + "commands.wysiwyg.quickPick.title": "WYSIWYG Options", + "commands.wysiwyg.quickPick.placeholder": "Which type of markup would you like to insert?", + "commands.wysiwyg.addHyperlink.hyperlinkInput.title": "WYSIWYG Hyperlink", + "commands.wysiwyg.addHyperlink.hyperlinkInput.prompt": "Enter the URL", + "commands.wysiwyg.addHyperlink.textInput.title": "WYSIWYG Text", + "commands.wysiwyg.addHyperlink.textInput.prompt": "Enter the text for the hyperlink", + "commands.wysiwyg.insertText.heading.input.title": "Heading level", + "commands.wysiwyg.insertText.heading.input.placeholder": "Which heading level do you want to insert?", + + "helpers.articleHelper.createContent.pageBundle.error": "A page bundle with the name {0} already exists in {1}.", + "helpers.articleHelper.createContent.contentExists.warning": "Content with the title already exists. Please specify a new title.", + "helpers.articleHelper.processCustomPlaceholders.placeholder.error": "Error while processing the {0} placeholder.", + "helpers.articleHelper.parseFile.diagnostic.error": "Error parsing the front matter of {0}.", + + "helpers.contentType.generate.noFrontMatter.error": "No front matter data found to generate a content type.", + "helpers.contentType.generate.override.quickPick.title": "Override the default content type", + "helpers.contentType.generate.override.quickPick.placeholder": "Do you want to overwrite the default content type configuration with the fields used in the current field?", + "helpers.contentType.generate.contentTypeInput.title": "Generate Content Type", + "helpers.contentType.generate.contentTypeInput.prompt": "Enter the name of the content type to generate", + "helpers.contentType.generate.contentTypeInput.validation.enterName": "Please enter a name for the content type.", + "helpers.contentType.generate.contentTypeInput.validation.nameExists": "A content type with this name already exists.", + "helpers.contentType.generate.noContentTypeName.warning": "You didn't specify a name for the content type.", + "helpers.contentType.generate.pageBundle.quickPick.title": "Use as a page bundle", + "helpers.contentType.generate.pageBundle.quickPick.placeHolder": "Do you want to use this content type as a page bundle?", + "helpers.contentType.generate.updated.success": "Content type {0} has been updated.", + "helpers.contentType.generate.generated.success": "Content type {0} has been generated.", + "helpers.contentType.addMissingFields.noFrontMatter.warning": "No front matter data found to add missing fields.", + "helpers.contentType.addMissingFields.updated.success": "Content type {0} has been updated.", + "helpers.contentType.setContentType.noFrontMatter.warning": "No front matter data found to set the content type.", + "helpers.contentType.setContentType.quickPick.title": "Select the content type", + "helpers.contentType.setContentType.quickPick.placeholder": "Which content type would you like to use?", + "helpers.contentType.create.progress.title": "{0}: Creating content...", + "helpers.contentType.create.success": "Your new content has been created.", + "helpers.contentType.verify.warning": "The content type actions are not available in this mode.", + + "helpers.customScript.executing": "Executing: {0}", + "helpers.customScript.singleRun.article.warning": "{0}: Article couldn't be retrieved.", + "helpers.customScript.bulkRun.noFiles.warning": "{0}: No files found", + "helpers.customScript.runMediaScript.noFolder.warning": "{0}: There was no folder or media path specified.", + "helpers.customScript.showOutput.frontMatter.success": "{0}: front matter updated.", + "helpers.customScript.showOutput.copyOutput.action": "Copy output", + "helpers.customScript.showOutput.success": "{0}: Executed your custom script.", + "helpers.customScript.validateCommand.error": "Invalid command: {0}", + + "helpers.dataFileHelper.process.error": "Something went wrong while processing the data file.", + + "helpers.extension.getVersion.changelog": "Check the changelog", + "helpers.extension.getVersion.starIt": "Give it a ⭐️", + "helpers.extension.getVersion.update.notification": "{0} has been updated to v{1} — check out what's new!", + "helpers.extension.migrateSettings.deprecated.warning": "The \"{0}\" and \"{1}\" settings have been deprecated. Please use the \"isPublishDate\" and \"isModifiedDate\" datetime field properties instead.", + "helpers.extension.migrateSettings.deprecated.warning.hide": "Hide", + "helpers.extension.migrateSettings.deprecated.warning.seeGuide": "See migration guide", + "helpers.extension.migrateSettings.templates.quickPick.title": "{0} - Templates", + "helpers.extension.migrateSettings.templates.quickPick.placeholder": "Do you want to keep on using the template functionality?", + "helpers.extension.checkIfExtensionCanRun.warning": "Front Matter BETA cannot be used while the stable version is installed. Please ensure that you have only over version installed.", + + "helpers.mediaHelper.saveFile.folder.error": "We couldn't find your selected folder.", + "helpers.mediaHelper.saveFile.file.uploaded.success": "File {0} uploaded to: {1}", + "helpers.mediaHelper.saveFile.file.uploaded.failed": "Sorry, something went wrong uploading {0}", + "helpers.mediaHelper.deleteFile.file.deletion.failed": "Sorry, something went wrong deleting {0}", "listeners.dashboard.settingsListener.triggerTemplate.notification": "Template files copied." } \ No newline at end of file diff --git a/src/commands/Template.ts b/src/commands/Template.ts index 652fb4a8..3ee00cdc 100644 --- a/src/commands/Template.ts +++ b/src/commands/Template.ts @@ -109,20 +109,22 @@ export class Template { const templates = await Template.getTemplates(); if (!templates || templates.length === 0) { - Notifications.warning(`No templates found.`); + Notifications.warning(l10n.t(LocalizationKey.commandsTemplateCreateNoTemplatesWarning)); return; } const selectedTemplate = await vscode.window.showQuickPick( templates.map((t) => path.basename(t.fsPath)), { - title: `Select a template`, - placeHolder: `Select the content template to use`, + title: l10n.t(LocalizationKey.commandsTemplateCreateSelectTemplateTitle), + placeHolder: l10n.t(LocalizationKey.commandsTemplateCreateSelectTemplatePlaceholder), ignoreFocusOut: true } ); if (!selectedTemplate) { - Notifications.warning(`No template selected.`); + Notifications.warning( + l10n.t(LocalizationKey.commandsTemplateCreateSelectTemplateNoTemplateWarning) + ); return; } @@ -134,7 +136,9 @@ export class Template { // Start the template read const template = templates.find((t) => t.fsPath.endsWith(selectedTemplate)); if (!template) { - Notifications.warning(`Content template could not be found.`); + Notifications.warning( + l10n.t(LocalizationKey.commandsTemplateCreateSelectTemplateNotFoundWarning) + ); return; } @@ -161,7 +165,7 @@ export class Template { // Update the properties inside the template let frontMatter = await ArticleHelper.getFrontMatterByPath(newFilePath); if (!frontMatter) { - Notifications.warning(`Something failed when retrieving the newly created file.`); + Notifications.warning(l10n.t(LocalizationKey.commonError)); return; } @@ -192,7 +196,7 @@ export class Template { vscode.window.showTextDocument(txtDoc); } - Notifications.info(`Your new content has been created.`); + Notifications.info(l10n.t(LocalizationKey.commandsTemplateCreateSuccess)); Telemetry.send(TelemetryEvent.createContentFromTemplate); diff --git a/src/commands/Wysiwyg.ts b/src/commands/Wysiwyg.ts index 1af18107..2c2fb72a 100644 --- a/src/commands/Wysiwyg.ts +++ b/src/commands/Wysiwyg.ts @@ -1,6 +1,8 @@ import { commands, window, Selection, QuickPickItem, TextEditor } from 'vscode'; import { COMMAND_NAME, CONTEXT, SETTING_CONTENT_WYSIWYG } from '../constants'; import { Settings } from '../helpers'; +import * as l10n from '@vscode/l10n'; +import { LocalizationKey } from '../localization'; enum MarkupType { bold = 1, @@ -81,45 +83,45 @@ export class Wysiwyg { commands.registerCommand(COMMAND_NAME.options, async () => { const qpItems: QuickPickItem[] = [ { - label: '$(list-unordered) Unordered list', - detail: 'Add an unordered list', + label: `$(list-unordered) ${LocalizationKey.commandsWysiwygCommandUnorderedListLabel}`, + detail: LocalizationKey.commandsWysiwygCommandUnorderedListDetail, alwaysShow: true }, { - label: '$(list-ordered) Ordered list', - detail: 'Add an ordered list', + label: `$(list-ordered) ${LocalizationKey.commandsWysiwygCommandOrderedListLabel}`, + detail: LocalizationKey.commandsWysiwygCommandOrderedListDetail, alwaysShow: true }, { - label: '$(tasklist) Task list', - detail: 'Add a task list', + label: `$(tasklist) ${LocalizationKey.commandsWysiwygCommandTaskListLabel}`, + detail: LocalizationKey.commandsWysiwygCommandTaskListDetail, alwaysShow: true }, { - label: '$(code) Code', - detail: 'Add inline code snippet', + label: `$(code) ${LocalizationKey.commandsWysiwygCommandCodeLabel}`, + detail: LocalizationKey.commandsWysiwygCommandCodeDetail, alwaysShow: true }, { - label: '$(symbol-namespace) Code block', - detail: 'Add a code block', + label: `$(symbol-namespace) ${LocalizationKey.commandsWysiwygCommandCodeblockLabel}`, + detail: LocalizationKey.commandsWysiwygCommandCodeblockDetail, alwaysShow: true }, { - label: '$(quote) Blockquote', - detail: 'Add a blockquote', + label: `$(quote) ${LocalizationKey.commandsWysiwygCommandBlockquoteLabel}`, + detail: LocalizationKey.commandsWysiwygCommandBlockquoteDetail, alwaysShow: true }, { - label: '$(symbol-text) Strikethrough', - detail: 'Add a strikethrough', + label: `$(symbol-text) ${LocalizationKey.commandsWysiwygCommandStrikethroughLabel}`, + detail: LocalizationKey.commandsWysiwygCommandStrikethroughDetail, alwaysShow: true } ]; const option = await window.showQuickPick([...qpItems], { - title: 'WYSIWYG Options', - placeHolder: 'Which type of markup would you like to insert?', + title: l10n.t(LocalizationKey.commandsWysiwygQuickPickTitle), + placeHolder: l10n.t(LocalizationKey.commandsWysiwygQuickPickPlaceholder), canPickMany: false, ignoreFocusOut: true }); @@ -209,17 +211,17 @@ export class Wysiwyg { const linkText = hasTextSelection ? editor.document.getText(selection) : ''; const link = await window.showInputBox({ - title: 'WYSIWYG Hyperlink', - placeHolder: 'Enter the URL', - prompt: 'Enter the URL', + title: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputTitle), + placeHolder: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputPrompt), + prompt: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputPrompt), value: linkText, ignoreFocusOut: true }); const text = await window.showInputBox({ - title: 'WYSIWYG Text', - prompt: 'Enter the text for the hyperlink', - placeHolder: 'Enter the text for the hyperlink', + title: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkTextInputTitle), + prompt: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkTextInputPrompt), + placeHolder: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkTextInputPrompt), value: linkText, ignoreFocusOut: true }); @@ -278,9 +280,9 @@ export class Wysiwyg { const headingLvl = await window.showQuickPick( ['Heading 1', 'Heading 2', 'Heading 3', 'Heading 4', 'Heading 5', 'Heading 6'], { - title: 'Heading Level', + title: l10n.t(LocalizationKey.commandsWysiwygInsertTextHeadingInputTitle), + placeHolder: l10n.t(LocalizationKey.commandsWysiwygInsertTextHeadingInputPlaceholder), canPickMany: false, - placeHolder: 'Which heading level do you want to insert?', ignoreFocusOut: true } ); diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts index e4764468..be41208b 100644 --- a/src/helpers/ArticleHelper.ts +++ b/src/helpers/ArticleHelper.ts @@ -42,6 +42,8 @@ import { CustomScript } from './CustomScript'; import { Folders } from '../commands/Folders'; import { existsAsync, readFileAsync } from '../utils'; import { mkdirAsync } from '../utils/mkdirAsync'; +import * as l10n from '@vscode/l10n'; +import { LocalizationKey } from '../localization'; export class ArticleHelper { private static notifiedFiles: string[] = []; @@ -442,7 +444,11 @@ export class ArticleHelper { const newFolder = join(folderPath, sanitizedName); if (await existsAsync(newFolder)) { Notifications.error( - `A page bundle with the name ${sanitizedName} already exists in ${folderPath}` + l10n.t( + LocalizationKey.helpersArticleHelperCreateContentPageBundleError, + sanitizedName, + folderPath + ) ); return; } else { @@ -466,7 +472,9 @@ export class ArticleHelper { await mkdirAsync(folderPath, { recursive: true }); if (await existsAsync(newFilePath)) { - Notifications.warning(`Content with the title already exists. Please specify a new title.`); + Notifications.warning( + l10n.t(LocalizationKey.helpersArticleHelperCreateContentContentExistsWarning) + ); return; } } @@ -597,7 +605,12 @@ export class ArticleHelper { value = value.replace(regex, updatedValue); } } catch (e) { - Notifications.error(`Error while processing the ${placeholder.id} placeholder`); + Notifications.error( + l10n.t( + LocalizationKey.helpersArticleHelperProcessCustomPlaceholdersPlaceholderError, + placeholder.id + ) + ); Logger.error((e as Error).message); value = DefaultFieldValues.faultyCustomPlaceholder; @@ -795,9 +808,10 @@ export class ArticleHelper { Extension.getInstance().diagnosticCollection.set(editor.document.uri, [ { severity: DiagnosticSeverity.Error, - message: `${ - error.name ? `${error.name}: ` : '' - }Error parsing the front matter of ${fileName}`, + message: `${error.name ? `${error.name}: ` : ''}${l10n.t( + LocalizationKey.helpersArticleHelperParseFileDiagnosticError, + fileName + )}`, range: fmRange } ]); diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts index 7f08999a..6b920306 100644 --- a/src/helpers/ContentType.ts +++ b/src/helpers/ContentType.ts @@ -3,6 +3,7 @@ import { PagesListener } from './../listeners/dashboard'; import { ArticleHelper, CustomScript, Settings } from '.'; import { DefaultFieldValues, + EXTENSION_NAME, FEATURE_FLAG, SETTING_CONTENT_DRAFT_FIELD, SETTING_DATE_FORMAT, @@ -29,6 +30,8 @@ import { processKnownPlaceholders } from './PlaceholderHelper'; import { basename } from 'path'; import { ParsedFrontMatter } from '../parsers'; import { encodeEmoji, existsAsync, writeFileAsync } from '../utils'; +import * as l10n from '@vscode/l10n'; +import { LocalizationKey } from '../localization'; export class ContentType { /** @@ -173,30 +176,34 @@ export class ContentType { const filePath = editor?.document.uri.fsPath; if (!content || !content.data) { - Notifications.warning(`No front matter data found to generate a content type.`); + Notifications.warning(l10n.t(LocalizationKey.helpersContentTypeGenerateNoFrontMatterError)); return; } - const override = await window.showQuickPick(['Yes', 'No'], { - title: 'Override default content type', - placeHolder: - 'Do you want to overwrite the default content type configuration with the fields used in the current field?', - ignoreFocusOut: true - }); - const overrideBool = override === 'Yes'; + const override = await window.showQuickPick( + [l10n.t(LocalizationKey.commonYes), l10n.t(LocalizationKey.commonNo)], + { + title: l10n.t(LocalizationKey.helpersContentTypeGenerateOverrideQuickPickTitle), + placeHolder: l10n.t(LocalizationKey.helpersContentTypeGenerateOverrideQuickPickPlaceholder), + ignoreFocusOut: true + } + ); + const overrideBool = override === l10n.t(LocalizationKey.commonYes); let contentTypeName: string | undefined = `default`; // Ask for the new content type name if (!overrideBool) { contentTypeName = await window.showInputBox({ - title: 'Generate Content Type', - placeHolder: 'Enter the name of the content type to generate', - prompt: 'Enter the name of the content type to generate', + title: l10n.t(LocalizationKey.helpersContentTypeGenerateContentTypeInputTitle), + placeHolder: l10n.t(LocalizationKey.helpersContentTypeGenerateContentTypeInputPrompt), + prompt: l10n.t(LocalizationKey.helpersContentTypeGenerateContentTypeInputPrompt), ignoreFocusOut: true, validateInput: (value: string) => { if (!value) { - return 'Please enter a name for the content type'; + return l10n.t( + LocalizationKey.helpersContentTypeGenerateContentTypeInputValidationEnterName + ); } const contentTypes = ContentType.getAll(); @@ -204,7 +211,9 @@ export class ContentType { contentTypes && contentTypes.find((ct) => ct.name.toLowerCase() === value.toLowerCase()) ) { - return 'A content type with this name already exists'; + return l10n.t( + LocalizationKey.helpersContentTypeGenerateContentTypeInputValidationNameExists + ); } return null; @@ -212,7 +221,9 @@ export class ContentType { }); if (!contentTypeName) { - Notifications.warning(`You didn't specify a name for the content type.`); + Notifications.warning( + l10n.t(LocalizationKey.helpersContentTypeGenerateNoContentTypeNameWarning) + ); return; } } @@ -221,12 +232,17 @@ export class ContentType { let pageBundle = false; const fileName = filePath ? basename(filePath) : undefined; if (fileName?.startsWith(`index.`)) { - const pageBundleAnswer = await window.showQuickPick(['Yes', 'No'], { - title: 'Use as page bundle', - placeHolder: 'Do you want to use this content type as a page bundle?', - ignoreFocusOut: true - }); - pageBundle = pageBundleAnswer === 'Yes'; + const pageBundleAnswer = await window.showQuickPick( + [l10n.t(LocalizationKey.commonYes), l10n.t(LocalizationKey.commonNo)], + { + title: l10n.t(LocalizationKey.helpersContentTypeGeneratePageBundleQuickPickTitle), + placeHolder: l10n.t( + LocalizationKey.helpersContentTypeGeneratePageBundleQuickPickPlaceHolder + ), + ignoreFocusOut: true + } + ); + pageBundle = pageBundleAnswer === l10n.t(LocalizationKey.commonYes); } const fields = ContentType.generateFields(content.data); @@ -256,11 +272,19 @@ export class ContentType { const configPath = await Settings.projectConfigPath(); const notificationAction = await Notifications.info( - `Content type ${contentTypeName} has been ${overrideBool ? `updated` : `generated`}.`, - configPath && (await existsAsync(configPath)) ? `Open settings` : undefined + overrideBool + ? l10n.t(LocalizationKey.helpersContentTypeGenerateUpdatedSuccess) + : l10n.t(LocalizationKey.helpersContentTypeGenerateGeneratedSuccess), + configPath && (await existsAsync(configPath)) + ? l10n.t(LocalizationKey.commonOpenSettings) + : undefined ); - if (notificationAction === 'Open settings' && configPath && (await existsAsync(configPath))) { + if ( + notificationAction === l10n.t(LocalizationKey.commonOpenSettings) && + configPath && + (await existsAsync(configPath)) + ) { commands.executeCommand('vscode.open', Uri.file(configPath)); } } @@ -278,7 +302,9 @@ export class ContentType { const content = ArticleHelper.getCurrent(); if (!content || !content.data) { - Notifications.warning(`No front matter data found to add missing fields.`); + Notifications.warning( + l10n.t(LocalizationKey.helpersContentTypeAddMissingFieldsNoFrontMatterWarning) + ); return; } @@ -293,11 +319,17 @@ export class ContentType { const configPath = await Settings.projectConfigPath(); const notificationAction = await Notifications.info( - `Content type ${contentType.name} has been updated.`, - configPath && (await existsAsync(configPath)) ? `Open settings` : undefined + l10n.t(LocalizationKey.helpersContentTypeAddMissingFieldsUpdatedSuccess, contentType.name), + configPath && (await existsAsync(configPath)) + ? l10n.t(LocalizationKey.commonOpenSettings) + : undefined ); - if (notificationAction === 'Open settings' && configPath && (await existsAsync(configPath))) { + if ( + notificationAction === l10n.t(LocalizationKey.commonOpenSettings) && + configPath && + (await existsAsync(configPath)) + ) { commands.executeCommand('vscode.open', Uri.file(configPath)); } } @@ -316,16 +348,18 @@ export class ContentType { const contentTypes = ContentType.getAll() || []; if (!content || !content.data) { - Notifications.warning(`No front matter data found to set the content type.`); + Notifications.warning( + l10n.t(LocalizationKey.helpersContentTypeSetContentTypeNoFrontMatterWarning) + ); return; } const ctAnswer = await window.showQuickPick( contentTypes.map((ct) => ct.name), { - title: 'Select the content type', - ignoreFocusOut: true, - placeHolder: 'Which content type would you like to use?' + title: l10n.t(LocalizationKey.helpersContentTypeSetContentTypeQuickPickTitle), + placeHolder: l10n.t(LocalizationKey.helpersContentTypeSetContentTypeQuickPickPlaceholder), + ignoreFocusOut: true } ); @@ -776,7 +810,7 @@ export class ContentType { window.withProgress( { location: ProgressLocation.Notification, - title: 'Front Matter: Creating content...', + title: l10n.t(LocalizationKey.helpersContentTypeCreateProgressTitle, EXTENSION_NAME), cancellable: false }, async () => { @@ -851,7 +885,7 @@ export class ContentType { await commands.executeCommand('vscode.open', Uri.file(newFilePath)); - Notifications.info(`Your new content has been created.`); + Notifications.info(l10n.t(LocalizationKey.helpersContentTypeCreateSuccess)); Telemetry.send(TelemetryEvent.createContentFromContentType); @@ -992,7 +1026,7 @@ export class ContentType { private static async verify() { const hasFeature = await ModeListener.hasFeature(FEATURE_FLAG.panel.contentType); if (!hasFeature) { - Notifications.warning(`The content type actions are not available in this mode.`); + Notifications.warning(l10n.t(LocalizationKey.helpersContentTypeVerifyWarning)); return false; } diff --git a/src/helpers/CustomScript.ts b/src/helpers/CustomScript.ts index c18566a1..f9f747d4 100644 --- a/src/helpers/CustomScript.ts +++ b/src/helpers/CustomScript.ts @@ -15,6 +15,8 @@ import { ParsedFrontMatter } from '../parsers'; import { TelemetryEvent } from '../constants/TelemetryEvent'; import { SETTING_CUSTOM_SCRIPTS } from '../constants'; import { existsAsync } from '../utils'; +import * as l10n from '@vscode/l10n'; +import { LocalizationKey } from '../localization'; export class CustomScript { /** @@ -101,7 +103,9 @@ export class CustomScript { } ); } else { - Notifications.warning(`${script.title}: Article couldn't be retrieved.`); + Notifications.warning( + l10n.t(LocalizationKey.helpersCustomScriptSingleRunArticleWarning, script.title) + ); } } @@ -115,7 +119,9 @@ export class CustomScript { const folders = await Folders.getInfo(); if (!folders || folders.length === 0) { - Notifications.warning(`${script.title}: No files found.`); + Notifications.warning( + l10n.t(LocalizationKey.helpersCustomScriptBulkRunNoFilesWarning, script.title) + ); return; } @@ -124,7 +130,7 @@ export class CustomScript { window.withProgress( { location: ProgressLocation.Notification, - title: `Executing: ${script.title}`, + title: l10n.t(LocalizationKey.helpersCustomScriptExecuting, script.title), cancellable: false }, async (progress, token) => { @@ -169,7 +175,9 @@ export class CustomScript { script: ICustomScript ): Promise { if (!path) { - Notifications.error(`${script.title}: There was no folder or media path specified.`); + Notifications.error( + l10n.t(LocalizationKey.helpersCustomScriptRunMediaScriptNoFolderWarning, script.title) + ); return; } @@ -177,7 +185,7 @@ export class CustomScript { window.withProgress( { location: ProgressLocation.Notification, - title: `Executing: ${script.title}`, + title: l10n.t(LocalizationKey.helpersCustomScriptExecuting, script.title), cancellable: false }, async () => { @@ -286,11 +294,15 @@ export class CustomScript { } else if (editor) { await ArticleHelper.update(editor, article); } else { + Logger.error(`Couldn't update article.`); throw new Error(`Couldn't update article.`); } - Notifications.info(`${script.title}: front matter updated.`); + Notifications.info( + l10n.t(LocalizationKey.helpersCustomScriptShowOutputFrontMatterSuccess, script.title) + ); } } else { + Logger.error(`No frontmatter found.`); throw new Error(`No frontmatter found.`); } } catch (error) { @@ -298,16 +310,21 @@ export class CustomScript { ContentProvider.show(output, script.title, script.outputType || 'text'); } else { window - .showInformationMessage(`${script.title}: ${output}`, 'Copy output') + .showInformationMessage( + `${script.title}: ${output}`, + l10n.t(LocalizationKey.helpersCustomScriptShowOutputCopyOutputAction) + ) .then((value) => { - if (value === 'Copy output') { + if (value === l10n.t(LocalizationKey.helpersCustomScriptShowOutputCopyOutputAction)) { vscodeEnv.clipboard.writeText(output); } }); } } } else { - Notifications.info(`${script.title}: Executed your custom script.`); + Notifications.info( + l10n.t(LocalizationKey.helpersCustomScriptShowOutputSuccess, script.title) + ); } } @@ -360,6 +377,7 @@ export class CustomScript { } if (!(await existsAsync(scriptPath))) { + Logger.error(`Script not found: ${scriptPath}`); throw new Error(`Script not found: ${scriptPath}`); } @@ -368,7 +386,7 @@ export class CustomScript { } const fullScript = `${command} "${scriptPath}" ${args}`; - Logger.info(`Executing: ${fullScript}`); + Logger.info(l10n.t(LocalizationKey.helpersCustomScriptExecuting, fullScript)); const output: string = await CustomScript.executeScriptAsync(fullScript, wsPath); @@ -441,7 +459,7 @@ export class CustomScript { return true; } catch (e) { - Logger.error(`Invalid command: ${command}`); + Logger.error(l10n.t(LocalizationKey.helpersCustomScriptValidateCommandError, command)); return false; } } diff --git a/src/helpers/DataFileHelper.ts b/src/helpers/DataFileHelper.ts index d2961222..f23a1bcf 100644 --- a/src/helpers/DataFileHelper.ts +++ b/src/helpers/DataFileHelper.ts @@ -7,6 +7,8 @@ import { commands } from 'vscode'; import { COMMAND_NAME, SETTING_DATA_FILES } from '../constants'; import { Settings } from './SettingsHelper'; import { existsAsync, readFileAsync } from '../utils'; +import * as l10n from '@vscode/l10n'; +import { LocalizationKey } from '../localization'; export class DataFileHelper { /** @@ -60,15 +62,7 @@ export class DataFileHelper { } } catch (ex) { Logger.error(`DataFileHelper::process: ${(ex as Error).message}`); - const btnClick = await Notifications.error( - `Something went wrong while processing the data file. Check your file and output log for more information.`, - 'Open output' - ); - - if (btnClick && btnClick === 'Open output') { - commands.executeCommand(COMMAND_NAME.showOutputChannel); - } - + Notifications.errorWithOutput(l10n.t(LocalizationKey.helpersDataFileHelperProcessError)); return; } } diff --git a/src/helpers/Extension.ts b/src/helpers/Extension.ts index 8e6ad425..90d5eb72 100644 --- a/src/helpers/Extension.ts +++ b/src/helpers/Extension.ts @@ -33,6 +33,8 @@ import { Notifications } from './Notifications'; import { Settings } from './SettingsHelper'; import { TaxonomyHelper } from './TaxonomyHelper'; import { Cache } from '../commands/Cache'; +import * as l10n from '@vscode/l10n'; +import { LocalizationKey } from '../localization'; export class Extension { private static instance: Extension; @@ -72,8 +74,8 @@ export class Extension { } if (usedVersion !== installedVersion) { - const whatIsNewTitle = `Check the changelog`; - const githubTitle = `Give it a ⭐️`; + const whatIsNewTitle = l10n.t(LocalizationKey.helpersExtensionGetVersionChangelog); + const githubTitle = l10n.t(LocalizationKey.helpersExtensionGetVersionStarIt); const whatIsNew = { title: whatIsNewTitle, @@ -94,7 +96,11 @@ export class Extension { window .showInformationMessage( - `${EXTENSION_NAME} has been updated to v${installedVersion} — check out what's new!`, + l10n.t( + LocalizationKey.helpersExtensionGetVersionUpdateNotification, + EXTENSION_NAME, + installedVersion + ), starGitHub, whatIsNew ) @@ -215,11 +221,18 @@ export class Extension { modifiedField?.teamValue ) { Notifications.warning( - `The "${CONFIG_KEY}.${SETTING_DATE_FIELD}" and "${CONFIG_KEY}.${SETTING_MODIFIED_FIELD}" settings have been deprecated. Please use the "isPublishDate" and "isModifiedDate" datetime field properties instead.`, - 'Hide', - 'See migration guide' + l10n.t( + LocalizationKey.helpersExtensionMigrateSettingsDeprecatedWarning, + `${CONFIG_KEY}.${SETTING_DATE_FIELD}`, + `${CONFIG_KEY}.${SETTING_MODIFIED_FIELD}` + ), + l10n.t(LocalizationKey.helpersExtensionMigrateSettingsDeprecatedWarningHide), + l10n.t(LocalizationKey.helpersExtensionMigrateSettingsDeprecatedWarningSeeGuide) ).then(async (value) => { - if (value === 'See migration guide') { + if ( + value === + l10n.t(LocalizationKey.helpersExtensionMigrateSettingsDeprecatedWarningSeeGuide) + ) { const isProd = this.isProductionMode; commands.executeCommand( 'vscode.open', @@ -234,7 +247,9 @@ export class Extension { true, 'workspace' ); - } else if (value === 'Hide') { + } else if ( + value === l10n.t(LocalizationKey.helpersExtensionMigrateSettingsDeprecatedWarningHide) + ) { await Extension.getInstance().setState( ExtensionState.Updates.v7_0_0.dateFields, true, @@ -291,15 +306,23 @@ export class Extension { const templates = await Template.getTemplates(); if (templates && templates.length > 0) { - const answer = await window.showQuickPick(['Yes', 'No'], { - title: 'Front Matter - Templates', - placeHolder: 'Do you want to keep on using the template functionality?', - ignoreFocusOut: true - }); + const answer = await window.showQuickPick( + [l10n.t(LocalizationKey.commonYes), l10n.t(LocalizationKey.commonNo)], + { + title: l10n.t( + LocalizationKey.helpersExtensionMigrateSettingsTemplatesQuickPickTitle, + EXTENSION_NAME + ), + placeHolder: l10n.t( + LocalizationKey.helpersExtensionMigrateSettingsTemplatesQuickPickPlaceholder + ), + ignoreFocusOut: true + } + ); await Settings.update( SETTING_TEMPLATES_ENABLED, - answer?.toLocaleLowerCase() === 'yes', + answer?.toLocaleLowerCase() === l10n.t(LocalizationKey.commonYes), true ); } @@ -410,9 +433,7 @@ export class Extension { const mainVersionInstalled = extensions.getExtension(EXTENSION_ID); if (mainVersionInstalled) { - Notifications.error( - `Front Matter BETA cannot be used while the main version is installed. Please ensure that you have only over version installed.` - ); + Notifications.error(l10n.t(LocalizationKey.helpersExtensionCheckIfExtensionCanRunWarning)); return false; } } diff --git a/src/helpers/MediaHelpers.ts b/src/helpers/MediaHelpers.ts index 744c10b1..af83cfc0 100644 --- a/src/helpers/MediaHelpers.ts +++ b/src/helpers/MediaHelpers.ts @@ -30,6 +30,8 @@ import { MediaListener as DashboardMediaListener } from '../listeners/dashboard' import { ArticleHelper } from './ArticleHelper'; import { lookup } from 'mime-types'; import { existsAsync, readdirAsync, unlinkAsync, writeFileAsync } from '../utils'; +import * as l10n from '@vscode/l10n'; +import { LocalizationKey } from '../localization'; export class MediaHelpers { private static media: MediaInfo[] = []; @@ -308,7 +310,7 @@ export class MediaHelpers { } if (!(await existsAsync(absFolderPath))) { - Notifications.error(`We couldn't find your selected folder.`); + Notifications.error(l10n.t(LocalizationKey.helpersMediaHelperSaveFileFolderError)); return; } @@ -317,12 +319,22 @@ export class MediaHelpers { if (imgData) { await writeFileAsync(staticPath, imgData.data); - Notifications.info(`File ${fileName} uploaded to: ${folder}`); + Notifications.info( + l10n.t( + LocalizationKey.helpersMediaHelperSaveFileFileUploadedSuccess, + fileName, + folder || '' + ) + ); return true; } else { - Notifications.error(`Something went wrong uploading ${fileName}`); - throw new Error(`Something went wrong uploading ${fileName}`); + Notifications.error( + l10n.t(LocalizationKey.helpersMediaHelperSaveFileFileUploadedFailed, fileName) + ); + throw new Error( + l10n.t(LocalizationKey.helpersMediaHelperSaveFileFileUploadedFailed, fileName) + ); } } @@ -355,8 +367,12 @@ export class MediaHelpers { MediaHelpers.media = []; return true; } catch (err: any) { - Notifications.error(`Something went wrong deleting ${basename(file)}`); - throw new Error(`Something went wrong deleting ${basename(file)}`); + Notifications.error( + l10n.t(LocalizationKey.helpersMediaHelperDeleteFileFileDeletionFailed, basename(file)) + ); + throw new Error( + l10n.t(LocalizationKey.helpersMediaHelperDeleteFileFileDeletionFailed, basename(file)) + ); } } diff --git a/src/localization/localization.enum.ts b/src/localization/localization.enum.ts index d89137a5..937652e5 100644 --- a/src/localization/localization.enum.ts +++ b/src/localization/localization.enum.ts @@ -127,6 +127,10 @@ export enum LocalizationKey { * no */ commonNo = 'common.no', + /** + * Open settings + */ + commonOpenSettings = 'common.openSettings', /** * output window */ @@ -1692,6 +1696,302 @@ export enum LocalizationKey { * Incorrect project folder path retrieved. */ commandsTemplateCreateFolderPathWarning = 'commands.template.create.folderPath.warning', + /** + * No templates found. + */ + commandsTemplateCreateNoTemplatesWarning = 'commands.template.create.noTemplates.warning', + /** + * Select a template + */ + commandsTemplateCreateSelectTemplateTitle = 'commands.template.create.selectTemplate.title', + /** + * Select the content template to use + */ + commandsTemplateCreateSelectTemplatePlaceholder = 'commands.template.create.selectTemplate.placeholder', + /** + * No template selected. + */ + commandsTemplateCreateSelectTemplateNoTemplateWarning = 'commands.template.create.selectTemplate.noTemplate.warning', + /** + * Content template could not be found. + */ + commandsTemplateCreateSelectTemplateNotFoundWarning = 'commands.template.create.selectTemplate.notFound.warning', + /** + * Your new content is now available. + */ + commandsTemplateCreateSuccess = 'commands.template.create.success', + /** + * Unordered list + */ + commandsWysiwygCommandUnorderedListLabel = 'commands.wysiwyg.command.unorderedList.label', + /** + * Add an unordered list + */ + commandsWysiwygCommandUnorderedListDetail = 'commands.wysiwyg.command.unorderedList.detail', + /** + * Ordered list + */ + commandsWysiwygCommandOrderedListLabel = 'commands.wysiwyg.command.orderedList.label', + /** + * Add an ordered list + */ + commandsWysiwygCommandOrderedListDetail = 'commands.wysiwyg.command.orderedList.detail', + /** + * Task list + */ + commandsWysiwygCommandTaskListLabel = 'commands.wysiwyg.command.taskList.label', + /** + * Add a task list + */ + commandsWysiwygCommandTaskListDetail = 'commands.wysiwyg.command.taskList.detail', + /** + * Code + */ + commandsWysiwygCommandCodeLabel = 'commands.wysiwyg.command.code.label', + /** + * Add inline code snippet + */ + commandsWysiwygCommandCodeDetail = 'commands.wysiwyg.command.code.detail', + /** + * Code block + */ + commandsWysiwygCommandCodeblockLabel = 'commands.wysiwyg.command.codeblock.label', + /** + * Add a code block + */ + commandsWysiwygCommandCodeblockDetail = 'commands.wysiwyg.command.codeblock.detail', + /** + * Blockquote + */ + commandsWysiwygCommandBlockquoteLabel = 'commands.wysiwyg.command.blockquote.label', + /** + * Add a blockquote + */ + commandsWysiwygCommandBlockquoteDetail = 'commands.wysiwyg.command.blockquote.detail', + /** + * Strikethrough + */ + commandsWysiwygCommandStrikethroughLabel = 'commands.wysiwyg.command.strikethrough.label', + /** + * Add strikethrough text + */ + commandsWysiwygCommandStrikethroughDetail = 'commands.wysiwyg.command.strikethrough.detail', + /** + * WYSIWYG Options + */ + commandsWysiwygQuickPickTitle = 'commands.wysiwyg.quickPick.title', + /** + * Which type of markup would you like to insert? + */ + commandsWysiwygQuickPickPlaceholder = 'commands.wysiwyg.quickPick.placeholder', + /** + * WYSIWYG Hyperlink + */ + commandsWysiwygAddHyperlinkHyperlinkInputTitle = 'commands.wysiwyg.addHyperlink.hyperlinkInput.title', + /** + * Enter the URL + */ + commandsWysiwygAddHyperlinkHyperlinkInputPrompt = 'commands.wysiwyg.addHyperlink.hyperlinkInput.prompt', + /** + * WYSIWYG Text + */ + commandsWysiwygAddHyperlinkTextInputTitle = 'commands.wysiwyg.addHyperlink.textInput.title', + /** + * Enter the text for the hyperlink + */ + commandsWysiwygAddHyperlinkTextInputPrompt = 'commands.wysiwyg.addHyperlink.textInput.prompt', + /** + * Heading level + */ + commandsWysiwygInsertTextHeadingInputTitle = 'commands.wysiwyg.insertText.heading.input.title', + /** + * Which heading level do you want to insert? + */ + commandsWysiwygInsertTextHeadingInputPlaceholder = 'commands.wysiwyg.insertText.heading.input.placeholder', + /** + * A page bundle with the name {0} already exists in {1}. + */ + helpersArticleHelperCreateContentPageBundleError = 'helpers.articleHelper.createContent.pageBundle.error', + /** + * Content with the title already exists. Please specify a new title. + */ + helpersArticleHelperCreateContentContentExistsWarning = 'helpers.articleHelper.createContent.contentExists.warning', + /** + * Error while processing the {0} placeholder. + */ + helpersArticleHelperProcessCustomPlaceholdersPlaceholderError = 'helpers.articleHelper.processCustomPlaceholders.placeholder.error', + /** + * Error parsing the front matter of {0}. + */ + helpersArticleHelperParseFileDiagnosticError = 'helpers.articleHelper.parseFile.diagnostic.error', + /** + * No front matter data found to generate a content type. + */ + helpersContentTypeGenerateNoFrontMatterError = 'helpers.contentType.generate.noFrontMatter.error', + /** + * Override the default content type + */ + helpersContentTypeGenerateOverrideQuickPickTitle = 'helpers.contentType.generate.override.quickPick.title', + /** + * Do you want to overwrite the default content type configuration with the fields used in the current field? + */ + helpersContentTypeGenerateOverrideQuickPickPlaceholder = 'helpers.contentType.generate.override.quickPick.placeholder', + /** + * Generate Content Type + */ + helpersContentTypeGenerateContentTypeInputTitle = 'helpers.contentType.generate.contentTypeInput.title', + /** + * Enter the name of the content type to generate + */ + helpersContentTypeGenerateContentTypeInputPrompt = 'helpers.contentType.generate.contentTypeInput.prompt', + /** + * Please enter a name for the content type. + */ + helpersContentTypeGenerateContentTypeInputValidationEnterName = 'helpers.contentType.generate.contentTypeInput.validation.enterName', + /** + * A content type with this name already exists. + */ + helpersContentTypeGenerateContentTypeInputValidationNameExists = 'helpers.contentType.generate.contentTypeInput.validation.nameExists', + /** + * You didn't specify a name for the content type. + */ + helpersContentTypeGenerateNoContentTypeNameWarning = 'helpers.contentType.generate.noContentTypeName.warning', + /** + * Use as a page bundle + */ + helpersContentTypeGeneratePageBundleQuickPickTitle = 'helpers.contentType.generate.pageBundle.quickPick.title', + /** + * Do you want to use this content type as a page bundle? + */ + helpersContentTypeGeneratePageBundleQuickPickPlaceHolder = 'helpers.contentType.generate.pageBundle.quickPick.placeHolder', + /** + * Content type {0} has been updated. + */ + helpersContentTypeGenerateUpdatedSuccess = 'helpers.contentType.generate.updated.success', + /** + * Content type {0} has been generated. + */ + helpersContentTypeGenerateGeneratedSuccess = 'helpers.contentType.generate.generated.success', + /** + * No front matter data found to add missing fields. + */ + helpersContentTypeAddMissingFieldsNoFrontMatterWarning = 'helpers.contentType.addMissingFields.noFrontMatter.warning', + /** + * Content type {0} has been updated. + */ + helpersContentTypeAddMissingFieldsUpdatedSuccess = 'helpers.contentType.addMissingFields.updated.success', + /** + * No front matter data found to set the content type. + */ + helpersContentTypeSetContentTypeNoFrontMatterWarning = 'helpers.contentType.setContentType.noFrontMatter.warning', + /** + * Select the content type + */ + helpersContentTypeSetContentTypeQuickPickTitle = 'helpers.contentType.setContentType.quickPick.title', + /** + * Which content type would you like to use? + */ + helpersContentTypeSetContentTypeQuickPickPlaceholder = 'helpers.contentType.setContentType.quickPick.placeholder', + /** + * {0}: Creating content... + */ + helpersContentTypeCreateProgressTitle = 'helpers.contentType.create.progress.title', + /** + * Your new content has been created. + */ + helpersContentTypeCreateSuccess = 'helpers.contentType.create.success', + /** + * The content type actions are not available in this mode. + */ + helpersContentTypeVerifyWarning = 'helpers.contentType.verify.warning', + /** + * Executing: {0} + */ + helpersCustomScriptExecuting = 'helpers.customScript.executing', + /** + * {0}: Article couldn't be retrieved. + */ + helpersCustomScriptSingleRunArticleWarning = 'helpers.customScript.singleRun.article.warning', + /** + * {0}: No files found + */ + helpersCustomScriptBulkRunNoFilesWarning = 'helpers.customScript.bulkRun.noFiles.warning', + /** + * {0}: There was no folder or media path specified. + */ + helpersCustomScriptRunMediaScriptNoFolderWarning = 'helpers.customScript.runMediaScript.noFolder.warning', + /** + * {0}: front matter updated. + */ + helpersCustomScriptShowOutputFrontMatterSuccess = 'helpers.customScript.showOutput.frontMatter.success', + /** + * Copy output + */ + helpersCustomScriptShowOutputCopyOutputAction = 'helpers.customScript.showOutput.copyOutput.action', + /** + * {0}: Executed your custom script. + */ + helpersCustomScriptShowOutputSuccess = 'helpers.customScript.showOutput.success', + /** + * Invalid command: {0} + */ + helpersCustomScriptValidateCommandError = 'helpers.customScript.validateCommand.error', + /** + * Something went wrong while processing the data file. + */ + helpersDataFileHelperProcessError = 'helpers.dataFileHelper.process.error', + /** + * Check the changelog + */ + helpersExtensionGetVersionChangelog = 'helpers.extension.getVersion.changelog', + /** + * Give it a ⭐️ + */ + helpersExtensionGetVersionStarIt = 'helpers.extension.getVersion.starIt', + /** + * {0} has been updated to v{1} — check out what's new! + */ + helpersExtensionGetVersionUpdateNotification = 'helpers.extension.getVersion.update.notification', + /** + * The "{0}" and "{1}" settings have been deprecated. Please use the "isPublishDate" and "isModifiedDate" datetime field properties instead. + */ + helpersExtensionMigrateSettingsDeprecatedWarning = 'helpers.extension.migrateSettings.deprecated.warning', + /** + * Hide + */ + helpersExtensionMigrateSettingsDeprecatedWarningHide = 'helpers.extension.migrateSettings.deprecated.warning.hide', + /** + * See migration guide + */ + helpersExtensionMigrateSettingsDeprecatedWarningSeeGuide = 'helpers.extension.migrateSettings.deprecated.warning.seeGuide', + /** + * {0} - Templates + */ + helpersExtensionMigrateSettingsTemplatesQuickPickTitle = 'helpers.extension.migrateSettings.templates.quickPick.title', + /** + * Do you want to keep on using the template functionality? + */ + helpersExtensionMigrateSettingsTemplatesQuickPickPlaceholder = 'helpers.extension.migrateSettings.templates.quickPick.placeholder', + /** + * Front Matter BETA cannot be used while the stable version is installed. Please ensure that you have only over version installed. + */ + helpersExtensionCheckIfExtensionCanRunWarning = 'helpers.extension.checkIfExtensionCanRun.warning', + /** + * We couldn't find your selected folder. + */ + helpersMediaHelperSaveFileFolderError = 'helpers.mediaHelper.saveFile.folder.error', + /** + * File {0} uploaded to: {1} + */ + helpersMediaHelperSaveFileFileUploadedSuccess = 'helpers.mediaHelper.saveFile.file.uploaded.success', + /** + * Sorry, something went wrong uploading {0} + */ + helpersMediaHelperSaveFileFileUploadedFailed = 'helpers.mediaHelper.saveFile.file.uploaded.failed', + /** + * Sorry, something went wrong deleting {0} + */ + helpersMediaHelperDeleteFileFileDeletionFailed = 'helpers.mediaHelper.deleteFile.file.deletion.failed', /** * Template files copied. */