diff --git a/lib/nulib/python/nulib/base.py b/lib/nulib/python/nulib/base.py
index 075b77f..6b28271 100644
--- a/lib/nulib/python/nulib/base.py
+++ b/lib/nulib/python/nulib/base.py
@@ -36,7 +36,36 @@ mydir, myname = path.split(myself)
# Fonctions diverses
+_undef = object()
class Undef(object):
+ def sa(self, value, kw, name, default=_undef):
+ """si value est Undef, récupérer la valeur avec le nom court name dans kw
+ """
+ if default is _undef: default = self
+ if value is self and name is not None: value = kw.pop(name, self)
+ if value is self: value = default
+ return value
+
+ def __nonzero__(self):
+ return False
+ def __len__(self):
+ return 0
+ def __lt__(self, other):
+ if other: return True
+ else: return False
+ def __le__(self, other):
+ return True
+ def __eq__(self, other):
+ if other: return False
+ else: return True
+ def __ne__(self, other):
+ if other: return True
+ else: return False
+ def __gt__(self, other):
+ if other: return False
+ else: return True
+ def __ge__(self, other):
+ return True
def __repr__(self):
return 'Undef'
def __call__(self):
diff --git a/lib/nulib/python/nulib/web/api.py b/lib/nulib/python/nulib/web/api.py
index 24ee87d..66fb2c5 100644
--- a/lib/nulib/python/nulib/web/api.py
+++ b/lib/nulib/python/nulib/web/api.py
@@ -1,7 +1,11 @@
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
-__all__ = ('_weburl', '_ensure_session')
+__all__ = (
+ '_weburl', '_ensure_session',
+ 'u', 'uval',
+)
+from types import UnicodeType, StringType
from ..ext import web
def _weburl(path, __BASEURL, **kw):
@@ -14,3 +18,21 @@ def _ensure_session(page):
if session is None: raise ValueError("no session configured")
page.session = session
return session
+
+def u(text):
+ """Si text n'est pas de l'unicode, le convertir en unicode avec l'encoding utf-8
+ """
+ t = type(text)
+ if t is not UnicodeType:
+ if t is not StringType: text = str(text)
+ text = unicode(text, "utf-8")
+ return text
+
+def uval(value):
+ """Transformer value en unicode, en particulier s'il est callable ou s'il
+ a une méthode render()
+ """
+ if value is None: return None
+ if hasattr(value, 'render'): value = value.render()
+ if callable(value): value = value()
+ return u(value)
diff --git a/lib/nulib/python/nulib/web/bootstrap.py b/lib/nulib/python/nulib/web/bootstrap.py
index a34ac48..2b4b180 100644
--- a/lib/nulib/python/nulib/web/bootstrap.py
+++ b/lib/nulib/python/nulib/web/bootstrap.py
@@ -2,19 +2,22 @@
__all__ = (
'load',
+ 'table', 'tr', 'td',
+ 'Menu', 'Action',
'About',
'Alert', 'set_alert',
- 'Menu', 'Action',
)
import sys, traceback
+from types import StringType
-from ..base import seqof, Undef
+from ..base import isseq, seqof, Undef
from ..ext import web
from . import ui
-from .ui import Action, u, p
-from .api import _ensure_session
+from .api import _ensure_session, u, uval
+from .model import Row, TableSchema
+from .ui import Action, p
Undef = Undef() # spécifique à ce module
@@ -43,12 +46,98 @@ def load(prefix=None, icons=True, charset="utf-8"):
])
return u"\n".join(lines)
-def sa(value, kw, name, default=Undef):
- """si value est indéfini, récupérer la valeur avec le nom court dans kw
- """
- if value is Undef and name is not None: value = kw.pop(name, Undef)
- if value is Undef: value = default
- return value
+################################################################################
+# Table
+
+TRD_CLASS_MAP = dict(
+ active="active",
+ success="success", done="success",
+ info="info",
+ warning="warning", warn="warning", notice="warning",
+ danger="danger", error="danger",
+)
+def trd_joinc(css):
+ if css is Undef: css = None
+ if type(css) is StringType:
+ css = css.split(",")
+ classes = []
+ for css in seqof(css):
+ classes.append(TRD_CLASS_MAP.get(css, css))
+ css = ' '.join(classes)
+ return css
+
+def td(value, schema=None, css=Undef, tag=Undef, **kw):
+ css = Undef.sa(css, kw, 'c')
+ value = uval(value)
+ if schema:
+ value = schema.html(value)
+ if css is Undef: css = schema.css(value)
+ if tag is Undef: tag = 'td'
+ css = trd_joinc(css)
+ return u'<%s%s>%s%s>' % (tag, ui.classif(css), value, tag)
+
+def tr(values, schema=None, css=Undef, celltag=Undef, **kw):
+ css = Undef.sa(css, kw, 'c')
+ tdschema = lambda value, index: None
+ if schema is not None:
+ if css is Undef: css = schema.css(values)
+ tdschema = lambda value, index: schema.cell_schema(value, index)
+ css = trd_joinc(css)
+ lines = []
+ lines.append(u'
' % ui.classif(css))
+ index = 0
+ if isinstance(values, dict) or isinstance(values, Row):
+ if schema is not None:
+ for col in schema.cols:
+ value = values[col.key]
+ lines.append(td(value, tdschema(value, index), tag=celltag))
+ index += 1
+ else:
+ for value in values.values():
+ lines.append(td(value, tdschema(value, index), tag=celltag))
+ index += 1
+ else:
+ for value in values:
+ lines.append(td(value, tdschema(value, index), tag=celltag))
+ index += 1
+ lines.append(u'