CustomizingWithCallbacks

From Request Tracker Wiki
Jump to navigation Jump to search

Callbacks

Introduction

RT uses Callbacks for adding extensions into the Web GUI without modifying html code. Wikipedia defines a callback as “executable code that is passed as an argument to other code. It allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer." So callback in RT is a code that you can put into right place and it will be called when a user opens a page.

Callbacks are called on different places and have to be placed into directories

<rt root>/local/html/Callbacks/<any directory>/<normal path to html-page>/<CallbackName>
  • <rt root> - we suppose you know where your RT is installed
  • local - local directory for your customizations, CustomizingWithLocalDir.
  • html - directory with Mason components.
  • Callbacks - directory for your Callbacks, create if it doesn't exist. It's Callbacks (lowercase "b") not CallBacks (uppercase "B"), not callbacks.
  • <any directory> - one directory with any name you like. Call it MyCallbacks, his_callbacks or boo. The assumption is that you will group your callbacks, based on logic of your choosing. You can have many different callback groups, and the callback will be run for each of them.
  • <normal path to html-page> - if a call you want to hook on is in html/X/Y.html file then you should create X/Y.html directory.
  • <CallbackName> - name of the callback, each page may have multiple callbacks. By default is 'Default', but might be different. Read more about names below.

Places where callbacks are called look in the following way (RT 3.8):

   $m->callback(
       TicketObj => $TicketObj,
       ARGSRef => \%ARGS,
       CallbackName => 'Initial',
   );

This is example from Ticket/Display.html in RT 3.8.7, full path to your code may look like this:

   /opt/rt3/local/html/Callbacks/MyCallbacks/Ticket/Display.html/Initial

Arguments passed to callback function are passed into your code and you can use them to explore situation and modify behaviour.

Finding callbacks

You can find all callbacks using grep command:

   cd /opt/rt3/
   find share/html | xargs grep '\->callback'

In RT 3.6 and older syntax is slightly different, old syntax is still valid and supported:

   cd /opt/rt3/
   find share/html | xargs grep 'Elements/Callback'

In RT 4.2.x these are most of them: RT_4.2_Callbacks

In RT-Assets 1.01 these are most of them: RT-Assets_1.01_Callbacks

CallbackName

Each Mason component may call multiple callbacks, so each callback has a name. The name of the callback you figure out from arguments used to call $m->callback. Understandably, the argument to define a callback name is 'CallbackName' and if it's absent then 'Default' is used.

For example, the following callback call in Modify.html lacks a name, so its name (by default) is Default

 $m->callback( TicketObj => $TicketObj, CustomFields => $CustomFields, ARGSRef => \%ARGS );

Sample callbacks

Comments

There are some drawbacks, when customizing RT with the "Local" principle: If you have many customizations it is difficult to propagate customizations across version changes. This is mainly because

  • when using the 'local' directory, you overlay files. If the original file is changed in a new release, e. g. a bug is fixed or a feature is added, you will not profit from this changes immediately, because your overlay is used.
  • when using a XXX_Local.pm, you overlay methods and the same drawback as above will hit you if the method has been changed across releases. See CustomizingWithOverlays for details.

For both customisation methods hold: They are not local enough! If you overlay, it might be possible that you overlay code (that you did not change) from earlier versions, that have been corrected or adopted to other changes in new versions and that is not compatible with the new version. Hence version upgrades may be complicated. I added two Sections above with customization methods I prefer, because we do many customizations, these are Patches and Callbacks. --DirkPape

GaryOberbrunner

Here's a sample ShowMessageStanza callback. Put this in /opt/rt3/share/html/Callbacks/*/Ticket/Elements/ShowMessageStanza/Default :

   <%init>
   my $val = $$content;
   use bytes;
   # Auto link 12-digit hex strings to a search page
   $val =~ s{[0-9a-f]{12}}{$&<\/a>}gi;
   $$content = $val;
   
   <%args>
   $content => undef
   


Note that the stanza will appear in $$content, you just modify it in place. Thanks to Toby Darling for the code!

Troubleshooting

Did you clear your Mason cache? (See CleanMasonCache)

Did you restart your webserver process?

Are your Mason component settings accurate (in the web UI, visit Tools -> System Configuration and scroll down)?

Are your file and directory permissions for your new callback set properly?

Are you sure you have your callback arguments correct? Beware 'TicketObj' vs. 'Ticket' being passed!