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