Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / rt / docs / extending / clickable_links.pod
1 =head1 MakeClicky extension
2
3 =head2 Description
4
5 I<MakeClicky> detects various formats of data in headers and email
6 messages, and makes them into links in RT's web UI.
7
8 =head2 Configuration
9
10 You can configure which actions are enabled from RT config with the
11 @Active_MakeClicky option, which should contain an ordered list of the
12 actions you want to apply.
13
14 By default, RT provides two actions:
15
16 =over 4
17
18 =item C<httpurl>
19
20 Detects C<http://> and C<https://> URLs and adds an C<[Open URL]> link
21 after the URL.
22
23 =item C<httpurl_overwrite>
24
25 Detects URLs as C<httpurl> format, but replaces the URL with a link.
26 This action is enabled by default.
27
28 =back
29
30 RTIR, an RT extension for CERT teams (not installed with core RT),
31 shipps with several additional actions you can use: C<ip>, C<ipdecimal>,
32 C<email>, C<domain> and C<RIPE>.
33
34 =head2 Order of actions
35
36 The order of the actions is important in situations when you use
37 multiple actions that could match the same block of text; only the first
38 matching action from the list is applied. For example, it makes no sense
39 to use C<httpurl> and C<httpurl_overwrite> at the same time, as both
40 actions always match the same pieces of text.
41
42 =head2 How it works
43
44 Each action consists of regular expression and function that does text
45 replacement.  When you open the history of a ticket, RT searches in the
46 text with the given regular expresion for matches. If it finds a match,
47 it calls the function with the match as the argument, then replaces the
48 matched text with the string returned by the function.
49
50 While RT only searches plaintext content, the actions can generate
51 arbitrary HTML.
52
53 =head2 Writing custom MakeClicky actions
54
55 To extend the list of actions with your own types of data, use the
56 provided callback. Specifically, create the file
57 F<local/html/Callbacks/MyCallbacks/Elements/MakeClicky/Default>.
58
59 It will be called with the following arguments:
60
61 =over 4
62
63 =item types
64
65 An array reference of hash references.  Modify this array
66 reference to add your own types; the first matching type will be
67 used. Each hashref should contain:
68
69 =over 4
70
71 =item name
72
73 The name of the data format; this is used in the configuration file to
74 enable the format.
75
76 =item regex
77
78 A regular expression to match against.
79
80 =item action
81
82 The name of the action to run (see "actions", below)
83
84 =back
85
86 =item actions
87
88 A hash reference of 'actions'.  Modify this hash reference to change or
89 add action types.  Values are subroutine references which will get
90 called when needed.  They should return the modified string. Note that
91 subroutine B<must escape> HTML.
92
93 =item handle
94
95 A subroutine reference; modify it only if you have to. This can be used
96 to add pre- or post-processing around all actions.
97
98 =item cache
99
100 An undefined variable that should be replaced with a subroutine
101 reference. This subroutine will be called twice, once with the arguments
102 fetch => content_ref and once with store => content_ref. In the fetch
103 case, if a cached copy is found, return the cached content, otherwise
104 return a false value. When passed store, you should populate your cache
105 with the content. The return value is ignored in this case.
106
107 =back
108
109 =head2 Actions' arguments
110
111 A hash is passed to the action with two keys that always exist:
112
113 =over 4
114
115 =item value
116
117 The full match of the regular expression; this is the block of text that
118 will be replaced with action's result.
119
120 =item all_matches
121
122 And arrayref with all of the match's capturing groups; for example if
123 your regexp is C<qr{ticket\s+#(\d+)}>, then the first element will be
124 full match ("ticket #XXX"), the same as in 'value' key, but the second
125 element of the array will be the id of a ticket (XXX).  Using this, you
126 can avoid reparsing the value in the action.  Only the first eight
127 groups of your regexps are passed to action.
128
129 =back
130
131 =head2 Custom MakeClicky action example
132
133 Create a new file F</opt/rt4/local/html/Callbacks/MyCallbacks/Elements/MakeClicky/Default>
134 with the content:
135
136   <%ARGS>
137   $types   => []
138   $actions => {}
139   </%ARGS>
140   <%INIT>
141   my $web_path = RT->Config->Get('WebPath');
142   
143   # action that takes ticket ID as argument and returns link to the ticket
144   $actions->{'link_ticket'} = sub {
145       my %args = @_;
146       my $id = $args{'all_matches'}[1];
147       return qq{<a href="$web_path/Ticket/Display.html?id=$id">$args{value}</a>};
148   };
149   
150   # add action to the list
151   push @$types, {
152       # name, that should be used in config to activate action
153       name   => 'short_ticket_link',
154       # regular expression that matches text 'ticket #xxx'
155       regex  => qr{ticket\s+#(\d+)}i,
156       # name of the action that should be applied
157       action => 'link_ticket',
158   };
159   </%INIT>
160
161 That's all; add C<short_ticket_link> to the C<@Active_MakeClicky> option
162 in your C<RT_SiteConfig.pm>, and restart your server.  Creating a ticket
163 with "ticket #1" in the body should cause that text to be automatically
164 linked to the ticket in question.
165
166 =head2 Notes for custom clicky actions writers
167
168 =over
169
170 =item *
171
172 Note that an action B<must escape> illegal HTML characters with entities
173 and/or arguments in URLs.
174
175 =item *
176
177 Complex regular expressions could slow down RT, as the conversion is run
178 each time a user opens a ticket, for every transaction.  For long
179 tickets and complex regular expressions, this can slow down ticket
180 display notably.
181
182 =item *
183
184 Try to match the shortest expression you need with your regular
185 expression; otherwise another action may miss its chance to match.
186
187 =item *
188
189 Whenever possible, precalculate values using closures around the
190 functions.
191
192 =back
193
194 =cut