Edgewall Software

This page documents the 1.4 (latest stable) release. Documentation for other releases can be found here.

TicketQuery Wiki Macro

The TicketQuery macro lets you display ticket information anywhere that accepts WikiFormatting. The query language used by the [[TicketQuery]] macro is described in the TracQuery page.

Usage

[[TicketQuery]]

Wiki macro listing tickets that match certain criteria.

This macro accepts a comma-separated list of keyed parameters, in the form "key=value".

If the key is the name of a field, the value must use the syntax of a filter specifier as defined in TracQuery#QueryLanguage. Note that this is not the same as the simplified URL syntax used for query: links starting with a ? character. Commas (,) can be included in field values by escaping them with a backslash (\).

Groups of field constraints to be OR-ed together can be separated by a literal or argument.

In addition to filters, several other named parameters can be used to control how the results are presented. All of them are optional.

The format parameter determines how the list of tickets is presented:

  • list — the default presentation is to list the ticket ID next to the summary, with each ticket on a separate line.
  • compact — the tickets are presented as a comma-separated list of ticket IDs.
  • count — only the count of matching tickets is displayed
  • rawcount — only the count of matching tickets is displayed, not even with a link to the corresponding query (since 1.1.1)
  • table — a view similar to the custom query view (but without the controls)
  • progress — a view similar to the milestone progress bars

The max parameter can be used to limit the number of tickets shown (defaults to 0, i.e. no maximum).

The order parameter sets the field used for ordering tickets (defaults to id).

The desc parameter indicates whether the order of the tickets should be reversed (defaults to false).

The group parameter sets the field used for grouping tickets (defaults to not being set).

The groupdesc parameter indicates whether the natural display order of the groups should be reversed (defaults to false).

The verbose parameter can be set to a true value in order to get the description for the listed tickets. For table format only. deprecated in favor of the rows parameter

The rows parameter can be used to specify which field(s) should be viewed as a row, e.g. rows=description|summary

The col parameter can be used to specify which fields should be viewed as columns. For table format only.

For compatibility with Trac 0.10, if there's a last positional parameter given to the macro, it will be used to specify the format. Also, using "&" as a field separator still works (except for order) but is deprecated.

Examples

Example Result Macro
Number of Triage tickets: 24 [[TicketQuery(status=new&milestone=,count)]]
Number of new tickets: 1067 [[TicketQuery(status=new,count)]]
Number of reopened tickets: 4 [[TicketQuery(status=reopened,count)]]
Number of assigned tickets: 24 [[TicketQuery(status=assigned,count)]]
Number of invalid tickets: 1514 [[TicketQuery(status=closed,resolution=invalid,count)]]
Number of worksforme tickets: 1420 [[TicketQuery(status=closed,resolution=worksforme,count)]]
Number of duplicate tickets: 2192 [[TicketQuery(status=closed,resolution=duplicate,count)]]
Number of wontfix tickets: 994 [[TicketQuery(status=closed,resolution=wontfix,count)]]
Number of fixed tickets: 4595 [[TicketQuery(status=closed,resolution=fixed,count)]]
Number of untriaged tickets (milestone unset): 26 [[TicketQuery(status!=closed,milestone=,count)]]
Total number of tickets: 12406 [[TicketQuery(count)]]
Number of tickets reported or owned by current user: 1851 [[TicketQuery(reporter=$USER,or,owner=$USER,count)]]
Number of tickets created this month: 9 [[TicketQuery(created=thismonth..,count)]]
Number of closed Firefox tickets: 13 [[TicketQuery(status=closed,keywords~=firefox,count)]]
Number of closed Opera tickets: 12 [[TicketQuery(status=closed,keywords~=opera,count)]]
Number of closed tickets affecting Firefox and Opera: 1 [[TicketQuery(status=closed,keywords~=firefox opera,count)]]
Number of closed tickets affecting Firefox or Opera: 24 [[TicketQuery(status=closed,keywords~=firefox|opera,count)]]
Number of tickets that affect Firefox or are closed and affect Opera: 25 [[TicketQuery(status=closed,keywords~=opera,or,keywords~=firefox,count)]]
Number of closed Firefox tickets that don't affect Opera: 1 [[TicketQuery(status=closed,keywords~=firefox -opera,count)]]
Last 3 modified tickets: #13871, #13872, #13869 [[TicketQuery(max=3,order=modified,desc=1,compact)]]

Details of ticket #1:

[[TicketQuery(id=1,col=id|owner|reporter,rows=summary,table)]]

Ticket Owner Reporter
#1 anonymous
Summary Add a new project summary module.

Format: list

[[TicketQuery(version=0.6|0.7&resolution=duplicate)]]

