- RT Search Results
  - Level of Difficulty
  - Column Maps
  - Column Map Callback
  - Column Map Parameters
  - Adding to Display Columns
  - Last Steps

# RT Search Results

Ticket search results in RT are presented as a table with multiple heading rows, one for each element of ticket metadata you have selected. Each row in the table represents one ticket and the appropriate metadata is displayed in each column. You can see similar listings when you search for other objects in RT like users, queues, templates, etc.

For tickets, the Query Builder allows you to modify the column layout using the Sorting and Display Columns sections at the bottom of the page. With them you can add and remove data elements to sort by, change the sort order, and add and remove which columns you want to see.

Although the Add Columns box has an extensive list of available columns, there are times when you need a value not listed. If you want to display a custom date range, you can configure the "%CustomDateRanges" in RT_Config setting.

Sometimes what you want is a novel value calculated based on other ticket information, like the number of messages on a ticket. RT provides a way to add this sort of customization using something called a Column Map.

## Level of Difficulty

The customizations described in this section require administrative access to the RT server and the RT filesystem, typically root or sudo level access. The customizations involve adding new code to RT, which is written in the Perl programming language and uses the Mason templating system. If you follow the example closely, you should be able to set up simple column maps with a basic understanding of these. For more complicated configurations, you may need to do more research to understand the Perl and Mason syntax.

## Column Maps

Each column in a ticket listing gets run through a bit of code called a Column Map that allows you to perform transformations on the value before it is displayed. In some cases, the value is just passed through. In others, like DueRelative, a date is transformed to a relative time like "2 days ago." You can tap into this functionality to add your own transformations or even generate completely new values.

To add to the existing Column Maps, you can use RT's callback mechanism. This allows you to add code to RT without modifying the core files, making upgrades much easier. As an example, we'll add a Column Map to the ticket display and explain the necessary callbacks. You can read more about callbacks in general in the "Callbacks" in writing_extensions documentation.

For our example, let's assume we want to display the number of messages (comments, correspondences) on a ticket.

## Column Map Callback

First we need to determine where to put our callback. RT's core Column Map code for tickets is here:

        /usr/share/request-tracker5/html/Elements/RT__Ticket/ColumnMap

We'll look there first, both to see some sample Column Maps and also to look for an appropriate callback to use to add our own. Looking in that file, we see `$COLUMN_MAP`, which is a large hashref with entries for each of the items you see in the Add Columns section of the Query Builder. That's where we need to add our new Column Map.

Looking in the `init` section, we find a callback with a `CallbackName` "Once" and it passes the `$COLUMN_MAP` reference as an argument, so that's the callback we need.

Following the callback documentation, we determine we can put our callback here:

        /usr/local/share/request-tracker5/html/Callbacks/MyRT/Elements/RT__Ticket/ColumnMap/Once

where Once is the name of the file where we'll put our code.

In the Once file, we'll put the following code:

        <%init>
        $COLUMN_MAP->{'NumberOfMessages'} = {
                title     => 'Messages',
                attribute => 'Messages',
                value     => sub {
                    my $ticket = shift;
                    my $txns = $ticket->Transactions;
                    $txns->Limit( FIELD => 'Type', VALUE => 'Comment' );
                    $txns->Limit( FIELD => 'Type', VALUE => 'Correspond' );
                    return $txns->Count;
                }
        };
        </%init>
        <%args>
        $COLUMN_MAP
        </%args>

Starting with the `args` section, the value we're interested in is the `$COLUMN_MAP` hash reference. Since it's a reference, it's pointing to the actual data structure constructed in the core RT code. This means we can add more entries and RT will have access to them.

## Column Map Parameters

As you can see in the examples in the core ColumnMap file, each entry has a key and a hashref with several other parameters. The key needs to be a unique value. If you using an existing value, you'll overwrite the original values.

The parameters in the hashref are as follows:

title

  The title is what will be used in the header row to identify this value.

attribute

  This defines the value you can use to reference your new column map from an RT Format configuration. You can edit formats in the Query Builder's Advanced section. If you're not familiar with formats, it's usually safe to set the attribute to the same value as `title`. It should be descriptive and unique.

value

  This is where you can put code to transform or calculate the value that will be displayed. This sets the value you see in the search results for this column.

Each of these can be a value like a simple string or an anonymous subroutine with code that runs to calculate the value.

If you write a subroutine, as we do for `value` in our example, RT will pass the current object as the first parameter to the sub. Since we're creating a column map for tickets, as RT processes the ticket for each row in the search results, the ticket object for that ticket is made available as the first parameter to our subroutine.

This allows us to then call methods on the RT::Ticket object to access and process the value. In our case, we can get the RT::Transactions collection, limit it to the types we're interested in, and then use the `Count` method to return the number of messages.

When writing code to calculate values, remember that it will be run for each row in search results. You should avoid doing things that are too time intensive in that code, like calling a web service to fetch a value.

## Adding to Display Columns

Now that we have our column map created, there is one more callback to add to make it available for all of our users in the Add Columns section in the Query Builder. This file builds the list of fields available:

        /usr/share/request-tracker5/html/Search/Elements/BuildFormatString

Looking there, we see the default callback (the callback without an explicit `CallbackName`) passes the `@fields` array, so that will work. Create the file:

        /usr/local/share/request-tracker5/html/Callbacks/MyRT/Search/Elements/BuildFormatString/Default

And put the following code in the Default file:

        <%INIT>
        push @{$Fields}, 'NumberOfMessages';
        </%INIT>
        <%ARGS>
        $Fields => undef
        </%ARGS>

This puts the hash key we chose for our column map in the fields list so it will be available in the list of available fields.

## Last Steps

Once you have the code in place, stop the RT web server, clear the Mason cache, and restart the server. Watch the RT logs for any errors, and navigate to the Query Build to use your new column map.

← Back to index