I have solved this problem in 2 different ways. Depending on your need, you 
pick one.

Option 1 "have an extra translation table" can look something like this

LANG = T.accepted_language if T.accepted_language in SUPPORTED_LANGUAGES 
else 'en'


db.define_table('tag',
    format=lambda r: db(
                            (db.tag_translation.tag == r.id) &
                            (db.tag_translation.lang == LANG)
                        ).select().first().name
)


db.define_table('tag_translation',
    Field('tag', 'reference tag'),
    Field('lang', requires=IS_IN_SET(SUPPORTED_LANGUAGES)),
    Field('name', label=T('Name')),
)




Option 2 which I kind of favor right now if I'm using postgresql, is to 
"use a JSON field" and store all the translations there:


def pick_lang():
    twoletter = session.lang or T.accepted_language[:2]
    if twoletter in SUPPORTED_LANGUAGES:
        T.force(twoletter)
        return twoletter
    else:
        T.force('en')
        return 'en'
LANG = pick_lang()

def represent_lang(v):
    if v is None:
        return v
    if LANG in v:
        return v[LANG]
    else:
        return v['en']


db.define_table('tag',
                Field('name', 'json', widget=TranslateWidget().widget, 
requires=IS_JSON(), represent=represent_lang)
)

You may notice this second option has a TranslateWidget, I have included a 
file with it in this post, just put it in modules and import it in your 
models. 

If you go with this option another useful function if you wanted to e.g. 
search tags by name, is: 

from gluon.dal import Expression

def JSON_KEY_EXPRESSION(field, key, value_type='string'):
    db = field._db
    def op(first, second):
        return "%s->>'%s'" % (db._adapter.expand(first), db._adapter.expand(
second))
    return Expression(db, op, field, key, value_type)

And then in a controller you could do something like

tags = db(JSON_KEY_EXPRESSION(db.tag.name, LANG).like('%' + request.vars.search 
+ '%', case_sensitive=False)).select()



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
# -*- coding: utf-8 -*-
# author: Leonel Câmara
"""
You can also use it with plugin_ckeditor example:
db.thing.body.widget=TranslateWidget(input_widget=ckeditor.widget).widget
"""
from gluon.html import *
from gluon.sqlhtml import FormWidget
from gluon import current
import json

LANGS = ['en' , 'pt']


class TranslateWidget(FormWidget):
    _class = 'string'

    def __init__(self, langs=None, input_widget=None):
        self.input_widget = input_widget
        self.langs = langs or LANGS
    
    def widget(self, field, value, **attributes):
        """
        Generates an INPUT text tag.

        see also: `FormWidget.widget`
        """

        default = dict(
            _type='hidden',
            value=(value is not None and str(value)) or '',
        )
        attr = FormWidget._attributes(field, default, **attributes)

        realvalue = INPUT(**attr)
        _id = attr['_id']

        
        nav_tabs = UL(
                  *[LI(A(lang, **{'_href': '#' + _id + '_' + lang, '_data-toggle':'tab'})) for lang in self.langs],
                  _class='nav nav-tabs'
                  )

        values = json.loads(value) if value else {lang:'' for lang in self.langs}

        if self.input_widget is None:
            tab_content = DIV(
                    *[DIV(TEXTAREA(values[lang], _name=_id + '_' + lang, _placeholder=current.T('Write me...'), _rows=2), _id=_id + '_' + lang, _class='tab-pane fade') for lang in self.langs],

            _class='tab-content')
        else:
            tab_content = DIV(_class='tab-content')
            for lang in self.langs:
                attributes = {'_id': _id + '_' + lang + '_widget',
                              '_name':_id + '_' + lang, 
                              '_placeholder':current.T('Write me...')
                             }
                tab_content.append(
                    DIV(self.input_widget(field, values[lang], **attributes), _class='tab-pane fade', _id=_id + '_' + lang)
                    )


        script = SCRIPT("""
                        $('#%(_id)s').closest('form').submit(function(){
                            $('#%(_id)s').val(JSON.stringify({
                                %(langvals)s
                            }));
                            %(removelangvals)s;
                        });
                        // This bullshit is needed for tabs with widgets using plugin simplemde
                        $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                          var target = $(e.target).attr("href") // activated tab
                          window[target.substring(1) + "_widget_mde"].codemirror.refresh();
                        });
                        """ % { '_id': _id, 
                                'langvals': ','.join('"%s":$("[name=\'%s\']").val()' % (lang, _id + '_' + lang) for lang in self.langs), 
                                'removelangvals': ';'.join('$("[name=\'%s\']").remove()' % (_id + '_' + lang) for lang in self.langs)
                               }
                       )
        nav_tabs[0]['_class'] ='active'
        tab_content[0]['_class'] += ' in active'
        if current.request.post_vars:
            # Make sure we validate our extra inputs for IS_JSON
            for lang in self.langs:
                name=_id + '_' + lang
                current.request.post_vars[name] = '{}'
        return CAT(nav_tabs, tab_content, realvalue, script)

Reply via email to