diff --git a/examples/babel.cfg b/examples/babel.cfg new file mode 100644 index 0000000..b722ee9 --- /dev/null +++ b/examples/babel.cfg @@ -0,0 +1,2 @@ +[python: translation.py] +extensions=jinja2.ext.autoescape,jinja2.ext.with_ diff --git a/examples/babel.sh b/examples/babel.sh new file mode 100755 index 0000000..350d891 --- /dev/null +++ b/examples/babel.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +BABEL=pybabel +TEMPLATE_FILE=messages.pot +TRANSLATIONS_DIR=translations + +if [[ "$1" = "lninit" ]]; then + $BABEL init -i $TEMPLATE_FILE -d $TRANSLATIONS_DIR -l de -l en_GB +elif [[ "$1" = "lnupdate" ]]; then + $BABEL extract -F babel.cfg -o $TEMPLATE_FILE + $BABEL update -i $TEMPLATE_FILE -d $TRANSLATIONS_DIR +elif [[ "$1" = "lncompile" ]]; then + $BABEL compile -f -d $TRANSLATIONS_DIR +fi diff --git a/examples/translation.py b/examples/translation.py new file mode 100644 index 0000000..8259bfb --- /dev/null +++ b/examples/translation.py @@ -0,0 +1,51 @@ +from flask_table import Table, Col, ButtonCol +from flask import Flask +from flask_babelex import Babel, Domain, _ + +"""An example for creating LinkCol or ButtonCol with translations. + You have to call ./babel.sh lncompile before using this example. +""" + +# Setup the flask app +app = Flask(__name__) + +# Setup babel +app.config['BABEL_DEFAULT_LOCALE'] = 'en_GB' +app.config['BABEL_TRANSLATION_DIRECTORIES'] = 'translations' +language_domain = Domain(dirname='translations', domain='messages') +language = Babel(default_locale='en_GB', configure_jinja=True, default_domain=language_domain) +language.init_app(app) + + +# This class shows how to use translations for columns and tables +class TranslatedTable(Table): + name = Col('name') + button = ButtonCol('button_name', 'some_url', translation_enabled=True) + + def __init__(self, items): + super(TranslatedTable, self).__init__(items, translation_enabled=True) + + +# The main page +@app.route('/', methods=['GET', 'POST']) +def index(): + # The column names will be translated by flask_table + items = [{'name': 'A'}, + {'name': 'B'}] + + # Pass some translated items to TranslatedTable + table = TranslatedTable(items) + + # return a translated table + return '' + table.__html__() + '' + + +# A page to redirect to +@app.route('/some_url', methods=['GET', 'POST']) +def some_url(): + # Display the local attribute for testing purposes + return 'Redirected' + + +if __name__ == '__main__': + app.run(debug=True) diff --git a/examples/translations/de/LC_MESSAGES/messages.po b/examples/translations/de/LC_MESSAGES/messages.po new file mode 100644 index 0000000..5186a85 --- /dev/null +++ b/examples/translations/de/LC_MESSAGES/messages.po @@ -0,0 +1,23 @@ +# German translations for PROJECT. +# Copyright (C) 2018 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# Sebastian Lau , 2018. +# +msgid "" +msgstr "" +"POT-Creation-Date: 2018-06-26 08:51+0200\n" +"PO-Revision-Date: 2018-06-26 08:51+0200\n" +"Language: de\n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.6.0\n" + +msgid "name" +msgstr "Name" + +msgid "button_name" +msgstr "Eine Weiterleitung" + diff --git a/examples/translations/en_GB/LC_MESSAGES/messages.po b/examples/translations/en_GB/LC_MESSAGES/messages.po new file mode 100644 index 0000000..a216906 --- /dev/null +++ b/examples/translations/en_GB/LC_MESSAGES/messages.po @@ -0,0 +1,21 @@ +# English (United Kingdom) translations for PROJECT. +# Copyright (C) 2018 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Language: en_GB\n" +"Language-Team: en_GB \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.6.0\n" + +msgid "name" +msgstr "Name" + +msgid "button_name" +msgstr "A redirection" + diff --git a/flask_table/columns.py b/flask_table/columns.py index fc74d24..c214733 100644 --- a/flask_table/columns.py +++ b/flask_table/columns.py @@ -2,7 +2,7 @@ from flask import Markup, url_for from babel.dates import format_date, format_datetime -from flask_babel import gettext as _ +from flask_babelex import _ from .html import element @@ -256,13 +256,15 @@ class LinkCol(Col): """ def __init__(self, name, endpoint, attr=None, attr_list=None, url_kwargs=None, url_kwargs_extra=None, - anchor_attrs=None, text_fallback=None, **kwargs): + anchor_attrs=None, text_fallback=None, + translation_enabled=False, **kwargs): super(LinkCol, self).__init__( name, attr=attr, attr_list=attr_list, **kwargs) self.endpoint = endpoint + self.translation_enabled = translation_enabled self._url_kwargs = url_kwargs or {} self._url_kwargs_extra = url_kwargs_extra or {} self.text_fallback = text_fallback @@ -284,9 +286,15 @@ def text(self, item, attr_list): if attr_list: return self.from_attr_list(item, attr_list) elif self.text_fallback: - return self.text_fallback + if self.translation_enabled: + return _(self.text_fallback) + else: + return self.text_fallback else: - return self.name + if self.translation_enabled: + return _(self.name) + else: + return self.name def url(self, item): return url_for(self.endpoint, **self.url_kwargs(item)) @@ -315,13 +323,16 @@ class ButtonCol(LinkCol): def __init__(self, name, endpoint, attr=None, attr_list=None, url_kwargs=None, button_attrs=None, form_attrs=None, - form_hidden_fields=None, **kwargs): + form_hidden_fields=None, + translation_enabled=False, **kwargs): super(ButtonCol, self).__init__( name, endpoint, attr=attr, attr_list=attr_list, - url_kwargs=url_kwargs, **kwargs) + url_kwargs=url_kwargs, + translation_enabled=translation_enabled, + **kwargs) self.button_attrs = button_attrs or {} self.form_attrs = form_attrs or {} self.form_hidden_fields = form_hidden_fields or {} diff --git a/flask_table/table.py b/flask_table/table.py index 9495e6e..47271d3 100644 --- a/flask_table/table.py +++ b/flask_table/table.py @@ -3,7 +3,7 @@ from collections import OrderedDict from flask import Markup -from flask_babel import gettext as _ +from flask_babelex import _ from .columns import Col from .compat import with_metaclass @@ -65,8 +65,10 @@ class Table(with_metaclass(TableMeta)): def __init__(self, items, classes=None, thead_classes=None, sort_by=None, sort_reverse=False, no_items=None, - table_id=None, border=None, html_attrs=None): + table_id=None, border=None, html_attrs=None, + translation_enabled=False): self.items = items + self.translation_enabled = translation_enabled self.sort_by = sort_by self.sort_reverse = sort_reverse if classes is not None: @@ -147,7 +149,10 @@ def tr(self, item): def th_contents(self, col_key, col): if not (col.allow_sort and self.allow_sort): - return Markup.escape(col.name) + if self.translation_enabled: + return Markup.escape(_(col.name)) + else: + return Markup.escape(col.name) if self.sort_by == col_key: if self.sort_reverse: @@ -159,7 +164,12 @@ def th_contents(self, col_key, col): else: href = self.sort_url(col_key) label_prefix = '' - label = '{prefix}{label}'.format(prefix=label_prefix, label=col.name) + if self.translation_enabled: + label = '{prefix}{label}'.format(prefix=label_prefix, + label=_(col.name)) + else: + label = '{prefix}{label}'.format(prefix=label_prefix, + label=col.name) return element('a', attrs=dict(href=href), content=label) def th(self, col_key, col): diff --git a/requirements.txt b/requirements.txt index 68d15ec..bfe0a05 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ Flask -Flask-Babel +Flask-BabelEx Flask-Testing