Importer and Exporter
Both APIs live in the module CliffLocalizationSuiteEditor (Type: Editor, export macro CLIFFLOCALIZATIONSUITEEDITOR_API) and are available in editor targets only.
IMPORTANT
These two entry points operate on the manifest / archive /
.locresdirectly. For day-to-day use go through the official GatherText pipeline (the Dashboard buttons orCliffLocalizationSuite.Import/Export), which handles config generation, the subprocess, reports and live refresh automatically. Calling them directly suits toolchain integration and automated tests.
FCliffImporter
Settings struct
struct CLIFFLOCALIZATIONSUITEEDITOR_API FCliffImportSettings
{
FString TargetPath; // 必需:Content/Localization/<Target>
FString ManifestName = TEXT("Game.manifest");
FString ArchiveName = TEXT("Game.archive");
FString NativeCulture; // 空则用 header 的 source-language
TArray<FString> ForeignCultures; // 空则用 header 的 target-language
FCliffSemanticMapping SemanticMapping = FCliffSemanticMapping::CreateDefault();
FString SidecarPath; // 可选:.cliffmap.json 路径
bool bCompileResources = true; // 直接编译 .locmeta/.locres 并热刷新
int32 LocResPriority = 0; // 数值越小优先级越高
};
Stats struct
struct CLIFFLOCALIZATIONSUITEEDITOR_API FCliffImportStats
{
int32 SourceCount = 0;
int32 TranslationCount = 0;
int32 WarningCount = 0;
FString CompiledCulture;
FString LocResFilePath;
FString LocMetaFilePath;
};
Methods
class CLIFFLOCALIZATIONSUITEEDITOR_API FCliffImporter
{
public:
static bool ImportFile(const FString& InCliffFilePath, const FCliffImportSettings& InSettings,
FCliffImportStats& OutStats, TArray<FCliffValidationIssue>& OutIssues, FText& OutError);
static bool ImportText(const FString& InCliffText, const FString& InCliffSourcePath,
const FCliffImportSettings& InSettings,
FCliffImportStats& OutStats, TArray<FCliffValidationIssue>& OutIssues, FText& OutError);
};
Example
FCliffImportSettings Settings;
Settings.TargetPath = FPaths::ProjectContentDir() / TEXT("Localization/Game");
Settings.NativeCulture = TEXT("zh-Hans");
Settings.ForeignCultures = { TEXT("en"), TEXT("ja") };
Settings.SemanticMapping = GetDefault<UCliffLocalizationSuiteSettings>()->GetSemanticMapping();
Settings.SidecarPath = TEXT("G:/Translations/cliff/Game.cliffmap.json");
FCliffImportStats Stats;
TArray<FCliffValidationIssue> Issues;
FText Error;
if (!FCliffImporter::ImportFile(TEXT("G:/Translations/cliff/ja/cliff-game.cliff"), Settings, Stats, Issues, Error))
{
UE_LOG(LogTemp, Error, TEXT("import failed: %s"), *Error.ToString());
}
// Stats.SourceCount / TranslationCount / WarningCount / LocResFilePath 可直接用于报告
Behaviour notes
| Behaviour | Description |
|---|---|
| Validation failure | Returns false, OutIssues holds every issue, and OutError is The CLIFF document is invalid; see the validation issues. |
status: initial | Writes the manifest only, no archive translation |
| Empty translation / self-translation | Write-back is refused (nothing is written when target is empty and the source is not in the target language); legacy empty translation entries are restored to the source text in place |
| Duplicate identity | No duplicate manifest context is added; the metadata is attached in place |
| Source-language import | The “effective source” of foreign archive entries is synchronised to the native translation automatically (the translation itself is untouched) |
| Compilation | With bCompileResources = true it generates .locmeta + the .locres for that culture and calls FTextLocalizationManager::UpdateFromLocalizationResource |
FCliffExporter
Settings struct
struct CLIFFLOCALIZATIONSUITEEDITOR_API FCliffExportSettings
{
FString TargetPath; // 必需
FString ManifestName = TEXT("Game.manifest");
FString ArchiveName = TEXT("Game.archive");
FString NativeCulture; // 空则从 <ManifestBase>.locmeta 推导
TArray<FString> Cultures; // 必需
FString CliffNamespace; // 空则用 manifest 基础名
FString SourceLanguage; // 空则用 NativeCulture
FString Standard; // 写入 header 的 standard
FCliffSemanticMapping SemanticMapping = FCliffSemanticMapping::CreateDefault();
FString OutputDirectory; // 空 = 不写盘
bool bWriteSidecar = true;
int32 LocResPriority = 0;
};
Output structs
struct CLIFFLOCALIZATIONSUITEEDITOR_API FCliffExportDocument
{
FString Clan; // 文件级 clan(manifest 基础名 kebab 化)
FString CliffText; // 序列化后的 CLIFF 文本
FString SuggestedFilePath; // <target-language>/<clan>.cliff
FString FilePath; // 实际写出的路径(OutputDirectory 为空时为空)
TArray<FCliffValidationIssue> Issues;
};
struct CLIFFLOCALIZATIONSUITEEDITOR_API FCliffExportStats
{
int32 DocumentCount = 0; // 每个 culture 一个文档
int32 EntryCount = 0;
int32 WarningCount = 0;
FString SidecarFilePath;
};
Methods
class CLIFFLOCALIZATIONSUITEEDITOR_API FCliffExporter
{
public:
static bool ExportTarget(const FCliffExportSettings& InSettings,
TArray<FCliffExportDocument>& OutDocuments,
FCliffExportStats& OutStats, FText& OutError);
static bool ExportFromLocResFile(const FString& InLocResFilePath, const FString& InCulture,
const FCliffExportSettings& InSettings,
FCliffExportDocument& OutDocument,
FCliffExportStats& OutStats,
TArray<FCliffValidationIssue>& OutIssues, FText& OutError);
};
Example
FCliffExportSettings Settings;
Settings.TargetPath = FPaths::ProjectContentDir() / TEXT("Localization/Game");
Settings.NativeCulture = TEXT("zh-Hans");
Settings.Cultures = { TEXT("zh-Hans"), TEXT("en"), TEXT("ja") };
Settings.CliffNamespace = GetDefault<UCliffLocalizationSuiteSettings>()->CliffNamespace;
Settings.SemanticMapping = GetDefault<UCliffLocalizationSuiteSettings>()->GetSemanticMapping();
Settings.Standard = GetDefault<UCliffLocalizationSuiteSettings>()->TranslationStandard;
Settings.OutputDirectory = TEXT("G:/Translations/cliff");
TArray<FCliffExportDocument> Documents;
FCliffExportStats Stats;
FText Error;
if (!FCliffExporter::ExportTarget(Settings, Documents, Stats, Error))
{
UE_LOG(LogTemp, Error, TEXT("export failed: %s"), *Error.ToString());
}
// Stats.DocumentCount(= culture 数)、EntryCount、WarningCount、SidecarFilePath
Behaviour notes
| Behaviour | Description |
|---|---|
| Document split | One document per culture; the header clan is the manifest stem kebab-cased (Game.manifest → cliff-game) |
| File path | <OutputDirectory>/<Culture>/<Clan>.cliff |
| Data source | The manifest plus each culture’s archive; ExportFromLocResFile reads a .locres directly (source text is filled in from the manifest) |
| Source language culture | No target is written and status is set to initial (so that mixed-language source text is not mistaken for a translation) |
| Self-check | The serialized result immediately goes through ParseAndValidate; HasErrors → returns false |
| Sidecar | <manifest stem>.cliffmap.json is written when bWriteSidecar && !OutputDirectory.IsEmpty() |
| Warnings | A missing type rule / missing clan mapping both increment WarningCount and log a line |
Related reading
- Import pipeline / export pipeline — step-by-step behaviour
- Key sidecar — structural details
- AI translation and commandlets