@@ -326,6 +326,7 @@ class HTMLDatabase:
326326 '''
327327 def __init__ (self , client ):
328328 self ._client = client
329+ self ._ = client ._
329330 self ._db = client .db
330331
331332 # we want config to be exposed
@@ -441,6 +442,7 @@ class HTMLClass(HTMLInputMixin, HTMLPermissions):
441442 '''
442443 def __init__ (self , client , classname , anonymous = 0 ):
443444 self ._client = client
445+ self ._ = client ._
444446 self ._db = client .db
445447 self ._anonymous = anonymous
446448
@@ -657,7 +659,7 @@ def submit(self, label=''"Submit New Entry"):
657659
658660 def history (self ):
659661 if not self .is_view_ok ():
660- return _ ('[hidden]' )
662+ return self . _ ('[hidden]' )
661663 return self ._ ('New node - no history' )
662664
663665 def renderWith (self , name , ** kwargs ):
@@ -776,7 +778,7 @@ def journal(self, direction='descending'):
776778
777779 def history (self , direction = 'descending' , dre = re .compile ('^\d+$' )):
778780 if not self .is_view_ok ():
779- return _ ('[hidden]' )
781+ return self . _ ('[hidden]' )
780782
781783 # pre-load the history with the current state
782784 current = {}
@@ -1064,6 +1066,7 @@ def __init__(self, client, classname, nodeid, prop, name, value,
10641066 anonymous = 0 ):
10651067 self ._client = client
10661068 self ._db = client .db
1069+ self ._ = client ._
10671070 self ._classname = classname
10681071 self ._nodeid = nodeid
10691072 self ._prop = prop
@@ -1149,7 +1152,7 @@ def plain(self, escape=0, hyperlink=0):
11491152 addresses and designators
11501153 '''
11511154 if not self .is_view_ok ():
1152- return _ ('[hidden]' )
1155+ return self . _ ('[hidden]' )
11531156
11541157 if self ._value is None :
11551158 return ''
@@ -1170,7 +1173,7 @@ def stext(self, escape=0):
11701173 This requires the StructureText module to be installed separately.
11711174 '''
11721175 if not self .is_view_ok ():
1173- return _ ('[hidden]' )
1176+ return self . _ ('[hidden]' )
11741177
11751178 s = self .plain (escape = escape )
11761179 if not StructuredText :
@@ -1214,7 +1217,7 @@ def email(self, escape=1):
12141217 ''' Render the value of the property as an obscured email address
12151218 '''
12161219 if not self .is_view_ok ():
1217- return _ ('[hidden]' )
1220+ return self . _ ('[hidden]' )
12181221
12191222 if self ._value is None :
12201223 value = ''
@@ -1236,7 +1239,7 @@ def plain(self):
12361239 ''' Render a "plain" representation of the property
12371240 '''
12381241 if not self .is_view_ok ():
1239- return _ ('[hidden]' )
1242+ return self . _ ('[hidden]' )
12401243
12411244 if self ._value is None :
12421245 return ''
@@ -1270,7 +1273,7 @@ def plain(self):
12701273 ''' Render a "plain" representation of the property
12711274 '''
12721275 if not self .is_view_ok ():
1273- return _ ('[hidden]' )
1276+ return self . _ ('[hidden]' )
12741277
12751278 if self ._value is None :
12761279 return ''
@@ -1309,7 +1312,7 @@ def plain(self):
13091312 ''' Render a "plain" representation of the property
13101313 '''
13111314 if not self .is_view_ok ():
1312- return _ ('[hidden]' )
1315+ return self . _ ('[hidden]' )
13131316
13141317 if self ._value is None :
13151318 return ''
@@ -1360,7 +1363,7 @@ def plain(self):
13601363 ''' Render a "plain" representation of the property
13611364 '''
13621365 if not self .is_view_ok ():
1363- return _ ('[hidden]' )
1366+ return self . _ ('[hidden]' )
13641367
13651368 if self ._value is None :
13661369 return ''
@@ -1377,7 +1380,7 @@ def now(self, str_interval=None):
13771380 DateHTMLProperty.
13781381 '''
13791382 if not self .is_view_ok ():
1380- return _ ('[hidden]' )
1383+ return self . _ ('[hidden]' )
13811384
13821385 ret = date .Date ('.' , translator = self ._client )
13831386
@@ -1421,7 +1424,7 @@ def field(self, size=30, default=None, format=_marker):
14211424 elif isinstance (default , DateHTMLProperty ):
14221425 raw_value = default ._value
14231426 else :
1424- raise ValueError , _ ('default value for '
1427+ raise ValueError , self . _ ('default value for '
14251428 'DateHTMLProperty must be either DateHTMLProperty '
14261429 'or string date representation.' )
14271430 elif isinstance (value , str ) or isinstance (value , unicode ):
@@ -1453,7 +1456,7 @@ def reldate(self, pretty=1):
14531456 If the "pretty" flag is true, then make the display pretty.
14541457 '''
14551458 if not self .is_view_ok ():
1456- return _ ('[hidden]' )
1459+ return self . _ ('[hidden]' )
14571460
14581461 if not self ._value :
14591462 return ''
@@ -1473,7 +1476,7 @@ def pretty(self, format=_marker):
14731476 for the situatin when a date only specifies a month and a year.
14741477 '''
14751478 if not self .is_view_ok ():
1476- return _ ('[hidden]' )
1479+ return self . _ ('[hidden]' )
14771480
14781481 if not self ._value :
14791482 return ''
@@ -1486,7 +1489,7 @@ def local(self, offset):
14861489 ''' Return the date/time as a local (timezone offset) date/time.
14871490 '''
14881491 if not self .is_view_ok ():
1489- return _ ('[hidden]' )
1492+ return self . _ ('[hidden]' )
14901493
14911494 return DateHTMLProperty (self ._client , self ._classname , self ._nodeid ,
14921495 self ._prop , self ._formname , self ._value , offset = offset )
@@ -1503,7 +1506,7 @@ def plain(self):
15031506 ''' Render a "plain" representation of the property
15041507 '''
15051508 if not self .is_view_ok ():
1506- return _ ('[hidden]' )
1509+ return self . _ ('[hidden]' )
15071510
15081511 if self ._value is None :
15091512 return ''
@@ -1513,7 +1516,7 @@ def pretty(self):
15131516 ''' Render the interval in a pretty format (eg. "yesterday")
15141517 '''
15151518 if not self .is_view_ok ():
1516- return _ ('[hidden]' )
1519+ return self . _ ('[hidden]' )
15171520
15181521 return self ._value .pretty ()
15191522
@@ -1554,15 +1557,16 @@ def __getattr__(self, attr):
15541557 ''' return a new HTMLItem '''
15551558 #print 'Link.getattr', (self, attr, self._value)
15561559 if not self ._value :
1557- raise AttributeError , "Can't access missing value"
1560+ msg = self ._ ('Attempt to look up %(attr)s on a missing value' )
1561+ return MissingValue (msg % locals ())
15581562 i = HTMLItem (self ._client , self ._prop .classname , self ._value )
15591563 return getattr (i , attr )
15601564
15611565 def plain (self , escape = 0 ):
15621566 ''' Render a "plain" representation of the property
15631567 '''
15641568 if not self .is_view_ok ():
1565- return _ ('[hidden]' )
1569+ return self . _ ('[hidden]' )
15661570
15671571 if self ._value is None :
15681572 return ''
@@ -1729,7 +1733,7 @@ def plain(self, escape=0):
17291733 ''' Render a "plain" representation of the property
17301734 '''
17311735 if not self .is_view_ok ():
1732- return _ ('[hidden]' )
1736+ return self . _ ('[hidden]' )
17331737
17341738 linkcl = self ._db .classes [self ._prop .classname ]
17351739 k = linkcl .labelprop (1 )
@@ -2294,4 +2298,29 @@ def __getattr__(self, name):
22942298 raise AttributeError , name
22952299 return self .client .instance .templating_utils [name ]
22962300
2301+ class MissingValue :
2302+ def __init__ (self , description , ** kwargs ):
2303+ self .__description = description
2304+ for key , value in kwargs .items ():
2305+ self .__dict__ [key ] = value
2306+
2307+ def __call__ (self , * args , ** kwargs ): return MissingValue (self .__description )
2308+ def __getattr__ (self , name ):
2309+ # This allows assignments which assume all intermediate steps are Null
2310+ # objects if they don't exist yet.
2311+ #
2312+ # For example (with just 'client' defined):
2313+ #
2314+ # client.db.config.TRACKER_WEB = 'BASE/'
2315+ self .__dict__ [name ] = MissingValue (self .__description )
2316+ return getattr (self , name )
2317+
2318+ def __getitem__ (self , key ): return self
2319+ def __nonzero__ (self ): return 0
2320+ def __str__ (self ): return '[%s]' % self .__description
2321+ def __repr__ (self ): return '<MissingValue 0x%x "%s">' % (id (self ),
2322+ self .__description )
2323+ def gettext (self , str ): return str
2324+ _ = gettext
2325+
22972326# vim: set et sts=4 sw=4 :
0 commit comments