Part of the EllisLab Network

Blog & News

Lisa Wess
Director of Community Services

Building a Bug Tracker: Filtering by Severity

In the beginning of this series, we set up some custom fields to handle data for the bug tracker.  Those custom fields can be used now, to help filter the data and get a more specific view for issues pertaining to any of those custom fields. 

The magic here will be using the weblog entries tag with the search parameter and segments.

Shall we? 

For this article, we’re going to focus on filtering all bug reports by their severity.  We’re going to be careful to build a template that we can use later for filtering by other custom fields while re-using the same template.

To begin, duplicate the index in the bug tracker template group and call the new template filter_by.

Now, open up that new template and find this code:

{exp:weblog:entries weblog="{bug_tracker_weblog}" limit="30" status="Open|New|Confirmed|Unconfirmed|External|Resolved" sort="desc"}

To this, we’re going to add the search parameter.  We’ll add it like so:

search:bug_tracker_{segment_3}="={segment_4}" dynamic="off"

We’re turning dynamic off here as we’re again defining our own semantics.  For the search parameter, we want to keep this flexible so we can use it for our other custom fields, hence calling segment_3.  We also want to be able to pass a variable to it so that we can re-use the template for all of our custom fields, so we’ll call segment_4 as well.

You’ll remember that our custom fields were all prepended with the short name of the weblog; however, we don’t want that to be reflected several times in the URL as that would be redundant.  To keep the URLs neat and tidy, we’re adding short name to the search parameter and then appending segment 3.  Momentarily you’ll see why.

Before that, as we did in last week’s article, we’re going to add the no_results variable pair here, like so:

{if no_results}
No bugs of {segment_4} {segment_3}
.
{/if}

And in order to have a conditional heading telling us what we’re filtering by, we’ll add this right below our already existing count conditional, and above the opening table tag:

<h3>Filtering by {segment_4} {segment_3}</h3>

We’ll make one more change to this template, and that is the embed calling inc/.head.  We need to pass it a correct title to display, so it should now look like so:

{embed="inc/.head" title="Bug Tracker - {segment_4} {segment_3}"}

It’s time to create links that allow for filtering by severity and segments.  Open up inc/.leftnav.

We’ll want to replace the severity link with a list of severities to filter by; replace this link:

<li><a href="#">Severity</a></li>

with:

<li>Severity</li>
    <
ul>
     <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Trivial/">Trivial</a></li>
         <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Minor/">Minor</a></li>
         <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Major/">Major</a></li>
         <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Critical/">Critical</a></li>
    </
ul>

The search parameter is not case sensitive; however, we’re also going to use this in our heading tags, so we will want it to have proper capitalization with minimal mark-up; capitalizing the severity in our links helps reach this goal.

Now visit the bug tracker, and click on the Trivial link - it should look like this:

Bug Tracker Filter by Severity

And here is the template code for bug_tracker/filter_by:

{html_begin}

{embed
="inc/.head" title="Bug Tracker - {segment_4} {segment_3}"}

<body>
<
div id="container">
{embed="inc/.banner"}
{embed
="inc/.leftnav"}
<div id="content">

{!-- List of all reported bugs --}

{exp
:weblog:entries weblog="{bug_tracker_weblog}" limit="30" status="Open|New|Confirmed|Unconfirmed|External|Resolved" sort="desc" search:bug_tracker_{segment_3}="={segment_4}" dynamic="off"}
{if no_results}
No bugs of {segment_4} {segment_3}
.
{/if}
{if count
== "1"}
<h3>Filtering by {segment_4} {segment_3}</h3>
<
table>
<
tr>
<
th>ID</th>
<
th>Status</th>
<
th>Version</th>
<
th>Description</th>
</
tr>
{/if}
<tr>
<
td>{entry_id}</td>
<
td>{status}</td>
<
td>{bug_tracker_version}</td>
<
td>{title}</td>
</
tr>
{if count == total_results}
</table>
{/if}
{
/exp:weblog:entries}

{
!-- End Bug List --}
</div>
{embed="inc/.footer"}
</div>
{html_end}

and the code for the updated inc/.leftnav template:

<div id="leftnav">
<
h3>Filter By</h3>
<
ul>
<
li><a href="#">Status</a></li>
<
li>Severity</li>
    <
ul>
     <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Trivial/">Trivial</a></li>
     <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Minor/">Minor</a></li>
     <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Major/">Major</a></li>
     <
li><a href="{path="{bug_tracker_template_group}/filter_by"}severity/Critical">Critical</a></li>
    </
ul>
<
li><a href="#">Version</a></li>
<
li><a href="#">Category</a></li>
<
li><a href="#">Reported by</a></li>
<
li><a href="#">Assigned To</a></li>
</
ul>

<
h3>Search and Report</h3>
<
ul>
<
li><a href="#">Search</a></li>
<
li><a href="{path="{bug_tracker_template_group}/submit_bug"}">Report</a></li>
<
li><a href="{path="{bug_tracker_template_group}/by_author}{logged_in_username}"}">View My Bugs</a></li>
</
ul>

<
h3>Subscribe</h3>

<
ul>
<
li><a href="#">RSS</a></li>
<
li><a href="#">Atom</a></li>
</
ul>

</
div>

And now we can easily filter posts by any severity, using one template.  We’ll expand on this concept as we go through and implement the features indicated in the left navigation menu.