Ticket #7316: 7316-timeline-render-hints-r7595.diff
| File 7316-timeline-render-hints-r7595.diff, 15.5 KB (added by cboos, 3 months ago) |
|---|
-
trac/attachment.py
42 42 INavigationContributor 43 43 from trac.web.href import Href 44 44 from trac.wiki.api import IWikiSyntaxProvider 45 from trac.wiki.formatter import format_to _oneliner45 from trac.wiki.formatter import format_to 46 46 47 47 48 48 class InvalidAttachment(TracError): … … 474 474 return tag(tag.em(os.path.basename(attachment.id)), 475 475 _(" attached to "), tag.em(name, title=title)) 476 476 elif field == 'description': 477 return format_to_oneliner(self.env, context(attachment.parent), 478 descr) 477 return format_to(self.env, None, context(attachment.parent), descr) 479 478 480 479 def get_search_results(self, req, resource_realm, terms): 481 480 """Return a search result generator suitable for ISearchSource. -
trac/mimeview/api.py
124 124 self.resource = resource 125 125 self.href = href 126 126 self.perm = resource and perm and perm(resource) or perm 127 self._hints = None 127 128 128 129 def from_request(cls, req, resource=None, id=False, version=False, 129 130 absurls=False): … … 171 172 context = context.parent 172 173 return '<%s %s>' % (type(self).__name__, ' - '.join(reversed(path))) 173 174 174 def __call__(self, resource , id=False, version=False):175 def __call__(self, resource=None, id=False, version=False): 175 176 """Create a nested rendering context. 176 177 177 178 `self` will be the parent for the new nested context. 178 179 179 180 :param resource: either a `Resource` object or the realm string for a 180 181 resource specification to be associated to the new 181 context 182 context. If `None`, the resource will be the same 183 as the resource of the parent context. 182 184 :param id: the identifier part of the resource specification 183 185 :param version: the version of the resource specification 184 186 :return: the new context object … … 190 192 True 191 193 >>> context(ticket1).resource is ticket1 192 194 True 195 >>> context(ticket1)().resource is ticket1 196 True 193 197 """ 194 resource = Resource(resource, id=id, version=version) 198 if resource: 199 resource = Resource(resource, id=id, version=version) 200 else: 201 resource = self.resource 195 202 context = Context(resource, href=self.href, perm=self.perm) 196 203 context.parent = self 197 204 … … 222 229 return True 223 230 context = context.parent 224 231 232 # Rendering hints 233 # 234 # A rendering hint is a key/value pairs that can influence renderers, 235 # wiki formatters and processors in the way they produce their output. 236 # The keys are strings, but the values could be anything. 237 # 238 # In nested contexts, the hints are inherited from their parent context, 239 # unless overriden locally. 225 240 241 def set_hints(self, **keyvalues): 242 """Set rendering hints for this rendering context. 243 244 >>> ctx = Context('timeline') 245 >>> ctx.set_hints(wiki_flavor='oneliner', shorten_lines=True) 246 >>> t_ctx = ctx('ticket', 1) 247 >>> t_ctx.set_hints(wiki_flavor='html', escape_newlines=True) 248 >>> (t_ctx.get_hint('wiki_flavor'), t_ctx.get_hint('shorten_lines'), \ 249 t_ctx.get_hint('escape_newlines')) 250 ('html', True, True) 251 >>> (ctx.get_hint('wiki_flavor'), ctx.get_hint('shorten_lines'), \ 252 ctx.get_hint('escape_newlines')) 253 ('oneliner', True, None) 254 """ 255 if self._hints is None: 256 self._hints = {} 257 hints = self._parent_hints() 258 if hints is not None: 259 self._hints.update(hints) 260 self._hints.update(keyvalues) 261 262 def get_hint(self, hint, default=None): 263 """Retrieve a rendering hint from this context or an ancestor context. 264 265 >>> ctx = Context('timeline') 266 >>> ctx.set_hints(wiki_flavor='oneliner') 267 >>> t_ctx = ctx('ticket', 1) 268 >>> t_ctx.get_hint('wiki_flavor') 269 'oneliner' 270 >>> t_ctx.get_hint('escape_newlines', True) 271 True 272 """ 273 hints = self._hints 274 if hints is None: 275 hints = self._parent_hints() 276 if hints is None: 277 return default 278 return hints.get(hint, default) 279 280 def has_hint(self, hint): 281 """Test whether a rendering hint is defined in this context or in some 282 ancestor context. 283 284 >>> ctx = Context('timeline') 285 >>> ctx.set_hints(wiki_flavor='oneliner') 286 >>> t_ctx = ctx('ticket', 1) 287 >>> t_ctx.has_hint('wiki_flavor') 288 True 289 >>> t_ctx.has_hint('escape_newlines') 290 False 291 """ 292 hints = self._hints 293 if hints is None: 294 hints = self._parent_hints() 295 if hints is None: 296 return False 297 return hint in hints 298 299 def _parent_hints(self): 300 p = self.parent 301 while p and p._hints is None: 302 p = p.parent 303 return p and p._hints 304 305 226 306 # Some common MIME types and their associated keywords and/or file extensions 227 307 228 308 KNOWN_MIME_TYPES = { -
trac/ticket/web_ui.py
113 113 114 114 timeline_newticket_formatter = Option('timeline', 'newticket_formatter', 115 115 'oneliner', 116 """Which formatter flavor (e.g. ' default' or 'oneliner') should be116 """Which formatter flavor (e.g. 'html' or 'oneliner') should be 117 117 used when presenting the description for new tickets. 118 118 If 'oneliner', the [timeline] abbreviated_messages option applies. 119 119 (''since 0.11'').""") … … 125 125 but keeps the old behavior for upgraded environments (i.e. 'no'). 126 126 (''since 0.11'').""") 127 127 128 def _must_preserve_newlines(self): 129 preserve_newlines = self.preserve_newlines 130 if preserve_newlines == 'default': 131 preserve_newlines = self.env.get_version(initial=True) >= 21 # 0.11 132 return preserve_newlines in _TRUE_VALUES 133 must_preserve_newlines = property(_must_preserve_newlines) 134 128 135 # IContentConverter methods 129 136 130 137 def get_supported_conversions(self): … … 339 346 descr = message = '' 340 347 if status == 'new': 341 348 message = description 342 flavor = self.timeline_newticket_formatter343 349 else: 344 350 descr = info 345 351 message = comment 346 flavor = 'oneliner' 347 if message: 348 if self.config['timeline'].getbool('abbreviated_messages'): 349 message = shorten_line(message) 350 descr += format_to(self.env, flavor, context(resource=ticket), 351 message) 352 return descr 352 t_context = context(resource=ticket) 353 t_context.set_hints(escape_newlines=self.must_preserve_newlines) 354 if status == 'new' and \ 355 context.get_hint('wiki_flavor') == 'oneliner': 356 flavor = self.timeline_newticket_formatter 357 t_context.set_hints(wiki_flavor=flavor, 358 shorten_lines=flavor == 'oneliner') 359 return descr + format_to(self.env, None, t_context, message) 353 360 354 361 # Internal methods 355 362 … … 578 585 return 'ticket.html', data, None 579 586 580 587 def _prepare_data(self, req, ticket, absurls=False): 581 preserve_newlines = self.preserve_newlines582 if preserve_newlines == 'default':583 preserve_newlines = self.env.get_version(initial=True) >= 21 # 0.11584 preserve_newlines = preserve_newlines in _TRUE_VALUES585 588 return {'ticket': ticket, 586 589 'context': Context.from_request(req, ticket.resource, 587 590 absurls=absurls), 588 'preserve_newlines': preserve_newlines}591 'preserve_newlines': self.must_preserve_newlines} 589 592 590 593 def _toggle_cc(self, req, cc): 591 594 """Return an (action, recipient) tuple corresponding to a change -
trac/ticket/roadmap.py
42 42 from trac.web.chrome import add_link, add_stylesheet, add_warning, \ 43 43 INavigationContributor 44 44 from trac.wiki.api import IWikiSyntaxProvider 45 from trac.wiki.formatter import format_to _html45 from trac.wiki.formatter import format_to 46 46 47 47 class ITicketGroupStatsProvider(Interface): 48 48 def get_ticket_group_stats(ticket_ids): … … 532 532 elif field == 'title': 533 533 return tag('Milestone ', tag.em(milestone.id), ' completed') 534 534 elif field == 'description': 535 return format_to _html(self.env, context(resource=milestone),536 shorten_line(description))535 return format_to(self.env, None, context(resource=milestone), 536 description) 537 537 538 538 # IRequestHandler methods 539 539 -
trac/versioncontrol/web_ui/changeset.py
47 47 from trac.web.chrome import add_ctxtnav, add_link, add_script, add_stylesheet, \ 48 48 prevnext_nav, INavigationContributor, Chrome 49 49 from trac.wiki import IWikiSyntaxProvider, WikiParser 50 from trac.wiki.formatter import format_to _html50 from trac.wiki.formatter import format_to 51 51 52 52 53 53 class IPropertyDiffRenderer(Interface): … … 824 824 return context.href.log(rev=rev_b, stop_rev=rev_a) 825 825 826 826 elif field == 'description': 827 if not self.timeline_long_messages:828 message = shorten_line(message)829 827 if self.wiki_format_messages: 830 828 markup = '' 829 if self.timeline_long_messages: # override default flavor 830 context = context() 831 context.set_hints(wiki_flavor='html') 831 832 else: 832 833 markup = message 833 834 message = None … … 861 862 files = files[:show_files] + [tag.li(u'\u2026')] 862 863 markup = tag(tag.ul(files, class_="changes"), markup) 863 864 if message: 864 markup += format_to _html(self.env, context, message)865 markup += format_to(self.env, None, context, message) 865 866 return markup 866 867 867 868 if rev_a == rev_b: -
trac/wiki/web_ui.py
41 41 INavigationContributor, ITemplateProvider 42 42 from trac.web import IRequestHandler 43 43 from trac.wiki.api import IWikiPageManipulator, WikiSystem 44 from trac.wiki.formatter import format_to _oneliner44 from trac.wiki.formatter import format_to 45 45 from trac.wiki.model import WikiPage 46 46 47 47 class InvalidWikiPage(TracError): … … 600 600 return tag(tag.em(get_resource_name(self.env, wiki_page)), 601 601 wiki_page.version > 1 and ' edited' or ' created') 602 602 elif field == 'description': 603 if self.config['timeline'].getbool('abbreviated_messages'): 604 comment = shorten_line(comment) 605 markup = format_to_oneliner(self.env, context(resource=wiki_page), 606 comment) 603 markup = format_to(self.env, None, context(resource=wiki_page), 604 comment) 607 605 if wiki_page.version > 1: 608 606 diff_href = context.href.wiki( 609 607 wiki_page.id, version=wiki_page.version, action='diff') -
trac/wiki/formatter.py
1085 1085 1086 1086 1087 1087 def format_to(env, flavor, context, wikidom, **options): 1088 if flavor is None: 1089 flavor = context.get_hint('wiki_flavor', 'html') 1088 1090 if flavor == 'oneliner': 1089 1091 return format_to_oneliner(env, context, wikidom, **options) 1090 1092 else: 1091 1093 return format_to_html(env, context, wikidom, **options) 1092 1094 1093 def format_to_html(env, context, wikidom, escape_newlines= False):1095 def format_to_html(env, context, wikidom, escape_newlines=None): 1094 1096 if not wikidom: 1095 1097 return Markup() 1098 if escape_newlines is None: 1099 escape_newlines = context.get_hint('escape_newlines', False) 1096 1100 return HtmlFormatter(env, context, wikidom).generate(escape_newlines) 1097 1101 1098 def format_to_oneliner(env, context, wikidom, shorten= False):1102 def format_to_oneliner(env, context, wikidom, shorten=None): 1099 1103 if not wikidom: 1100 1104 return Markup() 1105 if shorten is None: 1106 shorten = context.get_hint('shorten_lines', False) 1101 1107 return InlineHtmlFormatter(env, context, wikidom).generate(shorten) 1102 1108 1103 1109 def extract_link(env, context, wikidom): -
trac/timeline/web_ui.py
58 58 Timeline. (''since 0.11'')""") 59 59 60 60 abbreviated_messages = BoolOption('timeline', 'abbreviated_messages', 61 'true',61 True, 62 62 """Whether wiki-formatted event messages should be truncated or not. 63 63 64 64 This only affects the default rendering, and can be overriden by … … 179 179 if email: 180 180 email_map[username] = email 181 181 data['email_map'] = email_map 182 data['context'] = Context.from_request(req, absurls=True) 182 rss_context = Context.from_request(req, absurls=True) 183 rss_context.set_hints(wiki_flavor='html', shorten_lines=False) 184 data['context'] = rss_context 183 185 return 'timeline.rss', data, 'application/rss+xml' 184 186 else: 185 187 req.session['timeline.daysback'] = daysback 188 html_context = Context.from_request(req, absurls=True) 189 html_context.set_hints(wiki_flavor='oneliner', 190 shorten_lines=self.abbreviated_messages) 191 data['context'] = html_context 186 192 187 193 add_stylesheet(req, 'common/css/timeline.css') 188 194 rss_href = req.href.timeline([(f, 'on') for f in filters], … … 284 290 kind, date, author, data, provider = event 285 291 else: 286 292 kind, date, author, data = event 287 render = lambda field, context: provider.render_timeline_event(288 context, field, event)293 render = lambda field, context: \ 294 provider.render_timeline_event(context, field, event) 289 295 if isinstance(date, datetime): 290 296 dateuid = to_timestamp(date) 291 297 else:
