From 1b375d387c49101c9a79496b098e0ecc9db941cf Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Wed, 27 Jun 2012 13:27:24 +0200 Subject: [PATCH] [gen] Added support for right-to-left (RTL) languages. --- gen/mixins/ToolMixin.py | 12 +++++++++++- gen/mixins/__init__.py | 6 ++++++ gen/ui/ajax.pt | 6 +++++- gen/ui/appy.css | 1 + gen/ui/appyrtl.css | 7 +++++++ gen/ui/bannerrtl.jpg | Bin 0 -> 3751 bytes gen/ui/footer.pt | 2 +- gen/ui/lirtl.gif | Bin 0 -> 50 bytes gen/ui/navigate.pt | 2 +- gen/ui/page.pt | 21 +++++++++++---------- gen/ui/portlet.pt | 5 +++-- gen/ui/result.pt | 10 +++++----- gen/ui/search.pt | 2 +- gen/ui/template.pt | 25 +++++++++++++++---------- gen/ui/widgets/list.pt | 3 ++- gen/ui/widgets/ref.pt | 2 +- gen/ui/widgets/show.pt | 17 ++++++++++------- shared/data/__init__.py | 3 +++ 18 files changed, 83 insertions(+), 41 deletions(-) create mode 100644 gen/ui/appyrtl.css create mode 100644 gen/ui/bannerrtl.jpg create mode 100644 gen/ui/lirtl.gif diff --git a/gen/mixins/ToolMixin.py b/gen/mixins/ToolMixin.py index 5526439..2cf7149 100644 --- a/gen/mixins/ToolMixin.py +++ b/gen/mixins/ToolMixin.py @@ -110,7 +110,7 @@ class ToolMixin(BaseMixin): if not cfg.languageSelector: return if len(cfg.languages) < 2: return page = self.REQUEST.get('ACTUAL_URL').split('/')[-1] - return page not in ('edit', 'query', 'search') + return page not in ('edit', 'query', 'search', 'do') def getLanguages(self): '''Returns the supported languages. First one is the default.''' @@ -128,11 +128,21 @@ class ToolMixin(BaseMixin): rq.RESPONSE.setCookie('_ZopeLg', rq['language'], path='/') return self.goto(rq['HTTP_REFERER']) + def flipLanguageDirection(self, align, dir): + '''According to language direction p_dir ('ltr' or 'rtl'), this method + turns p_align from 'left' to 'right' (or the inverse) when + required.''' + if dir == 'ltr': return align + if align == 'left': return 'right' + if align == 'right': return 'left' + return align + def getGlobalCssJs(self): '''Returns the list of CSS and JS files to include in the main template. The method ensures that appy.css and appy.js come first.''' names = self.getPhysicalRoot().ui.objectIds('File') names.remove('appy.js'); names.insert(0, 'appy.js') + names.remove('appyrtl.css'); names.insert(0, 'appyrtl.css') names.remove('appy.css'); names.insert(0, 'appy.css') return names diff --git a/gen/mixins/__init__.py b/gen/mixins/__init__.py index e20ccd5..feb4fa8 100644 --- a/gen/mixins/__init__.py +++ b/gen/mixins/__init__.py @@ -10,6 +10,7 @@ from appy.gen.utils import * from appy.gen.layout import Table, defaultPageLayouts from appy.gen.descriptors import WorkflowDescriptor, ClassDescriptor from appy.shared.utils import sequenceTypes +from appy.shared.data import rtlLanguages # ------------------------------------------------------------------------------ class BaseMixin: @@ -1404,6 +1405,11 @@ class BaseMixin: if '-' in res: res = res[:res.find('-')] return res + def getLanguageDirection(self, lang): + '''Determines if p_lang is a LTR or RTL language.''' + if lang in rtlLanguages: return 'rtl' + return 'ltr' + def formatText(self, text, format='html'): '''Produces a representation of p_text into the desired p_format, which is "html" by default.''' diff --git a/gen/ui/ajax.pt b/gen/ui/ajax.pt index a2896b8..d089803 100644 --- a/gen/ui/ajax.pt +++ b/gen/ui/ajax.pt @@ -15,9 +15,13 @@ app tool/getApp; appUrl app/absolute_url; template python: contextObj.getPageTemplate(app.ui, page); + lang tool/getUserLanguage; + dir python: tool.getLanguageDirection(lang); + dleft python: (dir == 'ltr') and 'left' or 'right'; + dright python: (dir == 'ltr') and 'right' or 'left'; x python: resp.setHeader('Content-Type','text/html;;charset=utf-8'); x python: resp.setHeader('Expires', 'Mon, 11 Dec 1975 12:05:05 GMT'); - x python: resp.setHeader('Content-Language', req.get('language', 'en')); + x python: resp.setHeader('Content-Language', lang); x python: resp.setHeader('CacheControl', 'no-cache')"> Keys "Expires" and "CacheControl" are used for preventing IE to cache this page. Indeed, this page is retrieved through an asynchronous XMLHttpRequest by the browser, and diff --git a/gen/ui/appy.css b/gen/ui/appy.css index 485516d..ae4ddf6 100644 --- a/gen/ui/appy.css +++ b/gen/ui/appy.css @@ -92,6 +92,7 @@ img { border: 0; vertical-align: middle} .grid th { font-style: italic; font-weight: normal; border-bottom: 2px solid grey; padding: 2px 2px;} .grid td { padding-right: 5px; } +.cellGap { padding-right: 0.4em; } .noStyle { border: 0 !important; padding: 0 !important; margin: 0 !important; } .noStyle td { border:0 !important; padding:0 !important; margin:0 !important; } .translationLabel { background-color: #EAEAEA; border-bottom: 1px dashed grey; diff --git a/gen/ui/appyrtl.css b/gen/ui/appyrtl.css new file mode 100644 index 0000000..634370d --- /dev/null +++ b/gen/ui/appyrtl.css @@ -0,0 +1,7 @@ +ul { margin: 0 0.6em 0.2em 0 } +ul li { background-image: url("ui/lirtl.gif"); + background-position: right center; + padding-right: 15px; padding-left: 0px} +.portlet { border-right: none; border-left: 1px solid #5F7983 } +.lang { margin-right: 0px; margin-left: 6px; } +.cellGap { padding-left: 0.4em; } diff --git a/gen/ui/bannerrtl.jpg b/gen/ui/bannerrtl.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3a49971db11617e4d5516d124d296f6175e32cbd GIT binary patch literal 3751 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 literal 0 HcmV?d00001 diff --git a/gen/ui/footer.pt b/gen/ui/footer.pt index 1fdfc46..2e02f64 100644 --- a/gen/ui/footer.pt +++ b/gen/ui/footer.pt @@ -1,4 +1,4 @@ - + diff --git a/gen/ui/lirtl.gif b/gen/ui/lirtl.gif new file mode 100644 index 0000000000000000000000000000000000000000..db87f93e6f0f4c2ffaf5035548fe8533d6de234f GIT binary patch literal 50 zcmZ?wbhEHbWM^PyXkcUr3JUuF|G(l-7Df>UMg|=QAOOiQFmd`YOkZ*K*gR%d25SH= C +
Buttons for navigating among a list of elements (next, back, first, last, etc). diff --git a/gen/ui/page.pt b/gen/ui/page.pt index 84ef7e9..91a8181 100644 --- a/gen/ui/page.pt +++ b/gen/ui/page.pt @@ -72,10 +72,10 @@ - - - - + + + + - - + + @@ -157,7 +157,7 @@ Input field for storing comment Buttons for triggering transitions - diff --git a/gen/ui/portlet.pt b/gen/ui/portlet.pt index 8e8eaf0..7384b7b 100644 --- a/gen/ui/portlet.pt +++ b/gen/ui/portlet.pt @@ -62,10 +62,11 @@ expanded python: request.get(group['labelId'], 'collapsed') == 'expanded'"> Group name
- + onClick python:'toggleCookie(\'%s\')' % group['labelId']; + align dleft"/>
Group searches diff --git a/gen/ui/result.pt b/gen/ui/result.pt index ac84958..4e48db3 100644 --- a/gen/ui/result.pt +++ b/gen/ui/result.pt @@ -27,10 +27,10 @@ Display here POD templates if required. -
ActionByDateCommentActionByDateComment
+ Real button Creator and last modification date Plus/minus icon for accessing history -   History ||  @@ -233,7 +234,7 @@ - +
+ tal:condition="python: objs and widgets" + tal:attributes="align dright"> - @@ -118,7 +118,7 @@ tal:content="python: _(obj.portal_type)">Column "Actions" -
    @@ -55,7 +55,7 @@
