Addon localization

Hi guys, I’m trying to change locale of custom created properties by switching one’s property value. In the giving example I have two enums, and I want to change locale of one enum (simple_enum) by changing value of another enum (lang).

I tried to do this by:

if bpy.context.scene.s_props.lang == '1':
    locale = locale_1
else:
    locale = locale_2

But it didn’t work.


bl_info = {
    "name": "Test",
    "author": "",
    "version": (0, 0, 0),
    "blender": (2, 7, 2),
    "location": "Properties > Scene",
    "description": "Test",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "3D View"}




import bpy
from bpy.props import (EnumProperty,
                       PointerProperty,
                       )
from bpy.types import (PropertyGroup,
                       Panel,
                       )


locale_1 = {
    '1' : 'locale 1',
    '2' : 'locale 1',
    '3' : 'locale 1',
}
locale_2 = {
    '1' : 'locale 2',
    '2' : 'locale 2',
    '3' : 'locale 2',
}



if bpy.context.scene.s_props.lang == '1':
    locale = locale_1
else:
    locale = locale_2



class TestProperties(PropertyGroup):


    lang = EnumProperty(
        items=(
            ('1', 'locale 1', ""),
            ('2', 'locale 2', ""),
        ),
        name='',
        default='1')


    # Template selector
    simple_enum = EnumProperty(
        items=(
            ('1', locale['1'], ""),
            ('2', locale['2'], ""),
            ('3', locale['3'], ""),
        ),
        name=locale['1'],
        default='1')



class TestPanel(Panel):
    
    bl_label = "Test"
    bl_idname = "VIEW3D_PT_test"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "scene"


    def draw(self, context):
        layout = self.layout
        sce = context.scene
        s_props = sce.s_props
        lang = s_props.lang


        if lang == '1':
            locale = locale_1
        elif lang == '2':
            locale = locale_2
        
        col = layout.column()
        col.prop(s_props, "lang")
        col.prop(s_props, "simple_enum")



classes = [
    TestPanel,
    TestProperties,
]


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    
    bpy.types.Scene.s_props = PointerProperty(type=TestProperties)


def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    
    del bpy.types.Scene.s_props


if __name__ == "__main__":
    register()


You should use the i18n module:

http://www.blender.org/api/blender_python_api_2_72_release/bpy.app.translations.html

Thanks, but as I understand the i18n module controlled by Internalization system setting, which would translate whole Blender UI to the chosen locale, I need to translate only addon props.

Is it supposed to change language as your locale property changes?

Yes it should.

That’s quite problematic, because you would need to re-register all properties. They can’t be altered on the fly.

I have managed to figure it out, it took me quite a while but it was a good exercise. :slight_smile:


import bpy


language = {
	"1" : {
		"hello" : "Woof Hello",
		"hungry" : "Woof Hungry",
		"thirsty" : "Woof Thirsty"
	},
	"2" : {
		"hello" : "Meow Hello",
		"hungry" : "Meow Hungry",
		"thirsty" : "Meow Thirsty"
	},
}


def get_texts_callback(scene, context):
	global language


	selected_language = context.scene.s_props.lang
	lang = language[selected_language]
	
	items = [
		("1", lang["hello"],	""),
		("2", lang["hungry"],	""),
		("3", lang["thirsty"],	""),
	]


	return items


class LanguagesGroup(bpy.types.PropertyGroup):
	lang = bpy.props.EnumProperty(
		items=(
			("1", "Dog Language", ""),
			("2", "Cat Language", ""),
		),
		name="Language",
		default="1"
	)


class TextGroup(bpy.types.PropertyGroup):
	texts = bpy.props.EnumProperty(
		items=get_texts_callback,
		name=""
	)


class TestPanel(bpy.types.Panel):
	bl_label = "Test"
	bl_idname = "VIEW3D_PT_test"
	bl_space_type = "PROPERTIES"
	bl_region_type = "WINDOW"
	bl_context = "scene"


	def draw(self, context):
		layout = self.layout
		scene = context.scene
		
		row = layout.row()
		row.prop(scene.s_props, "lang")


		row = layout.row()
		row.prop(scene.s_texts, "texts")


		# col.prop(s_props, "simple_enum")


def register():
	bpy.utils.register_class(TestPanel)
	bpy.utils.register_class(LanguagesGroup)
	bpy.utils.register_class(TextGroup)
	bpy.types.Scene.s_props = bpy.props.PointerProperty(type=LanguagesGroup)
	bpy.types.Scene.s_texts = bpy.props.PointerProperty(type=TextGroup)


def unregister():
	bpy.utils.unregister_class(TestPanel)
	bpy.utils.unregister_class(LanguagesGroup)
	bpy.utils.unregister_class(TextGroup)
	del bpy.types.Scene.s_props
	del bpy.types.Scene.s_texts


if __name__ == "__main__":
	register()

I hope it helps and give you some ideas.

Set enum items by a function? Original :slight_smile: the only downer is that I cannot set enum’s default value, but in my case it’s not important.

Thanks for the help.

Small addition: it is possible to set enums default value by introducing “id” value to the item, like so:


items = [
	("1", lang["hello"],	"", 0),
	("2", lang["hungry"],	"", 1),
	("3", lang["thirsty"],	"", 2),
]