One of WebGUI's greatest strengths is that it works on many operating systems and can connect to many external resources such as LDAP, Database, and web servers. If you're planning on writing plug-ins for or making core changes to WebGUI you should follow the coding guidelines presented here to ensure maximum compatibility. In addition, WebGUI has been built with performance in mind; we try to keep our code neat and elegant, so should you.
We, as a community have decided to adopt Perl Best Practices (PBP) as our best practices for WebGUI. As far as we are concerned you might as well scratch "Perl" off the cover and replace it with "WebGUI".
Note that you can use the CPAN module Perl::Critic to locate PBP violations in your code. Your code should pass Perl::Critic on at least the gentle setting.
The following guidelines are areas where we have decided to override the rules set forth in PBP.
perltidy --perl-best-practices -l=115
Since it's hard to test www_ functions, they don't need to have tests, but all others should. See Developer's Guide To Testing In WebGUI.
Describe how to use the functions and what parameters can be passed to the function. See Plain Old Documentation (POD). After implementing new functionality always write/update any relevant documentation and/or help files. Doing this as you create your code will ensure that everything is always up to date.
Definition subroutines do not need, POD, but all other subroutines do. If you are overriding an inherited method, then tell why in the POD.
All messages to the user should be retrieved from an i18n language package. See Internationalization.
See The Help System.
Apart from the Operation/Profile/View, the Operation/Profile/Edit and the Send Invitation Template almost all templates are selectable. And almost all views are templatable.
Never use . or any other punctuation in your template variable names. Underscore is okay.
HTML and CSS that is generated from Perl creates difficulties in creating and maintaining templates. Avoid generating HTML or CSS in Perl code. If CSS is needed, add it to the asset's stylesheet. If an asset does not have a stylesheet, add one.
If you use javascript, use the YUI library.The Yahoo User Interface Library YUI (http://developer.yahoo.com/yui/) is a Javascript/Ajax library that is bundled with WebGUI. Use it. Make as many reusable parts as possible.
Don't reinvent the wheel. Save yourself a lot of time and effort by using code that someone else has already written for you.
We've built a decent sized code-base within WebGUI. Much of the functionality needed by plug-ins has already been developed; such as URL rewriting, database access, date math, discussions, etc. Also, you may find that the functionality you are looking for has been written by someone else and stored at CPAN (www.cpan.org). The easiest way to find useful modules on CPAN is to use Search CPAN.
If you're careful about how you construct your database statements, you'll be able to stay database agnostic. Here are a few hints:
If you muck around with database tables for an upgrade script, especially asset, assetData, or wobject tables, you need to test back beyond the current upgrade to 6.8.10.
#-------------------------------------------------------------------
sub myMethod {..}
sub _privateMethod {
However, try never to make private methods, unless they absolutely need to be private. You never know what someone outside your module might need from your module, so consider making all your methods public unless they're subject to change or be removed in the near term.
sub www_myMethod {
This means that your subroutines, variables, table names, etc. should consistently have long meaningful names. This keeps the code readable.
Refrain from using the default variable ($_), especially in passing method parameters ($@). Instead, shift off all of the method parameters.
Use OO Design (object-oriented) where it fits and procedural design where it fits. Contrary to popular belief one is not wholly better than the other, and there is a need for both; especially in Perl. For instance, objects are anywhere from 50% to 200% slower than procedural code at runtime (depending upon the situation and the benchmark used). However, objects typically lend themselves to more powerful and reusable functionality. Refer to PBP p319 for further discussion.
You can always make something more granular later, but once it's granular, going back means breaking the API.
For any plug-in you create, select a namespace that is not currently in use by any other plug-in. Make sure that your namespace is descriptive and useful. Use namespaces in package names, incrementers, tables, help, internationalization, etc. Here are some examples:
package WebGUI::Asset::Wobject::MyNewWobject;
create table MyNewWobject ();
create table MyNewWobject_colateralData ();
In any of your asset collateral tables, name the primary key something descriptive. If you need an incrementer for your key, use the table name combined with the column name as the incrementer name. Every incrementer should begin with the namespace to prevent overlap.
All HTML that your code produces (from your default templates or other means) has to be accessible.
Do not use target="_blank" to open new windows and do not use javascript unless there is an alternative to access the content.
Links to files should offer the option to save them or to open them.
This could be reached by adding something like this to all modproxy templates:
<IfModule mod_headers.c>
<FilesMatch "\.(pdf|ppt|doc)$">
Header append Content-Disposition "attachment;"
</FilesMatch>
</IfModule>
It is not required to use Class::InsideOut any longer.
Keywords: testing plugin pbp api Development Best Practices