@@ -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
@@ -668,7 +670,7 @@ def submit(self, label=''"Submit New Entry"):
668670
669671 def history (self ):
670672 if not self .is_view_ok ():
671- return _ ('[hidden]' )
673+ return self . _ ('[hidden]' )
672674 return self ._ ('New node - no history' )
673675
674676 def renderWith (self , name , ** kwargs ):
@@ -787,7 +789,7 @@ def journal(self, direction='descending'):
787789
788790 def history (self , direction = 'descending' , dre = re .compile ('^\d+$' )):
789791 if not self .is_view_ok ():
790- return _ ('[hidden]' )
792+ return self . _ ('[hidden]' )
791793
792794 # pre-load the history with the current state
793795 current = {}
@@ -1075,6 +1077,7 @@ def __init__(self, client, classname, nodeid, prop, name, value,
10751077 anonymous = 0 ):
10761078 self ._client = client
10771079 self ._db = client .db
1080+ self ._ = client ._
10781081 self ._classname = classname
10791082 self ._nodeid = nodeid
10801083 self ._prop = prop
@@ -1160,7 +1163,7 @@ def plain(self, escape=0, hyperlink=0):
11601163 addresses and designators
11611164 '''
11621165 if not self .is_view_ok ():
1163- return _ ('[hidden]' )
1166+ return self . _ ('[hidden]' )
11641167
11651168 if self ._value is None :
11661169 return ''
@@ -1181,7 +1184,7 @@ def stext(self, escape=0):
11811184 This requires the StructureText module to be installed separately.
11821185 '''
11831186 if not self .is_view_ok ():
1184- return _ ('[hidden]' )
1187+ return self . _ ('[hidden]' )
11851188
11861189 s = self .plain (escape = escape )
11871190 if not StructuredText :
@@ -1225,7 +1228,7 @@ def email(self, escape=1):
12251228 ''' Render the value of the property as an obscured email address
12261229 '''
12271230 if not self .is_view_ok ():
1228- return _ ('[hidden]' )
1231+ return self . _ ('[hidden]' )
12291232
12301233 if self ._value is None :
12311234 value = ''
@@ -1247,7 +1250,7 @@ def plain(self):
12471250 ''' Render a "plain" representation of the property
12481251 '''
12491252 if not self .is_view_ok ():
1250- return _ ('[hidden]' )
1253+ return self . _ ('[hidden]' )
12511254
12521255 if self ._value is None :
12531256 return ''
@@ -1281,7 +1284,7 @@ def plain(self):
12811284 ''' Render a "plain" representation of the property
12821285 '''
12831286 if not self .is_view_ok ():
1284- return _ ('[hidden]' )
1287+ return self . _ ('[hidden]' )
12851288
12861289 if self ._value is None :
12871290 return ''
@@ -1320,7 +1323,7 @@ def plain(self):
13201323 ''' Render a "plain" representation of the property
13211324 '''
13221325 if not self .is_view_ok ():
1323- return _ ('[hidden]' )
1326+ return self . _ ('[hidden]' )
13241327
13251328 if self ._value is None :
13261329 return ''
@@ -1371,7 +1374,7 @@ def plain(self):
13711374 ''' Render a "plain" representation of the property
13721375 '''
13731376 if not self .is_view_ok ():
1374- return _ ('[hidden]' )
1377+ return self . _ ('[hidden]' )
13751378
13761379 if self ._value is None :
13771380 return ''
@@ -1388,7 +1391,7 @@ def now(self, str_interval=None):
13881391 DateHTMLProperty.
13891392 '''
13901393 if not self .is_view_ok ():
1391- return _ ('[hidden]' )
1394+ return self . _ ('[hidden]' )
13921395
13931396 ret = date .Date ('.' , translator = self ._client )
13941397
@@ -1432,7 +1435,7 @@ def field(self, size=30, default=None, format=_marker):
14321435 elif isinstance (default , DateHTMLProperty ):
14331436 raw_value = default ._value
14341437 else :
1435- raise ValueError , _ ('default value for '
1438+ raise ValueError , self . _ ('default value for '
14361439 'DateHTMLProperty must be either DateHTMLProperty '
14371440 'or string date representation.' )
14381441 elif isinstance (value , str ) or isinstance (value , unicode ):
@@ -1464,7 +1467,7 @@ def reldate(self, pretty=1):
14641467 If the "pretty" flag is true, then make the display pretty.
14651468 '''
14661469 if not self .is_view_ok ():
1467- return _ ('[hidden]' )
1470+ return self . _ ('[hidden]' )
14681471
14691472 if not self ._value :
14701473 return ''
@@ -1484,7 +1487,7 @@ def pretty(self, format=_marker):
14841487 for the situatin when a date only specifies a month and a year.
14851488 '''
14861489 if not self .is_view_ok ():
1487- return _ ('[hidden]' )
1490+ return self . _ ('[hidden]' )
14881491
14891492 if not self ._value :
14901493 return ''
@@ -1497,7 +1500,7 @@ def local(self, offset):
14971500 ''' Return the date/time as a local (timezone offset) date/time.
14981501 '''
14991502 if not self .is_view_ok ():
1500- return _ ('[hidden]' )
1503+ return self . _ ('[hidden]' )
15011504
15021505 return DateHTMLProperty (self ._client , self ._classname , self ._nodeid ,
15031506 self ._prop , self ._formname , self ._value , offset = offset )
@@ -1514,7 +1517,7 @@ def plain(self):
15141517 ''' Render a "plain" representation of the property
15151518 '''
15161519 if not self .is_view_ok ():
1517- return _ ('[hidden]' )
1520+ return self . _ ('[hidden]' )
15181521
15191522 if self ._value is None :
15201523 return ''
@@ -1524,7 +1527,7 @@ def pretty(self):
15241527 ''' Render the interval in a pretty format (eg. "yesterday")
15251528 '''
15261529 if not self .is_view_ok ():
1527- return _ ('[hidden]' )
1530+ return self . _ ('[hidden]' )
15281531
15291532 return self ._value .pretty ()
15301533
@@ -1565,15 +1568,16 @@ def __getattr__(self, attr):
15651568 ''' return a new HTMLItem '''
15661569 #print 'Link.getattr', (self, attr, self._value)
15671570 if not self ._value :
1568- raise AttributeError , "Can't access missing value"
1571+ msg = self ._ ('Attempt to look up %(attr)s on a missing value' )
1572+ return MissingValue (msg % locals ())
15691573 i = HTMLItem (self ._client , self ._prop .classname , self ._value )
15701574 return getattr (i , attr )
15711575
15721576 def plain (self , escape = 0 ):
15731577 ''' Render a "plain" representation of the property
15741578 '''
15751579 if not self .is_view_ok ():
1576- return _ ('[hidden]' )
1580+ return self . _ ('[hidden]' )
15771581
15781582 if self ._value is None :
15791583 return ''
@@ -1760,7 +1764,7 @@ def plain(self, escape=0):
17601764 ''' Render a "plain" representation of the property
17611765 '''
17621766 if not self .is_view_ok ():
1763- return _ ('[hidden]' )
1767+ return self . _ ('[hidden]' )
17641768
17651769 linkcl = self ._db .classes [self ._prop .classname ]
17661770 k = linkcl .labelprop (1 )
@@ -2330,4 +2334,29 @@ def __getattr__(self, name):
23302334 raise AttributeError , name
23312335 return self .client .instance .templating_utils [name ]
23322336
2337+ class MissingValue :
2338+ def __init__ (self , description , ** kwargs ):
2339+ self .__description = description
2340+ for key , value in kwargs .items ():
2341+ self .__dict__ [key ] = value
2342+
2343+ def __call__ (self , * args , ** kwargs ): return MissingValue (self .__description )
2344+ def __getattr__ (self , name ):
2345+ # This allows assignments which assume all intermediate steps are Null
2346+ # objects if they don't exist yet.
2347+ #
2348+ # For example (with just 'client' defined):
2349+ #
2350+ # client.db.config.TRACKER_WEB = 'BASE/'
2351+ self .__dict__ [name ] = MissingValue (self .__description )
2352+ return getattr (self , name )
2353+
2354+ def __getitem__ (self , key ): return self
2355+ def __nonzero__ (self ): return 0
2356+ def __str__ (self ): return '[%s]' % self .__description
2357+ def __repr__ (self ): return '<MissingValue 0x%x "%s">' % (id (self ),
2358+ self .__description )
2359+ def gettext (self , str ): return str
2360+ _ = gettext
2361+
23332362# vim: set et sts=4 sw=4 :
0 commit comments