+ Appy (top) navigation + Edit the element diff --git a/gen/ui/search.pt b/gen/ui/search.pt index 00704d9..fed0d57 100644 --- a/gen/ui/search.pt +++ b/gen/ui/search.pt @@ -39,7 +39,7 @@
Submit button -


+


diff --git a/gen/ui/template.pt b/gen/ui/template.pt index 6eee4e0..dca54d3 100644 --- a/gen/ui/template.pt +++ b/gen/ui/template.pt @@ -9,14 +9,19 @@ _ python: tool.translate; req python: request; resp req/RESPONSE; + lang tool/getUserLanguage; + dir python: tool.getLanguageDirection(lang); + dleft python: (dir == 'ltr') and 'left' or 'right'; + dright python: (dir == 'ltr') and 'right' or 'left'; x python: resp.setHeader('Content-type', 'text/html;;charset=UTF-8'); x python: resp.setHeader('Expires', 'Thu, 11 Dec 1975 12:05:00 GMT+2'); - x python: resp.setHeader('Content-Language', req.get('language', 'en'))"> + x python: resp.setHeader('Content-Language', lang)" + tal:attributes="dir python: tool.getLanguageDirection(lang)"> - @@ -27,16 +32,16 @@ Top banner - - Icon for removing the row -
+ - + Links to main pages - Language selector (links or listbox) -
- + @@ -51,7 +56,7 @@
-

