diff --git a/pyramid_formalchemy/actions.py b/pyramid_formalchemy/actions.py index 0e23486..97f830a 100644 --- a/pyramid_formalchemy/actions.py +++ b/pyramid_formalchemy/actions.py @@ -71,7 +71,7 @@ def action(name=None): objects = getattr(request.model_class, attr, None) if objects is None: objects = self.defaults_actions.get(attr, Actions()) - setattr(request, key, objects) + request.actions[key] = objects request.action = func.__name__ return func(self, *args, **kwargs) return wrapped @@ -117,8 +117,8 @@ class Action(object): localizer = get_localizer(request) mapping = getattr(request, 'action_mapping', {}) if not mapping: - for k in ('model_name', 'model_id'): - mapping[k] = getattr(request, k, '') + for k in ('model_name', 'model_label', 'model_id'): + mapping[k] = localizer.translate(getattr(request, k, '')) request.action_mapping = mapping for k in ('content', 'alt'): v = rcontext[k] @@ -201,7 +201,7 @@ class Option(Action): def update(self): if 'value' not in self.attrs: - self.attrs['value'] = self.rcontext.get('value', self) + self.attrs['value'] = self.rcontext.get('value', None) class UIButton(Action): """An action rendered as an jquery.ui aware link:: @@ -270,20 +270,28 @@ class Actions(list): """ tag = u'' def __init__(self, *args, **kwargs): + self.sep = kwargs.get('sep', u'\n') res = DottedNameResolver('pyramid_formalchemy.actions') list.__init__(self, [res.maybe_resolve(a) for a in args]) def render(self, request, **kwargs): - return u'\n'.join([a.render(request, **kwargs) for a in self]) + return self.sep.join([a.render(request, **kwargs) for a in self]) def __add__(self, other): actions = list(self)+list(other) - return self.__class__(*actions) + actions = self.__class__(*actions) + actions.sep = self.sep + return actions def __repr__(self): return '<%s %s>' % (self.__class__.__name__, list.__repr__(self)) +class RequestActions(dict): + """An action container used to store action in requests. + Return an empty Actions instance if actions are not found""" + def __getattr__(self, attr): + return self.get(attr, Actions()).render class Languages(Actions): """Languages actions:: @@ -322,7 +330,7 @@ class Languages(Actions): new = UIButton( id='new', - content=_('New ${model_name}'), + content=_('New ${model_label}'), icon='ui-icon-circle-plus', attrs=dict(href="request.fa_url(request.model_name, 'new')"), ) diff --git a/pyramid_formalchemy/i18n.py b/pyramid_formalchemy/i18n.py index 0a45e6a..b114440 100644 --- a/pyramid_formalchemy/i18n.py +++ b/pyramid_formalchemy/i18n.py @@ -5,3 +5,24 @@ from pyramid.i18n import get_localizer _ = TranslationStringFactory('pyramid_formalchemy') +class I18NModel(object): + + def __init__(self, context, request): + self.context = context + self.request = request + + @property + def label(self): + return getattr(self.context, '__label__', self.context.__name__) + + @property + def plural(self): + value = getattr(self.context, '__plural__', None) + if value: + return value + else: + return self.label + + def __getattr__(self, attr): + return getattr(self.context, attr) + diff --git a/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.mo b/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.mo index 6dcd2de..56f5e35 100644 Binary files a/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.mo and b/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.mo differ diff --git a/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.po b/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.po index e831c89..ae6fd1d 100644 --- a/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.po +++ b/pyramid_formalchemy/locale/fr/LC_MESSAGES/pyramid_formalchemy.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: pyramid_formalchemy 0.3\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2011-06-18 12:02+0200\n" -"PO-Revision-Date: 2011-06-18 19:54+0200\n" +"PO-Revision-Date: 2011-06-20 16:14+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: fr \n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" @@ -18,39 +18,39 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.5\n" -#: pyramid_formalchemy/actions.py:206 +#: pyramid_formalchemy/actions.py:312 msgid "French" msgstr "Français" -#: pyramid_formalchemy/actions.py:207 +#: pyramid_formalchemy/actions.py:313 msgid "English" msgstr "Anglais" -#: pyramid_formalchemy/actions.py:224 -msgid "New ${model_name}" -msgstr "Nouveau ${model_name}" +#: pyramid_formalchemy/actions.py:330 +msgid "New ${model_label}" +msgstr "Nouveau ${model_label}" -#: pyramid_formalchemy/actions.py:232 +#: pyramid_formalchemy/actions.py:338 msgid "Save" msgstr "Sauver" -#: pyramid_formalchemy/actions.py:239 +#: pyramid_formalchemy/actions.py:345 msgid "Save and add another" msgstr "Sauver et ajouter un autre" -#: pyramid_formalchemy/actions.py:248 +#: pyramid_formalchemy/actions.py:354 msgid "Edit" msgstr "Editer" -#: pyramid_formalchemy/actions.py:255 +#: pyramid_formalchemy/actions.py:361 msgid "Back" msgstr "Retour" -#: pyramid_formalchemy/actions.py:263 +#: pyramid_formalchemy/actions.py:369 msgid "Delete" msgstr "Supprimer" -#: pyramid_formalchemy/actions.py:274 +#: pyramid_formalchemy/actions.py:380 msgid "Cancel" msgstr "Annuler" diff --git a/pyramid_formalchemy/locale/pyramid_formalchemy.pot b/pyramid_formalchemy/locale/pyramid_formalchemy.pot index 726b3a2..6a4f6a7 100644 --- a/pyramid_formalchemy/locale/pyramid_formalchemy.pot +++ b/pyramid_formalchemy/locale/pyramid_formalchemy.pot @@ -7,9 +7,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: pyramid_formalchemy 0.3\n" +"Project-Id-Version: pyramid_formalchemy 0.4\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-06-18 19:54+0200\n" +"POT-Creation-Date: 2011-06-20 16:14+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,39 +18,39 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.5\n" -#: pyramid_formalchemy/actions.py:206 +#: pyramid_formalchemy/actions.py:312 msgid "French" msgstr "" -#: pyramid_formalchemy/actions.py:207 +#: pyramid_formalchemy/actions.py:313 msgid "English" msgstr "" -#: pyramid_formalchemy/actions.py:224 -msgid "New ${model_name}" +#: pyramid_formalchemy/actions.py:330 +msgid "New ${model_label}" msgstr "" -#: pyramid_formalchemy/actions.py:232 +#: pyramid_formalchemy/actions.py:338 msgid "Save" msgstr "" -#: pyramid_formalchemy/actions.py:239 +#: pyramid_formalchemy/actions.py:345 msgid "Save and add another" msgstr "" -#: pyramid_formalchemy/actions.py:248 +#: pyramid_formalchemy/actions.py:354 msgid "Edit" msgstr "" -#: pyramid_formalchemy/actions.py:255 +#: pyramid_formalchemy/actions.py:361 msgid "Back" msgstr "" -#: pyramid_formalchemy/actions.py:263 +#: pyramid_formalchemy/actions.py:369 msgid "Delete" msgstr "" -#: pyramid_formalchemy/actions.py:274 +#: pyramid_formalchemy/actions.py:380 msgid "Cancel" msgstr "" diff --git a/pyramid_formalchemy/resources.py b/pyramid_formalchemy/resources.py index 6fd7e3e..2b783d5 100644 --- a/pyramid_formalchemy/resources.py +++ b/pyramid_formalchemy/resources.py @@ -37,14 +37,12 @@ class Base(object): if self.__model_class__: request.model_class = self.__model_class__ request.model_name = self.__model_class__.__name__ + request.actions = actions.RequestActions() langs = request.registry.settings.get('available_languages', '') if langs: if isinstance(langs, basestring): langs = langs.split() - request.language_actions = actions.Languages(*langs) - else: - request.language_actions = actions.Actions() - + request.actions['languages'] = actions.Languages(*langs) def get_model(self): request = self.request diff --git a/pyramid_formalchemy/views.py b/pyramid_formalchemy/views.py index f297fff..5afc608 100644 --- a/pyramid_formalchemy/views.py +++ b/pyramid_formalchemy/views.py @@ -14,6 +14,7 @@ from pyramid.security import has_permission from pyramid import httpexceptions as exc from pyramid.exceptions import NotFound from pyramid_formalchemy.utils import TemplateEngine +from pyramid_formalchemy.i18n import I18NModel from pyramid_formalchemy import events from pyramid_formalchemy import actions @@ -65,12 +66,12 @@ class ModelView(object): def models(self, **kwargs): """Models index page""" request = self.request - models = {} + models = [] if isinstance(request.models, list): for model in request.models: if has_permission('view', model, request): key = model.__name__ - models[key] = request.fa_url(key, request.format) + models.append(model) else: for key, obj in request.models.__dict__.iteritems(): if not key.startswith('_'): @@ -78,7 +79,7 @@ class ModelView(object): try: if issubclass(obj, Document): if has_permission('view', obj, request): - models[key] = request.fa_url(key, request.format) + models.append(obj) continue except: pass @@ -89,10 +90,19 @@ class ModelView(object): if not isinstance(obj, type): continue if has_permission('view', obj, request): - models[key] = request.fa_url(key, request.format) + models.append(obj) + + results = {} + for m in models: + if request.format == 'html': + url = request.fa_url(m.__name__) + else: + url = request.fa_url(m.__name__, request.format) + results[I18NModel(m, request).plural] = url + if kwargs.get('json'): - return models - return self.render(models=models) + return results + return self.render(models=results) def sync(self, fs, id=None): """sync a record. If ``id`` is None add a new record else save current one.""" @@ -134,10 +144,13 @@ class ModelView(object): else: raise NotFound() + request.model_class = model_class = I18NModel(request.model_class, request) kwargs.update( main = get_renderer('pyramid_formalchemy:templates/admin/master.pt').implementation(), + model_class=model_class, model_name=request.model_name, breadcrumb=self.breadcrumb(**kwargs), + actions=request.actions, F_=get_translator()) return kwargs @@ -206,8 +219,11 @@ class ModelView(object): self.fieldset_class) if fs is self.fieldset_class: fs = fs(request.model_class) + if not isinstance(request.forms, list): + # add default fieldset to form module eg: caching + setattr(request.forms, form_name, fs) fs.engine = fs.engine or self.engine - fs = id and fs.bind(model) or fs + fs = id and fs.bind(model) or fs.copy() fs._request = request return fs @@ -215,15 +231,22 @@ class ModelView(object): """return a Grid object""" request = self.request model_name = request.model_name - if hasattr(request.forms, '%sGrid' % model_name): - g = getattr(request.forms, '%sGrid' % model_name) + form_name = '%sGrid' % model_name + if hasattr(request.forms, form_name): + g = getattr(request.forms, form_name) g.engine = g.engine or self.engine g.readonly = True + g._request = self.request self.update_grid(g) return g model = self.context.get_model() grid = self.grid_class(model) grid.engine = self.engine + if not isinstance(request.forms, list): + # add default grid to form module eg: caching + setattr(request.forms, form_name, grid) + grid = grid.copy() + grid._request = self.request self.update_grid(grid) return grid diff --git a/pyramidapp/pyramidapp/tests.py b/pyramidapp/pyramidapp/tests.py index 23bd758..989cef4 100644 --- a/pyramidapp/pyramidapp/tests.py +++ b/pyramidapp/pyramidapp/tests.py @@ -201,7 +201,7 @@ class Test_3_JQuery(Test_1_UI): # add page resp.mustcontain('/admin/Foo/new') - resp = resp.click('New Foo') + resp = resp.click(linkid='new') resp.mustcontain('/admin/Foo"') form = resp.forms[0] form['Foo--bar'] = 'value'