I’m trying to export certain texts for localization. The texts are located in an array in some asset. I run GatherText and then export to .PO file. The problem is that the texts are not gathered the way it stored in an array, but alphabetically! This would be a nightmare to translate, because the context of text (surrounding dialog lines) are lost.
How can I affect an order in which texts are gathered or exported? Any solution would do, even changes in the engine code.
The sorting happens in FPortableObjectFormatDOM::SortEntries.
Generally we find order to be unimportant since once the PO is imported into a translation provider the entries will be sorted however there system wants them to be anyway (although it sounds like you’re editing the POs directly, which is also fine).
If you’re using our dialogue waves for your audio, then these have the ability to provide translation notes that appear as comments in the PO file. If you’re not, then string tables (defined from CSV or in code) have the ability to provide meta-data that appears as comments in the PO file.
The translation software I’ve encountered (poedit) only provided sorting by translation, and by source text. If you know any PO editor that can sort by reference, we would appreciate a link
Thank you for the information on string tables, I’ll look into it. For now, I made a simple predicate to sort entries by reference and it does what we need at the moment.
Where the locale variable is the locale you want to sort, and the target_name variable is the target you want it sorted in.
Run this script. It’ll sort the PO file you specified via variables by source reference.
Yeah, it’s that simple: it opens the PO file from ‘…/Localization/TargetName/Locale/TargetName.po’ (e.g., ‘…/Localization/Game/en-US/Game.po’ which resolves to ‘/Content/Localization/Game/en-US/Game.po’ if the script is in /Content/Python where it should be) and uses the sort() method… That’s it. As I said, the default sort method for POs is by source reference, which is exactly what you want here. It’ll group together strings that belong together and sit in the same asset, in the same array, etc. Helps a ton.
And Unreal doesn’t care about the order of entries in POs it imports, it just identifies them by namespaces and IDs, so it’s working like a charm.
(One minor annoyance is that it sorts numbers incorrectly since they’re part of a string, e.g., so array[100] comes before array[2]. Might be critical to you but you can fix this by iterating over PO entries and, say, adding zero-padding to indexes in source references (array[0002] will come before array[0100]). See polib docs or ping me later: I’ll be doing that for another project in a week or two.)
Hi, thanks for explaining your process.
Unfortunately, I get these errors :
Traceback (most recent call last):
File "C:\Users\johng\Documents\Unreal Projects\SVZ_427\Content\Python\LocTest_AnswerHubScript_fixed.py", line 9, in <module>
po = polib.pofile(file_name, wrapwidth=0, encoding='utf-8-sig')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\johng\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\polib.py", line 130, in pofile
return _pofile_or_mofile(pofile, 'pofile', **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\johng\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\polib.py", line 78, in _pofile_or_mofile
instance = parser.parse()
^^^^^^^^^^^^^^
File "C:\Users\johng\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\polib.py", line 1456, in parse
raise IOError('Syntax error in po file %s(line %s)' %
OSError: Syntax error in po file (line 1)