Internationalisierung (i18n)

Richtlinien für die Mehrsprachigkeit der WvdS FPC RAD Suite.

Grundprinzip

Keine buchstäblichen Zeichenfolgen im Pascal-Code (außer in asm-Blöcken und technischen Konstanten).

Unterstützte Sprachen

Code Sprache Status
EN Englisch Basis (Pflicht)
DE Deutsch Vollständig
SL Slowenisch Vollständig
HR Kroatisch Vollständig

Resourcestrings

Struktur

sources/common/core/
├── WvdS.VSCode.Strings.pas      # Englisch (Default)
├── WvdS.VSCode.Strings.DE.pas   # Deutsch
├── WvdS.VSCode.Strings.SL.pas   # Slowenisch
└── WvdS.VSCode.Strings.HR.pas   # Kroatisch

Basis-Unit (Englisch)

unit WvdS.VSCode.Strings;
 
{$mode objfpc}{$H+}
 
interface
 
resourcestring
  // === CORE ===
  rsCoreActivated = 'WvdS Core extension activated';
  rsCoreDeactivated = 'WvdS Core extension deactivated';
  rsCoreError = 'Error: %s';
 
  // === BUILD ===
  rsBuildStarting = 'Build starting...';
  rsBuildCompleted = 'Build completed successfully';
  rsBuildFailed = 'Build failed: %s';
  rsBuildCompilerNotFound = 'Compiler not found: %s';
 
  // === PROJECTS ===
  rsProjectCreating = 'Creating project...';
  rsProjectCreated = 'Project ''%s'' created successfully';
  rsProjectNameEmpty = 'Project name cannot be empty';
  rsProjectNameTooLong = 'Project name cannot exceed %d characters';
  rsProjectNameInvalidChar = 'Invalid character in project name: ''%s''';
 
  // === TOOLCHAIN ===
  rsToolNotFound = 'Tool not found: %s';
  rsToolDetected = '%s detected at %s';
  rsToolVersionMismatch = '%s version %s found, expected %s';
 
  // === VALIDATION ===
  rsValidationFailed = 'Validation failed: %s';
  rsFileNotFound = 'File not found: %s';
  rsAccessDenied = 'Access denied: %s';
  rsUnexpectedError = 'Unexpected error (%s): %s';
 
implementation
 
end.

Deutsche Übersetzung

unit WvdS.VSCode.Strings.DE;
 
{$mode objfpc}{$H+}
 
interface
 
resourcestring
  // === CORE ===
  rsCoreActivated = 'WvdS Core Extension aktiviert';
  rsCoreDeactivated = 'WvdS Core Extension deaktiviert';
  rsCoreError = 'Fehler: %s';
 
  // === BUILD ===
  rsBuildStarting = 'Build wird gestartet...';
  rsBuildCompleted = 'Build erfolgreich abgeschlossen';
  rsBuildFailed = 'Build fehlgeschlagen: %s';
  rsBuildCompilerNotFound = 'Compiler nicht gefunden: %s';
 
  // === PROJECTS ===
  rsProjectCreating = 'Projekt wird erstellt...';
  rsProjectCreated = 'Projekt ''%s'' erfolgreich erstellt';
  rsProjectNameEmpty = 'Projektname darf nicht leer sein';
  rsProjectNameTooLong = 'Projektname darf maximal %d Zeichen haben';
  rsProjectNameInvalidChar = 'Ungültiges Zeichen im Projektnamen: ''%s''';
 
  // === TOOLCHAIN ===
  rsToolNotFound = 'Werkzeug nicht gefunden: %s';
  rsToolDetected = '%s erkannt unter %s';
  rsToolVersionMismatch = '%s Version %s gefunden, erwartet %s';
 
  // === VALIDATION ===
  rsValidationFailed = 'Validierung fehlgeschlagen: %s';
  rsFileNotFound = 'Datei nicht gefunden: %s';
  rsAccessDenied = 'Zugriff verweigert: %s';
  rsUnexpectedError = 'Unerwarteter Fehler (%s): %s';
 
implementation
 
end.

Verwendung im Code

Einfache Strings

uses
  WvdS.VSCode.Strings;
 
// KORREKT
ShowInfoMessage(rsBuildStarting);
 
// VERBOTEN
ShowInfoMessage('Build starting...');

Strings mit Parametern