This is displayed as:

#181
Wiki preview injects new lines
#204
request for colour legend (or something similar) for ticket groups in reports
#226
Ticket Dependencies
#239
Link to diff of specifik wiki change instead of the page itself
#351
All ticket modifications should be tracked in timeline
#413
Installing on Windows, drive other than C:
#450
Diffviewer should try to convert the text into utf-8.
#475
merging of similar tickets
#519
Python process sometimes hangs on Windows Server 2003
#529
IE 5-6 over HTTPS broken downloads

[[TicketQuery(id=123)]]

This is displayed as:

#123
No SQL error display

Format: compact

[[TicketQuery(version=0.6|0.7&resolution=duplicate, compact)]]

This is displayed as:

#181, #204, #226, #239, #351, #413, #450, #475, #519, #529

Format: count

[[TicketQuery(version=0.6|0.7&resolution=duplicate, count)]]

This is displayed as:

10

Format: progress

[[TicketQuery(milestone=0.12.8&group=type,format=progress)]]

This is displayed as:

defect

5 / 5

enhancement

2 / 2

Format: table

You can choose the columns displayed in the table format (format=table) using col=<field>. You can specify multiple fields and the order they are displayed in by placing pipes (|) between the columns:

[[TicketQuery(max=3,status=closed,order=id,desc=1,format=table,col=resolution|summary|owner|reporter)]]

This is displayed as:

Full rows

In table format you can specify full rows using rows=<field>:

[[TicketQuery(max=3,status=closed,order=id,desc=1,format=table,col=resolution|summary|owner|reporter,rows=description)]]

This is displayed as:

Results (1 - 3 of 11311)

1 2 3 4 5 6 7 8 9 10 11
Ticket Resolution Summary Owner Reporter
#13871 fixed Daysback in timeline page has off-by-one issue Jun Omae Jun Omae
Description

When submitting form in timeline page with 1 in daysback field, the user expects searching events between yesterday of the from date and the from date (just one day). However, it actually searches events between 2 days ago of the from date and the from date.

Also, entering 0 in the daysback field, the timeline page treat as 1. As the result, it is unable to search events for just one day. Before Trac 1.2, entering 0 in the daysback field is able to search events for just one day.

  • trac/timeline/web_ui.py

    diff --git a/trac/timeline/web_ui.py b/trac/timeline/web_ui.py
    index 719618fd2..c186add27 100644
    a b class TimelineModule(Component):  
    174174
    175175        stop = fromdate
    176176        start = to_datetime(stop.replace(tzinfo=None) -
    177                             timedelta(days=daysback + 1), req.tz)
     177                            timedelta(days=daysback), req.tz)
    178178
    179179        # create author include and exclude sets
    180180        include = set()
  • trac/timeline/tests/web_ui.py

    diff --git a/trac/timeline/tests/web_ui.py b/trac/timeline/tests/web_ui.py
    index 0877c6225..b917b0e30 100644
    a b class TimelineEventProviderTestCase(unittest.TestCase):  
    225225                yield ('test', 'Test')
    226226
    227227            def get_timeline_events(self, req, start, stop, filters):
    228                 return iter(self._events or ())
     228                for event in self._events:
     229                    if start <= event[1] <= stop:
     230                        yield event
    229231
    230232            def render_timeline_event(self, context, field, event):
    231233                return event[3].render(context, field, event)
    class TimelineEventProviderTestCase(unittest.TestCase):  
    270272            ('test&2', datetime(2018, 3, 19, 23, 56, 12, 987654, utc),
    271273             'Joe <joe@example.org>', Mock(render=render)),
    272274        ]
    273         req = MockRequest(self.env, path_info='/timeline',
    274                           args={'format': 'rss'})
     275        req = MockRequest(self.env, path_info='/timeline', tz=utc,
     276                          args={'format': 'rss', 'daysback': '90',
     277                                'from': '2018-04-30T00:00:00Z'})
    275278        rv = self._process_request(req)
    276279        self.assertEqual('timeline.rss', rv[0])
    277280        self.assertEqual({'content_type': 'application/rss+xml'}, rv[2])
    class TimelineEventProviderTestCase(unittest.TestCase):  
    307310        self.assertEqual('<?xml version="1.0"?>', output[:21])
    308311        minidom.parseString(output)  # verify valid xml
    309312
     313    def test_daysback(self):
     314        provider = self.timeline_event_providers['normal'](self.env)
     315        provider._events = [
     316            ('test', datetime(2025, 2, 19, 12, tzinfo=utc),
     317             'trac', None),
     318            ('test', datetime(2025, 2, 18, 12, tzinfo=utc),
     319             'trac', None),
     320        ]
     321        req = MockRequest(self.env, path_info='/timeline', tz=utc,
     322                          args={'from': '2025-02-19T00:00:00Z',
     323                                'daysback': '1'})
     324        rv = self._process_request(req)
     325        data = rv[1]
     326        events = data['events']
     327        self.assertEqual(1, len(events))
     328        self.assertEqual(datetime(2025, 2, 19, 12, tzinfo=utc),
     329                         events[0]['datetime'])
     330
    310331    def _process_request(self, req):
    311332        mod = TimelineModule(self.env)
    312         req = MockRequest(self.env, path_info='/timeline',
    313                           args={'format': 'rss'})
    314333        self.assertTrue(mod.match_request(req))
    315334        return mod.process_request(req)
    316335