+


@@ -143,7 +148,7 @@
+ diff --git a/gen/ui/widgets/list.pt b/gen/ui/widgets/list.pt index 3cad885..9aec355 100644 --- a/gen/ui/widgets/list.pt +++ b/gen/ui/widgets/list.pt @@ -9,7 +9,8 @@ + Actions - + diff --git a/gen/ui/widgets/show.pt b/gen/ui/widgets/show.pt index 2643aa0..1b79450 100644 --- a/gen/ui/widgets/show.pt +++ b/gen/ui/widgets/show.pt @@ -22,7 +22,7 @@ The table header rowThe table content
+ tal:attributes="align python: tool.flipLanguageDirection(cell['align'], dir); + width cell/width;">
+ tal:attributes="align python: tool.flipLanguageDirection(cell['align'], dir); + colspan cell/colspan; + class python: test(repeat['cell'].end, '', 'cellGap')">
@@ -153,7 +155,7 @@ Display the title of the group if it is not rendered a fieldset.The column headers diff --git a/shared/data/__init__.py b/shared/data/__init__.py index 1e9579a..ba08dd7 100644 --- a/shared/data/__init__.py +++ b/shared/data/__init__.py @@ -160,6 +160,9 @@ nativeNames = { 'zh' : '中文', 'zu' : 'isiZulu' } +# List of languages having direction right-to-left (RTL) ----------------------- +rtlLanguages = ('ar', 'he', 'fa') + # ------------------------------------------------------------------------------ class Languages: '''This class gives access to the language codes and names as standardized
+ class widget/style; + align dleft"> @@ -176,7 +179,7 @@