// KORREKT - Format verwenden
ShowInfoMessage(Format(rsProjectCreated, [ProjectName]));
ShowErrorMessage(Format(rsBuildFailed, [ErrorMessage]));
 
// VERBOTEN
ShowInfoMessage('Project ''' + ProjectName + ''' created');

Pluralisierung

resourcestring
  rsFilesFound_One = '%d file found';
  rsFilesFound_Many = '%d files found';
 
function GetFilesFoundMessage(ACount: Integer): string;
begin
  if ACount = 1 then
    Result := Format(rsFilesFound_One, [ACount])
  else
    Result := Format(rsFilesFound_Many, [ACount]);
end;

Erlaubte Ausnahmen

Technische Konstanten

const
  // Technische IDs - nicht übersetzen
  COMMAND_ID = 'wvds.build.run';
  FILE_EXTENSION = '.pas';
  CONFIG_KEY = 'wvds.toolchain.fpcPath';

Format-Strings

const
  // JSON/XML Templates - nicht übersetzen
  JSON_TEMPLATE = '{"name": "%s", "version": "%s"}';
  XML_TEMPLATE = '<%s>%s</%s>';

asm-Blöcke

// JavaScript-Code darf Strings enthalten
asm
  console.log('Debug message');
  vscode.window.showInformationMessage('Hello');
end;

Workflow: Neuen String hinzufügen

Schritt 1: Englischen String definieren

// WvdS.VSCode.Strings.pas
resourcestring
  rsNewFeatureMessage = 'New feature activated';

Schritt 2: Deutsche Übersetzung

// WvdS.VSCode.Strings.DE.pas
resourcestring
  rsNewFeatureMessage = 'Neue Funktion aktiviert';

Schritt 3: Slowenische Übersetzung

// WvdS.VSCode.Strings.SL.pas
resourcestring
  rsNewFeatureMessage = 'Nova funkcija aktivirana';

Schritt 4: Kroatische Übersetzung

// WvdS.VSCode.Strings.HR.pas
resourcestring
  rsNewFeatureMessage = 'Nova funkcija aktivirana';

Schritt 5: Im Code verwenden

ShowInfoMessage(rsNewFeatureMessage);

Sprachauswahl zur Laufzeit

Die Sprache wird aus den VS Code Einstellungen gelesen:

function GetCurrentLanguage: string;
begin
  Result := GetVSCodeLanguage;  // z.B. 'de', 'en', 'sl', 'hr'
end;
 
procedure LoadLanguageStrings;
var
  Lang: string;
begin
  Lang := GetCurrentLanguage;
  case Lang of
    'de': LoadGermanStrings;
    'sl': LoadSlovenianStrings;
    'hr': LoadCroatianStrings;
  else
    // Englisch als Fallback
    LoadEnglishStrings;
  end;
end;

Validierung

wvds-lint i18n-Check

wvds-lint i18n --path sources/

Geprüft wird:

  • Hardcodierte Strings im Code
  • Fehlende Übersetzungen
  • Unbenutzte Resourcestrings
  • Format-String-Konsistenz (gleiche Anzahl %s, %d)

Checkliste

[ ] Englischer String definiert
[ ] Deutsche Übersetzung hinzugefügt
[ ] Slowenische Übersetzung hinzugefügt
[ ] Kroatische Übersetzung hinzugefügt
[ ] Format-Parameter stimmen überein
[ ] Im Code verwendet (nicht hardcodiert)
[ ] wvds-lint i18n erfolgreich

Best Practices

Klare, kontextfreie Strings

// GUT - Selbsterklärend
rsFileNotFound = 'File not found: %s';
 
// SCHLECHT - Kontext fehlt
rsNotFound = 'Not found: %s';  // Was wurde nicht gefunden?

Volle Sätze bevorzugen

// GUT
rsProjectCreatedSuccessfully = 'Project ''%s'' was created successfully.';
 
// SCHLECHT - Fragmente
rsProject = 'Project';
rsCreated = 'created';
rsSuccessfully = 'successfully';
// UI: rsProject + ' ' + Name + ' ' + rsCreated + ' ' + rsSuccessfully
// Problem: Wortstellung variiert zwischen Sprachen!

Konsistente Terminologie

Begriff Englisch Deutsch
Build Build Build (nicht „Erstellung“)
Compile Compile Kompilieren
Path Path Pfad
Settings Settings Einstellungen

Siehe auch

Zuletzt geändert: den 29.01.2026 um 15:13