#13867 fixed Unit tests failing with Subversion 1.14.5 Jun Omae Jun Omae
Description

It seems that SubversionNode.get_copy_ancestry raises the following AttributeError in the all failures.

======================================================================
ERROR: test_get_copy_ancestry_for_move (tracopt.versioncontrol.svn.tests.svn_fs.SvnCachedRepositoryScopedTests.test_get_copy_ancestry_for_move)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/runner/work/trac/trac/tracopt/versioncontrol/svn/tests/svn_fs.py", line 1267, in test_get_copy_ancestry_for_move
    ancestry = node.get_copy_ancestry()
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/runner/work/trac/trac/tracopt/versioncontrol/svn/svn_fs.py", line 855, in get_copy_ancestry
    path = path.lstrip(b'/')
           ^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'lstrip'

...
Ran 2810 tests in 554.016s

FAILED (errors=12, skipped=5)
#13866 fixed Syntax hightlihging has unexpected styles after Pygments 2.7.0 Jun Omae Jun Omae
Description

After Pygments 2.7.0, the syntax highlighting has unexpected styles (e.g. pre, td.linenoes pre).

$ script='import pygments; from pygments.formatters.html import HtmlFormatter as F; print(pygments.__version__); print(F().get_style_defs("div.code pre"))'
$ diff -u <(/venv/pygments-2.6.1/bin/python -c "$script") \
>         <(/venv/pygments-2.7.0/bin/python -c "$script")
--- /dev/fd/63  2025-02-05 19:05:33.783629775 +0900
+++ /dev/fd/62  2025-02-05 19:05:33.783629775 +0900
@@ -1,6 +1,11 @@
-2.6.1
+2.7.0
+pre { line-height: 125%; margin: 0; }
+td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
+span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
+td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
 div.code pre .hll { background-color: #ffffcc }
-div.code pre  { background: #f8f8f8; }
+div.code pre { background: #f8f8f8; }
 div.code pre .c { color: #408080; font-style: italic } /* Comment */
 div.code pre .err { border: 1px solid #FF0000 } /* Error */
 div.code pre .k { color: #008000; font-weight: bold } /* Keyword */

I think we could directly invoke get_background_style_defs and get_token_style_defs in the HtmlFormatter.

  • trac/mimeview/pygments.py

     
    3737__all__ = ['PygmentsRenderer']
    3838
    3939
     40if hasattr(HtmlFormatter, 'get_background_style_defs') and \
     41        hasattr(HtmlFormatter, 'get_token_style_defs'):
     42    def _get_style_defs(style, arg):  # Pygments 2.7.0+
     43        lines = []
     44        formatter = HtmlFormatter(style=style)
     45        lines.extend(formatter.get_background_style_defs(arg))
     46        lines.extend(formatter.get_token_style_defs(arg))
     47        return '\n'.join(lines)
     48else:
     49    def _get_style_defs(style, arg):
     50        formatter = HtmlFormatter(style=style)
     51        return formatter.get_style_defs(arg)
     52
     53
    4054class PygmentsRenderer(Component):
    4155    """HTML renderer for syntax highlighting based on Pygments."""
    4256
     
    186200            req.end_headers()
    187201            return
    188202
    189         formatter = HtmlFormatter(style=style_cls)
    190         content = formatter.get_style_defs(['div.code pre', 'table.code td'])
     203        content = _get_style_defs(style_cls, ['div.code pre', 'table.code td'])
    191204        content = content.encode('utf-8')
    192205
    193206        req.send_response(200)

See also: https://github.com/pygments/pygments/blob/2.19.1/pygments/formatters/html.py#L516

1 2 3 4 5 6 7 8 9 10 11


See also: TracQuery, TracTickets, TracReports

Last modified 3 years ago Last modified on Mar 6, 2022, 8:38:39 AM
Note: See TracWiki for help on using the wiki.