##// END OF EJS Templates
templater: abstract away from joinfmt...
Yuya Nishihara -
r37343:ebf139cb default
parent child Browse files
Show More
@@ -316,16 +316,16 b' def join(context, mapping, args):'
316 # i18n: "join" is a keyword
316 # i18n: "join" is a keyword
317 raise error.ParseError(_("join expects one or two arguments"))
317 raise error.ParseError(_("join expects one or two arguments"))
318
318
319 # TODO: perhaps this should be evalfuncarg(), but it can't because hgweb
320 # abuses generator as a keyword that returns a list of dicts.
321 joinset = evalrawexp(context, mapping, args[0])
319 joinset = evalrawexp(context, mapping, args[0])
322 joinset = templateutil.unwrapvalue(context, mapping, joinset)
323 joinfmt = getattr(joinset, 'joinfmt', pycompat.identity)
324 joiner = " "
320 joiner = " "
325 if len(args) > 1:
321 if len(args) > 1:
326 joiner = evalstring(context, mapping, args[1])
322 joiner = evalstring(context, mapping, args[1])
327 itemiter = (joinfmt(x) for x in pycompat.maybebytestr(joinset))
323 if isinstance(joinset, templateutil.wrapped):
328 return templateutil.joinitems(itemiter, joiner)
324 return joinset.join(context, mapping, joiner)
325 # TODO: perhaps a generator should be stringify()-ed here, but we can't
326 # because hgweb abuses it as a keyword that returns a list of dicts.
327 joinset = templateutil.unwrapvalue(context, mapping, joinset)
328 return templateutil.joinitems(pycompat.maybebytestr(joinset), joiner)
329
329
330 @templatefunc('label(label, expr)')
330 @templatefunc('label(label, expr)')
331 def label(context, mapping, args):
331 def label(context, mapping, args):
@@ -42,6 +42,15 b' class wrapped(object):'
42 """Yield each template mapping"""
42 """Yield each template mapping"""
43
43
44 @abc.abstractmethod
44 @abc.abstractmethod
45 def join(self, context, mapping, sep):
46 """Join items with the separator; Returns a bytes or (possibly nested)
47 generator of bytes
48
49 A pre-configured template may be rendered per item if this container
50 holds unprintable items.
51 """
52
53 @abc.abstractmethod
45 def show(self, context, mapping):
54 def show(self, context, mapping):
46 """Return a bytes or (possibly nested) generator of bytes representing
55 """Return a bytes or (possibly nested) generator of bytes representing
47 the underlying object
56 the underlying object
@@ -86,11 +95,15 b' class hybrid(wrapped):'
86 for x in self._values:
95 for x in self._values:
87 yield makemap(x)
96 yield makemap(x)
88
97
98 def join(self, context, mapping, sep):
99 # TODO: switch gen to (context, mapping) API?
100 return joinitems((self.joinfmt(x) for x in self._values), sep)
101
89 def show(self, context, mapping):
102 def show(self, context, mapping):
90 # TODO: switch gen to (context, mapping) API?
103 # TODO: switch gen to (context, mapping) API?
91 gen = self._gen
104 gen = self._gen
92 if gen is None:
105 if gen is None:
93 return joinitems((self.joinfmt(x) for x in self._values), ' ')
106 return self.join(context, mapping, ' ')
94 if callable(gen):
107 if callable(gen):
95 return gen()
108 return gen()
96 return gen
109 return gen
@@ -137,6 +150,14 b' class mappable(wrapped):'
137 def itermaps(self, context):
150 def itermaps(self, context):
138 yield self.tomap()
151 yield self.tomap()
139
152
153 def join(self, context, mapping, sep):
154 # TODO: just copies the old behavior where a value was a generator
155 # yielding one item, but reconsider about it. join() over a string
156 # has no consistent result because a string may be a bytes, or a
157 # generator yielding an item, or a generator yielding multiple items.
158 # Preserving all of the current behaviors wouldn't make any sense.
159 return self.show(context, mapping)
160
140 def show(self, context, mapping):
161 def show(self, context, mapping):
141 # TODO: switch gen to (context, mapping) API?
162 # TODO: switch gen to (context, mapping) API?
142 gen = self._gen
163 gen = self._gen
General Comments 0
You need to be logged in to leave comments. Login now