Master to 4.2.8
[usit-rt.git] / lib / RT / StyleGuide.pod
CommitLineData
84fb5b46
MKG
1=head1 NAME
2
3RT::StyleGuide - RT Style Guide
4
c33a4027
MKG
5=head1 CAVEATS
6
7This file is somewhat out of date; L<hacking> takes precedence over it.
8
84fb5b46
MKG
9=head1 INTRODUCTION
10
11All code and documentation that is submitted to be included in the RT
12distribution should follow the style in this document. This is not to
13try to stifle your creativity, but to make life easier for everybody who
14has to work with your code, and to aid those who are not quite sure how
15to do something.
16
17These conventions below apply to perl modules, web programs, and
18command-line programs, specifically, but also might apply to some
19degree to any Perl code written for use in RT.
20
21Note that these are all guidelines, not unbreakable rules. If you have
22a really good need to break one of the rules herein, however, then it is
23best to ask on the B<rt-devel> mailing list first.
24
25Note that with much of this document, it is not so much the Right Way as
26it is Our Way. We need to have conventions in order to make life easier
27for everyone. So don't gripe, and just follow it, because you didn't
28get a good grade in "Plays Well With Others" in kindergarten and you
29want to make up for it now.
30
31If you have any questions, please ask us on the B<rt-devel> mailing list:
32
af59614d 33 http://www.bestpractical.com/rt/lists.html
84fb5b46
MKG
34
35We don't always follow this guide. We are making changes throughout
36our code to be in line with it. But just because we didn't do
37it yet, that is no excuse. Do it anyway. :-)
38
39This document is subject to change at the whims of the core RT team.
40We hope to add any significant changes at the bottom of the document.
41
42
43=head1 CODING PRINCIPLES
44
45=head2 Perl Version
46
af59614d 47We code everything to Perl 5.10.1 or higher.
84fb5b46
MKG
48
49=head2 Documentation
50
51All modules will be documented using the POD examples in the module
52boilerplate. The function, purpose, use of the module will be
53explained, and each public API will be documented with name,
54description, inputs, outputs, side effects, etc.
55
56If an array or hash reference is returned, document the size of the
57array (including what each element is, as appropriate) and name each key
58in the hash. For complex data structures, map out the structure as
59appropriate (e.g., name each field returned for each column from a DB
60call; yes, this means you shouldn't use "SELECT *", which you shouldn't
61use anyway).
62
63Also document what kind of data returned values are. Is it an integer,
64a block of HTML, a boolean?
65
66All command-line program options will be documented using the
67boilerplate code for command-line programs, which doesn't yet exist.
68Each available function, switch, etc. should be documented, along
69with a statement of function, purpose, use of the program. Do not
70use the same options as another program, for a different purpose.
71
72All web templates should be documented with a statement of function,
73purpose, and use in a mason comment block.
74
75Any external documents, and documentation for command-line programs and
76modules, should be written in POD, where appropriate. From there, they
af59614d 77can be translated to many formats with the various pod2* translators.
84fb5b46
MKG
78Read the perlpod manpage before writing any POD, because although POD is
79not difficult, it is not what most people are used to. It is not a
80regular markup language; it is just a way to make easy documentation
81for translating to other formats. Read, and understand, the perlpod
82manpage, and ask us or someone else who knows if you have any questions.
83
84
85=head2 Version
86
87Our distribution versions use tuples, where the first number is the
88major revision, the second number is the version, and third
89number is the subversion. Odd-numbered versions are development
90versions. Examples:
91
af59614d
MKG
92 1.0.0 First release of RT 1
93 1.0.1 Second release of RT 1.0
94 1.0.10 etc.
95 1.1.0 First development release of RT 1.2 (or 2.0)
96 2.0.0 First release of RT 2
84fb5b46 97
c33a4027 98Versions may end in "rc" and a number if they are release candidates:
84fb5b46 99
c33a4027 100 2.0.0rc1 First release candiate for real 2.0.0
84fb5b46
MKG
101
102
103=head2 Comments
104
105All code should be self-documenting as much as possible. Only include
106necessary comments. Use names like "$ticket_count", so you don't need to
107do something like:
108
af59614d
MKG
109 # ticket count
110 my $tc = 0;
84fb5b46
MKG
111
112Include any comments that are, or might be, necessary in order for
113someone else to understand the code. Sometimes a simple one-line
114comment is good to explain what the purpose of the following code is
115for. Sometimes each line needs to be commented because of a complex
116algorithm. Read Kernighan & Pike's I<Practice of Programming> about
117commenting. Good stuff, Maynard.
118
119
120=head2 Warnings and Strict
121
122All code must compile and run cleanly with "use strict" enabled and the
123perl "-w" (warnings) option on. If you must do something that -w or
124strict complains about, there are workarounds, but the chances that you
125really need to do it that way are remote.
126
127=head2 Lexical Variables
128
129Use only lexical variables, except for special global variables
130($VERSION, %ENV, @ISA, $!, etc.) or very special circumstances (see
131%HTML::Mason::Commands::session ). Global variables
132for regular use are never appropriate. When necessary, "declare"
133globals with "use vars" or "our()".
134
135A lexical variable is created with my(). A global variable is
136pre-existing (if it is a special variable), or it pops into existence
137when it is used. local() is used to tell perl to assign a temporary
138value to a variable. This should only be used with special variables,
139like $/, or in special circumstances. If you must assign to any global
140variable, consider whether or not you should use local().
141
142local() may also be used on elements of arrays and hashes, though there
143is seldom a need to do it, and you shouldn't.
144
145
84fb5b46
MKG
146=head2 Pass by Reference
147
148Arrays and hashes should be passed to and from functions by reference
149only. Note that a list and an array are NOT the same thing. This
150is perfectly fine:
151
af59614d 152 return($user, $form, $constants);
84fb5b46
MKG
153
154An exception might be a temporary array of discrete arguments:
155
af59614d
MKG
156 my @return = ($user, $form);
157 push @return, $constants if $flag;
158 return @return;
84fb5b46
MKG
159
160Although, usually, this is better (faster, easier to read, etc.):
161
af59614d
MKG
162 if ($flag) {
163 return($user, $form, $constants);
164 } else {
165 return($user, $form);
166 }
84fb5b46
MKG
167
168We need to talk about Class::ReturnValue here.
169
170
84fb5b46
MKG
171=head2 Method parameters
172
173If a method takes exactly one mandatory argument, the argument should be
174passed in a straightforward manner:
175
176 my $self = shift;
177 my $id = shift;
178
179In all other cases, the method needs to take named parameters, usually
180using a C<%args> hash to store them:
181
182 my $self = shift;
c33a4027
MKG
183 my %args = (
184 Name => undef,
185 Description => undef,
186 @_
187 );
84fb5b46
MKG
188
189You may specify defaults to those named parameters instead of using
190C<undef> above, as long as it is documented as such.
191
192It is worth noting that the existing RT codebase had not followed this
c33a4027 193style perfectly; we are trying to fix it without breaking existing APIs.
84fb5b46
MKG
194
195=head2 Tests
196
197Modules should provide test code, with documentation on how to use
198it. Test::More makes it easy to create tests. Any code you write
199should have a testsuite. Any code you alter should have a test
200suite. If a patch comes in without tests, there is something wrong.
201
202When altering code, you must run the test harness before submitting a
203patch or committing code to the repository.
204
205"make test" will run the test suite.
206
207=head2 STDIN/STDOUT
208
209Always report errors using $RT::Logger. It's a Log::Dispatch object.
210Unlike message meant for the user, log messages are not to be
211internationalized.
212
213There are several different levels ($RT::Logger methods) of logging:
214
215=over 4
216
217=item debug
218
219Used for messages only needed during system debugging.
220
221=item info
222
223Should be used to describe "system-critical" events which aren't errors.
224Examples: creating users, deleting users, creating tickets, creating queues,
225sending email (message id, time, recipients), recieving mail, changing
226passwords, changing access control, superuser logins)
227
228=item error
229
230Used for RT-generated failures during execution.
231
232=item crit
233
234Should be used for messages when an action can not be completed due to some
235error condition beyond our control.
236
237=back
238
239In the web UI and modules, never print directly to STDERR. Do not print
240directly to STDOUT, unless you need to print directly to the user's console.
241
242In command-line programs, feel free to print to STDERR and STDOUT as
243needed for direct console communication. But for actual error reporting,
244use the logging API.
245
246
247=head2 System Calls
248
249Always check return values from system calls, including open(),
af59614d 250close(), mkdir(), or anything else that talks directly to the system.
84fb5b46
MKG
251Perl built-in system calls return the error in $!; some functions in
252modules might return an error in $@ or some other way, so read the module's
253documentation if you don't know. Always do something, even if it is
254just calling $RT::Logger->warning(), when the return value is not what you'd expect.
255
256
257
258=head1 STYLE
259
260Much of the style section is taken from the perlsyle manpage. We make
261some changes to it here, but it wouldn't be a bad idea to read that
262document, too.
263
264=head2 Terminology
265
266=over 4
267
84fb5b46
MKG
268=item function vs. sub(routine) vs. method
269
270Just because it is the Perl Way (not necessarily right for all
271languages, but the documented terminology in the perl documentation),
272"method" should be used only to refer to a subroutine that are object
273methods or class methods; that is, these are functions that are used
274with OOP that always take either an object or a class as the first
275argument. Regular subroutines, ones that are not object or class
276methods, are functions. Class methods that create and return an object
277are optionally called constructors.
278
279=item Users
280
281"users" are normally users of RT, the ones hitting the site; if using
af59614d 282it in any other context, specify.
84fb5b46
MKG
283"system users" are user
284names on the operating system. "database users" are the user names in
285the database server. None of these needs to be capitalized.
286
287=back
288
289
290=head2 Names
291
292Don't use single-character variables, except as iterator variables.
293
294Don't use two-character variables just to spite us over the above rule.
295
296Constants are in all caps; these are variables whose value will I<never>
297change during the course of the program.
298
af59614d
MKG
299 $Minimum = 10; # wrong
300 $MAXIMUM = 50; # right
84fb5b46 301
af59614d 302Other variables are lowercase, with underscores separating the words.
84fb5b46
MKG
303They words used should, in general, form a noun (usually singular),
304unless the variable is a flag used to denote some action that should be
305taken, in which case they should be verbs (or gerunds, as appropriate)
306describing that action.
307
af59614d
MKG
308 $thisVar = 'foo'; # wrong
309 $this_var = 'foo'; # right
310 $work_hard = 1; # right, verb, boolean flag
311 $running_fast = 0; # right, gerund, boolean flag
84fb5b46
MKG
312
313Arrays and hashes should be plural nouns, whether as regular arrays and
314hashes or array and hash references. Do not name references with "ref"
315or the data type in the name.
316
af59614d
MKG
317 @stories = (1, 2, 3); # right
318 $comment_ref = [4, 5, 6]; # wrong
319 $comments = [4, 5, 6]; # right
320 $comment = $comments->[0]; # right
84fb5b46
MKG
321
322Make the name descriptive. Don't use variables like "$sc" when you
323could call it "$story_count". See L<"Comments">.
324
325There are several variables in RT that are used throughout the code,
326that you should use in your code. Do not use these variable names for
327anything other than how they are normally used, and do not use any
328other variable names in their place. Some of these are:
329
af59614d 330 $self # first named argument in object method
84fb5b46
MKG
331
332Subroutines (except for special cases, like AUTOLOAD and simple accessors)
333begin with a verb, with words following to complete the action. Accessors
334don't start with "Get" if they're just the name of the attribute.
335
336Accessors which return an object should end with the suffix Obj.
337
338This section needs clarification for RT.
339
340Words begin with a capital letter. They
341should as clearly as possible describe the activity to be peformed, and
af59614d 342the data to be returned.
84fb5b46
MKG
343
344
345
af59614d
MKG
346 Load(); # good
347 LoadByName(); # good
348 LoadById(); # good
84fb5b46
MKG
349
350Subroutines beginning with C<_> are special: they are not to be used
351outside the current object. There is not to be enforced by the code
352itself, but by someone very big and very scary.
353
354For large for() loops, do not use $_, but name the variable.
355Do not use $_ (or assume it) except for when it is absolutely
356clear what is going on, or when it is required (such as with
357map() and grep()).
358
af59614d 359 for (@list) {
c33a4027
MKG
360 print; # OK; everyone knows this one
361 print uc; # wrong; few people know this
362 print uc $_; # better
af59614d 363 }
84fb5b46
MKG
364
365Note that the special variable C<_> I<should> be used when possible.
366It is a placeholder that can be passed to stat() and the file test
367operators, that saves perl a trip to re-stat the file. In the
368example below, using C<$file> over for each file test, instead of
369C<_> for subsequent uses, is a performance hit. You should be
370careful that the last-tested file is what you think it is, though.
371
af59614d 372 if (-d $file) { # $file is a directory
c33a4027 373 # ...
af59614d 374 } elsif (-l _) { # $file is a symlink
c33a4027 375 # ...
af59614d 376 }
84fb5b46
MKG
377
378Package names begin with a capital letter in each word, followed by
379lower case letters (for the most part). Multiple words should be StudlyCapped.
380
af59614d
MKG
381 RT::User # good
382 RT::Database::MySQL # proper name
383 RT::Display::Provider # good
384 RT::CustomField # not so good, but OK
84fb5b46 385
c33a4027 386Plugin modules should begin with "RT::Extension::", followed by the name
af59614d 387of the plugin.
84fb5b46
MKG
388
389=head1 Code formatting
390
c33a4027 391When in doubt, use perltidy; RT includes a F<.perltidyrc>.
84fb5b46
MKG
392
393=head2 Indents and Blank Space
394
c33a4027 395All indents should be four spaces; hard tabs are forbidden.
84fb5b46
MKG
396
397No space before a semicolon that closes a statement.
398
af59614d
MKG
399 foo(@bar) ; # wrong
400 foo(@bar); # right
84fb5b46
MKG
401
402Line up corresponding items vertically.
403
af59614d
MKG
404 my $foo = 1;
405 my $bar = 2;
406 my $xyzzy = 3;
84fb5b46 407
af59614d
MKG
408 open(FILE, $fh) or die $!;
409 open(FILE2, $fh2) or die $!;
84fb5b46 410
af59614d
MKG
411 $rot13 =~ tr[abcedfghijklmnopqrstuvwxyz]
412 [nopqrstuvwxyzabcdefghijklm];
84fb5b46 413
af59614d
MKG
414 # note we use a-mn-z instead of a-z,
415 # for readability
416 $rot13 =~ tr[a-mn-z]
417 [n-za-m];
84fb5b46
MKG
418
419Put blank lines between groups of code that do different things. Put
420blank lines after your variable declarations. Put a blank line before a
421final return() statement. Put a blank line following a block (and
422before, with the exception of comment lines).
423
424An example:
425
af59614d
MKG
426 # this is my function!
427 sub foo {
c33a4027
MKG
428 my $val = shift;
429 my $obj = new Constructor;
430 my($var1, $var2);
84fb5b46 431
c33a4027
MKG
432 $obj->SetFoo($val);
433 $var1 = $obj->Foo();
84fb5b46 434
c33a4027 435 return($val);
af59614d 436 }
84fb5b46 437
af59614d 438 print 1;
84fb5b46
MKG
439
440
441=head2 Parentheses
442
443For control structures, there is a space between the keyword and opening
444parenthesis. For functions, there is not.
445
af59614d
MKG
446 for(@list) # wrong
447 for (@list) # right
84fb5b46 448
af59614d
MKG
449 my ($ref) # wrong
450 my($ref) # right
84fb5b46
MKG
451
452Be careful about list vs. scalar context with parentheses!
453
af59614d
MKG
454 my @array = ('a', 'b', 'c');
455 my($first_element) = @array; # a
456 my($first_element) = ('a', 'b', 'c'); # a
457 my $element_count = @array; # 3
458 my $last_element = ('a', 'b', 'c'); # c
84fb5b46
MKG
459
460Always include parentheses after functions, even if there are no arguments.
461There are some exceptions, such as list operators (like print) and unary
462operators (like undef, delete, uc).
463
464There is no space inside the parentheses, unless it is needed for
465readability.
466
af59614d
MKG
467 for ( map { [ $_, 1 ] } @list ) # OK
468 for ( @list ) # not really OK, not horrible
84fb5b46
MKG
469
470On multi-line expressions, match up the closing parenthesis with either
471the opening statement, or the opening parenthesis, whichever works best.
472Examples:
473
af59614d 474 @list = qw(
c33a4027
MKG
475 bar
476 baz
af59614d 477 ); # right
84fb5b46 478
af59614d 479 if ($foo && $bar && $baz
c33a4027
MKG
480 && $buz && $xyzzy) {
481 print $foo;
af59614d 482 }
84fb5b46
MKG
483
484Whether or not there is space following a closing parenthesis is
485dependent on what it is that follows.
486
af59614d 487 print foo(@bar), baz(@buz) if $xyzzy;
84fb5b46
MKG
488
489Note also that parentheses around single-statement control expressions,
490as in C<if $xyzzy>, are optional (and discouraged) C<if> it is I<absolutely>
491clear -- to a programmer -- what is going on. There is absolutely no
492need for parentheses around C<$xyzzy> above, so leaving them out enhances
493readability. Use your best discretion. Better to include them, if
494there is any question.
495
496The same essentially goes for perl's built-in functions, when there is
497nothing confusing about what is going on (for example, there is only one
498function call in the statement, or the function call is separated by a
499flow control operator). User-supplied functions must always include
500parentheses.
501
af59614d
MKG
502 print 1, 2, 3; # good
503 delete $hash{key} if isAnon($uid); # good
84fb5b46
MKG
504
505
506However, if there is any possible confusion at all, then include the
507parentheses. Remember the words of Larry Wall in the perlstyle manpage:
508
af59614d
MKG
509 When in doubt, parenthesize. At the very least it will
510 let some poor schmuck bounce on the % key in vi.
84fb5b46 511
af59614d
MKG
512 Even if you aren't in doubt, consider the mental welfare
513 of the person who has to maintain the code after you, and
514 who will probably put parens in the wrong place.
84fb5b46
MKG
515
516So leave them out when it is absoutely clear to a programmer, but if
517there is any question, leave them in.
518
519
520=head2 Braces
521
522(This is about control braces, not hash/data structure braces.)
523
524There is always a space befor the opening brace.
525
af59614d
MKG
526 while (<$fh>){ # wrong
527 while (<$fh>) { # right
84fb5b46
MKG
528
529A one-line block may be put on one line, and the semicolon may be
530omitted.
531
af59614d 532 for (@list) { print }
84fb5b46
MKG
533
534Otherwise, finish each statement with a semicolon, put the keyword and
535opening curly on the first line, and the ending curly lined up with the
536keyword at the end.
537
af59614d 538 for (@list) {
c33a4027
MKG
539 print;
540 smell();
af59614d 541 }
84fb5b46 542
c33a4027 543Generally, we prefer "cuddled elses":
84fb5b46 544
af59614d 545 if ($foo) {
c33a4027 546 print;
af59614d 547 } else {
c33a4027 548 die;
af59614d 549 }
84fb5b46
MKG
550
551=head2 Operators
552
553Put space around most operators. The primary exception is the for
554aesthetics; e.g., sometimes the space around "**" is ommitted,
555and there is never a space before a ",", but always after.
556
af59614d
MKG
557 print $x , $y; # wrong
558 print $x, $y; # right
84fb5b46 559
af59614d
MKG
560 $x = 2 >> 1; # good
561 $y = 2**2; # ok
84fb5b46 562
af59614d 563Note that "&&" and "||" have a higher precedence than "and" and "or".
84fb5b46
MKG
564Other than that, they are exactly the same. It is best to use the lower
565precedence version for control, and the higher for testing/returning
566values. Examples:
567
af59614d
MKG
568 $bool = $flag1 or $flag2; # WRONG (doesn't work)
569 $value = $foo || $bar; # right
570 open(FILE, $file) or die $!;
84fb5b46 571
af59614d
MKG
572 $true = foo($bar) && baz($buz);
573 foo($bar) and baz($buz);
84fb5b46
MKG
574
575Note that "and" is seldom ever used, because the statement above is
576better written using "if":
577
af59614d 578 baz($buz) if foo($bar);
84fb5b46
MKG
579
580Most of the time, the confusion between and/&&, or/|| can be alleviated
581by using parentheses. If you want to leave off the parentheses then you
582I<must> use the proper operator. But if you use parentheses -- and
583normally, you should, if there is any question at all -- then it doesn't
584matter which you use. Use whichever is most readable and aesthetically
585pleasing to you at the time, and be consistent within your block of code.
586
c33a4027 587Break long lines AFTER operators, except for ".", "and", "or", "&&", "||".
84fb5b46
MKG
588Try to keep the two parts to a binary operator (an operator that
589has two operands) together when possible.
590
af59614d 591 print "foo" . "bar" . "baz" .
c33a4027
MKG
592 "buz"; # wrong
593
594 print "foo" . "bar" . "baz"
595 . "buz"; # right
84fb5b46 596
af59614d
MKG
597 print $foo unless $x == 3 && $y ==
598 4 && $z == 5; # wrong
84fb5b46 599
af59614d 600 print $foo unless $x == 3 && $y == 4
c33a4027 601 && $z == 5; # right
84fb5b46
MKG
602
603
604=head2 Other
605
606Put space around a complex subscript inside the brackets or braces.
607
af59614d
MKG
608 $foo{$bar{baz}{buz}}; # OK
609 $foo{ $bar{baz}{buz} }; # better
84fb5b46
MKG
610
611In general, use single-quotes around literals, and double-quotes
af59614d 612when the text needs to be interpolated.
84fb5b46
MKG
613
614It is OK to omit quotes around names in braces and when using
615the => operator, but be careful not to use a name that doubles as
616a function; in that case, quote.
617
af59614d 618 $what{'time'}{it}{is} = time();
84fb5b46
MKG
619
620When making compound statements, put the primary action first.
621
af59614d
MKG
622 open(FILE, $fh) or die $!; # right
623 die $! unless open(FILE, $fh); # wrong
84fb5b46 624
af59614d
MKG
625 print "Starting\n" if $verbose; # right
626 $verbose && print "Starting\n"; # wrong
84fb5b46
MKG
627
628
629Use here-docs instead of repeated print statements.
630
af59614d
MKG
631 print <<EOT;
632 This is a whole bunch of text.
633 I like it. I don't need to worry about messing
634 with lots of print statements and lining them up.
635 EOT
84fb5b46
MKG
636
637Just remember that unless you put single quotes around your here-doc
638token (<<'EOT'), the text will be interpolated, so escape any "$" or "@"
639as needed.
640
641=head1 INTERNATIONALIZATION
642
643
644=head2 String extraction styleguide
645
646=over 4
647
648=item Web templates
649
650Templates should use the /l filtering component to call the localisation
651framework
652
af59614d 653The string Foo!
84fb5b46 654
af59614d 655Should become <&|/l&>Foo!</&>
84fb5b46 656
af59614d 657All newlines should be removed from localized strings, to make it easy to
84fb5b46
MKG
658grep the codebase for strings to be localized
659
af59614d
MKG
660The string Foo
661 Bar
662 Baz
663
664Should become <&|/l&>Foo Bar Baz</&>
84fb5b46
MKG
665
666
667Variable subsititutions should be moved to Locale::MakeText format
668
af59614d 669The string Hello, <%$name %>
84fb5b46 670
af59614d 671should become <&|/l, $name &>Hello, [_1]</&>
84fb5b46
MKG
672
673
674Multiple variables work just like single variables
84fb5b46 675
af59614d
MKG
676The string You found <%$num%> tickets in queue <%$queue%>
677
678should become <&|/l, $num, $queue &>You found [_1] tickets in queue [_2]</&>
84fb5b46
MKG
679
680When subcomponents are called in the middle of a phrase, they need to be escaped
681too:
682
af59614d 683The string <input type="submit" value="New ticket in">&nbsp<& /Elements/SelectNewTicketQueue&>
84fb5b46 684
af59614d 685should become <&|/l, $m->scomp('/Elements/SelectNewTicketQueue')&><input type="submit" value="New ticket in">&nbsp;[_1]</&>
84fb5b46
MKG
686
687
688
689
af59614d 690The string <& /Widgets/TitleBoxStart, width=> "40%", titleright => "RT $RT::VERSION for RT->Config->Get('rtname')", title => 'Login' &>
84fb5b46 691
af59614d
MKG
692should become <& /Widgets/TitleBoxStart,
693 width=> "40%",
694 titleright => loc("RT [_1] for [_2]",$RT::VERSION, RT->Config->Get('rtname')),
695 title => loc('Login'),
696 &>
84fb5b46 697
af59614d 698=item Library code
84fb5b46
MKG
699
700
701
702Within RT's core code, every module has a localization handle available through the 'loc' method:
703
af59614d 704The code return ( $id, "Queue created" );
84fb5b46 705
af59614d 706should become return ( $id, $self->loc("Queue created") );
84fb5b46
MKG
707
708When returning or localizing a single string, the "extra" set of parenthesis () should be omitted.
709
af59614d 710The code return ("Subject changed to ". $self->Data );
84fb5b46 711
af59614d 712should become return $self->loc( "Subject changed to [_1]", $self->Data );
84fb5b46
MKG
713
714
715It is important not to localize the names of rights or statuses within RT's core, as there is logic that depends on them as string identifiers. The proper place to localize these values is when they're presented for display in the web or commandline interfaces.
716
717
718=back
719
720=head1 CODING PRCEDURE
721
722This is for new programs, modules, specific APIs, or anything else.
723
724=over 4
725
726=item Present idea to rt-devel
727
728We may know of a better way to approach the problem, or know of an
af59614d 729existing way to deal with it, or know someone else is working on it.
84fb5b46
MKG
730This is mostly informal, but a fairly complete explanation for the need
731and use of the code should be provided.
732
733
734=item Present complete specs to rt-devel
735
736The complete proposed API should be submitted for
737approval and discussion. For web and command-line programs, present the
738functionality and interface (op codes, command-lin switches, etc.).
739
740The best way to do this is to take the documentation portion of the
741boilerplate and fill it in. You can make changes later if necessary,
742but fill it in as much as you can.
743
744
745
746=item Prepare for code review
747
748When you are done, the code will undergo a code review by a member of
749the core team, or someone picked by the core team. This is not to
750belittle you (that's just a nice side effect), it is to make sure that
751you understand your code, that we understand your code, that it won't
752break other code, that it follows the documentation and existing
753proposal. It is to check for possible optimizations or better ways of
754doing it.
755
756Note that all code is expected to follow the coding principles and style
757guide contained in this document.
758
759
760=item Finish it up
761
762After the code is done (possibly going through multiple code reviews),
c33a4027
MKG
763if you do not have repository access, submit it to rt-bugs@fsck.com as a
764unified diff. From that point on, it'll be handled by someone with
765repository access.
84fb5b46
MKG
766
767=back
768
769
770=head1 BUG REPORTS, PATCHES
771
c33a4027
MKG
772Use rt-bugs@bestpractical.com for I<any> bug that is not being fixed
773immediately. If it is not in RT, there is a good chance it will not be
774dealt with.
84fb5b46 775
c33a4027
MKG
776Send patches to rt-bugs@bestpractical.com, too. Use C<diff -u> for
777patches.
84fb5b46
MKG
778
779=head1 SCHEMA DESIGN
780
781RT uses a convention to denote the foreign key status in its tables.
782The rule of thumb is:
783
784=over 4
785
786=item When it references to another table, always use the table name
787
788For example, the C<Template> field in the C<Scrips> table refers to
789the C<Id> of the same-named C<Template> table.
790
791=item Otherwise, always use the C<Id> suffix
792
793For example, the C<ObjectId> field in the C<ACL> table can refer
794to any object, so it has the C<Id> suffix.
795
796=back
797
798There are some legacy fields that did not follow this rule, namely
799C<ACL.PrincipalId>, C<GroupMembers.GroupId> and C<Attachments.TransactionId>,
800but new tables are expected to be consistent.
801
802
803=head1 EXTENDING RT CLASSES
804
805=head2 The Overlay mechanism
806
807RT's classes allow "overlay" methods to be placed into files named Filename_Vendor.pm and Filename_Local.pm
808_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.
809
810These overlay files can contain new subs or subs to replace existing subs in this module.
811
812Each of these files should begin with the line
813
814 no warnings qw(redefine);
815
816so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
817
818=head1 TO DO
819
820Talk about DBIx::SearchBuilder
821
822Talk about mason
823 component style
824 cascading style sheets
af59614d 825
84fb5b46
MKG
826Talk about adding a new translation
827
828Talk more about logging