Localization don't work on dynamic string table loaded from csv

Hello!

My localization work well on string table assets. After I throu out my string table asset and load dynamically string tables from csv on project start inside c++ code then I cannot gather this dynamically loaded string tables.

It is possible to localize dynamically loaded string tables from csv ?
If not, someone know if this future request is written somewhere ?
I check 4.17 and 4.17.1 and can’t find mention about it.
Or maybe is this bug ?

Are you loading your CSV string table using the LOCTABLE_FROMFILE_GAME macro? If not then the source code gatherer currently won’t pick up your string table as it looks for these macros to know which CSV files to parse as string tables.

If you are using the LOCTABLE_FROMFILE_GAME macro then make sure that the source file containing the macro is being gathered for your game.

Hello!

Thank you for your answer! I don’t use LOCTABLE_FROMFILE_GAME because I cannot pass variable as macro parameter. Instead of I’m using exactly same code as macro is.

FStringTableRegistry::Get().Internal_LocTableFromFile(*Line, Line, csvFile, FPaths::GameDir());

I create csv file list dynamically outside of Visual Studio and need to use variable. Every String Tables loading correct and I can use then in editor or in game.

So If GatherText commandlet looking for LOCTABLE_FROMFILE_GAME, how to use variable for it ?

Or what is the other way to load dynamically created list of csv files ?

void FImportCsvInGamePlugin::LoadAllStringTables ()
{
	FString dirGeneratedStringTables = "Content/Localization/StringTables/";

	// Find and load CSV file
	FString StringTableListFile = FPaths::GameDir() + *dirGeneratedStringTables + "StringTableList.txt";
	TArray<FString> * StringTableList = LoadStringTableFilesList(StringTableListFile);

	for (int i = 1; i < StringTableList->Num(); i++)	// pass over first line
	{
		FString Line = (*StringTableList)[i];
		FString csvFile = dirGeneratedStringTables + *((*StringTableList)[i]) + ".csv";

		//LOCTABLE_FROMFILE_GAME("aaa", kaka, "../Localization/Generated/STestStringTable.csv");
		FStringTableRegistry::Get().Internal_LocTableFromFile(*Line, Line, csvFile, FPaths::GameDir());		
	};
}

TArray * FImportCsvInGamePlugin::LoadStringTableFilesList (FString FNameFullPath)
{
	TArray<FString> * FileContent = new TArray<FString>;
	if (FPaths::FileExists(FNameFullPath))
	{
		FFileHelper::LoadANSITextFileToStrings(*FNameFullPath, NULL, *FileContent);  // load on line per array element
		return FileContent;
	} else {
		return nullptr;
	};
}

I see. The macro can’t handle variable data (and even if it did, the gatherer wouldn’t understand it). The macro also provides the namespace information to the gatherer, so the gatherer can’t actually process just the CSV files on their own. You may be better using assets instead (you can import your existing CSV files into the assets).

I didn’t imagine people trying to load CSV string tables dynamically, as they require code to load them so I had assumed any lists of tables to load would be in code and loaded via that macro. You’re also calling a function prefixed as being internal, so it’s not really surprising that it doesn’t do exactly what you wanted it to do… sorry about that :frowning:

Hm. Our team create texts and translation in ODS (LibreOffice Calc) and I thru scripts change it to many csv which load to DataTable, PO and StringTables. After run scripts UEditor is running and everything is automatically. So maybe when I create .h or .cpp file thru script with macro LOCTABLE_FROMFILE_GAME prepared exactly with my dynamic list, maybe localization handle it. I will try tomorrow.

If you can generate some code using the macro then the gatherer should handle it, just make sure that the paths are relative to FPaths::GameContentDir().

For people who came here for solutions:
Method described here work well. I generete synthetic cpp file with macros of all dynamically created csv. Example content of this file:

LOCTABLE_FROMFILE_GAME(“Localization/StringTables/GeneralStringTable.csv”, “GeneralStringTable”, “Localization/StringTables/GeneralStringTable.csv”);

Paths is relative to Content folder like Jamie Dale wrote.

Do I need to set up LocalizationDashBoardTool to collect the dynamically generated string table in LocalizationDashBoardTool?