[Rt-commit] rt branch, 4.0/writing-rt-extensions-doc, updated. rt-4.0.6-261-gf3565c2

Jim Brandt jbrandt at bestpractical.com
Fri Jan 3 11:10:14 EST 2014


The branch, 4.0/writing-rt-extensions-doc has been updated
       via  f3565c2b871c334b3fee4b357c17bb5c7599e125 (commit)
       via  abafceffa27be1d2f61bfe38d7e6dff54afb03a2 (commit)
       via  72d37ffb65d9b05a37d4150c151f059476d251bd (commit)
      from  38f4250710efc8df41884e7caca2335f741122ab (commit)

Summary of changes:
 docs/writing-extensions.pod | 176 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 143 insertions(+), 33 deletions(-)

- Log -----------------------------------------------------------------
commit 72d37ffb65d9b05a37d4150c151f059476d251bd
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Jan 3 10:16:39 2014 -0500

    Add docs on writing tests and clean up callback path example

diff --git a/docs/writing-extensions.pod b/docs/writing-extensions.pod
index b50e0b7..5ab592f 100644
--- a/docs/writing-extensions.pod
+++ b/docs/writing-extensions.pod
@@ -65,7 +65,8 @@ you're using some sort of version control for your work.
 
 There are several places to put code to provide your new features
 and if you follow the guidelines below, you'll make sure things
-get installed in the right places when you're ready to use it.
+get installed in the right places when you're ready to use it. These standards
+apply to RT 4.0 and 4.2 and any differences between the two are noted below.
 
 =head2 Module Code
 
@@ -84,6 +85,11 @@ that will use these callbacks. See L</Callbacks> for more information.
 Your Mason templates should go in an C<html> directory with the appropriate
 directory structure to make sure the callbacks are executed.
 
+If you are creating completely new pages for RT, you can put thes under the
+C<html> directory also. You can create subdirectories as needed to add the
+page to existing RT paths (like Tools) or to create new directories for your
+extension.
+
 =head2 CSS and Javascript
 
 Where these files live differs between RT 4.2 and above, and RT 4.0 and
@@ -105,7 +111,14 @@ the paths correctly, you should only need to set the file names like this:
 
 If you need to have users create a group, scrip, template, or some other
 object in their RT instance, you can automate this using an F<initialdata>
-file. If you need this, the file should go in the C<etc> directory.
+file. If you need this, the file should go in the C<etc> directory. This will
+allow users to easily run the F<initialdata> file when installing with:
+
+    make initdb
+
+Make sure to note this step in your installation instructions. You can read
+more about F<initialdata> files in the
+L<RT initialdata documentation|http://bestpractical.com/docs/rt/latest/initialdata.html>.
 
 =head2 Module::Install Files
 
@@ -124,14 +137,55 @@ You can find details in the module documentation.
 
 =head2 Tests
 
+=head3 Test Directory
+
 You can create tests for your new extension just as with other perl code
 you write. However, unlike typical CPAN modules where users run the tests
 as a step in the installation process, RT users installing extensions don't
 usually run tests. This is because running the tests requires your RT to
 be set up in development mode which involves installing some additional
-modules and having a dev instance. To prevent users from accidentally
-running the tests, we put them in a C<xt> directory rather than the typical
-C<t> directory.
+modules and having a test database. To prevent users from accidentally
+running the tests, which will fail without this testing setup, we put them in
+a C<xt> directory rather than the typical C<t> directory.
+
+=head3 Writing Extension Tests
+
+If you want to write and run tests yourself, you'll need a development RT
+instance set up. Since you are building an extension, you probably already have
+one. To start with testing, set the C<RTHOME> environment variable to the base
+directory of your RT instance so your extension tests run against the right
+instance. This is especially useful if you have your test RT installed in a non-standard location.
+
+Next, you need to subclass from L<RT::Test|http://bestpractical.com/docs/rt/latest/RT/Test.html>
+which gives you access to the test RT and a test database for running
+tests. For this, you'll create a F<Test.pm> file in your C<lib> tree.
+The easiest way to set up the test module to pull in F<RT::Test> is to look at
+an example extension. L<RT::Extension::RepeatTicket>, for example, has a
+testing configuration you can borrow from.
+
+You'll notice that the file included in the extension is
+F<lib/RT/Extension/RepeatTicket/Test.pm.in>. This is because there are paths
+that are set based on your RT location, so the actual F<Test.pm> file is
+written when you run F<Makefile.PL> with appropriate paths substituted
+when F<Makefile.PL> is run. L<Module::Install> provides an interface to make
+this easy with a C<substitute> feature. The substitution code is in the
+F<Makefile.PL> file and you can borrow that as well.
+
+Once you have that set up, add this to the top of your test files:
+
+    use RT::Extension::Demo::Test tests => undef;
+
+and you'll be able to run tests in the context of a fully functioning RT
+instance. The L<RT::Test|http://bestpractical.com/docs/rt/latest/RT/Test.html>
+documentation describes some of the helper methods available and you can
+look at other extensions and the RT source code for examples of how to
+do things like create tickets, queues, and users, how to set rights, and
+how to modify tickets to simulate various RT tasks.
+
+If you have a command-line component in your extension, the easiest way
+to test it is to set up a C<run> method using the Modulino approach.
+You can find an example of this approach in L<RT::Extension::RepeatTicket>
+in the F<bin> directory.
 
 =head2 Patches
 
@@ -147,21 +201,23 @@ have extra code.
 
 =head2 Directory Structure
 
-RT looks in the following path for callbacks:
+RT looks in the F<local/plugins> directory under the RT base directory for
+extensions registered with the C<@Plugins> configuration. RT then uses the
+following structure when looking for callbacks:
 
-    local/html/Callbacks/[custom_name]/[rt mason path]/[callback name]
+    local/plugins/[ext name]/html/Callbacks/[custom name]/[rt mason path]/[callback name]
 
 The extension installation process will handle some of this for you by putting
-your html directory under C<local> as part of the installation process.
-You need to make sure the path under C<html> is correct since that is installed
-as-is.
+your html directory under F<local/plugins/[ext name]> as part of the
+installation process. You need to make sure the path under C<html> is correct
+since that is installed as-is.
 
 The C<Callbacks> directory is required. The next directory can be named
 anything and is provided to allow RT owners to keep local files organized
 in a way that makes sense to them. In the case of
 an extension, you should name the directory the same as your extension.
 So if your extension is C<RT::Extension::Demo>, you should create a
-C<RT-Extension-Demo> directory under C<Callbacks>.
+F<RT-Extension-Demo> directory under F<Callbacks>.
 
 The rest of the path is determined by the RT Mason code and the callback you
 want to use. You can find callbacks by looking for calls to the C<callback>
@@ -172,25 +228,25 @@ RT directory:
 
 As an example, assume you wanted to modify the ticket update page to put
 something after the Time Worked field. You run the above and see there is
-a callback in C<share/html/Ticket/Update.html> that looks like this:
+a callback in F<share/html/Ticket/Update.html> that looks like this:
 
     $m->callback( %ARGS, CallbackName => 'AfterWorked', Ticket => $TicketObj );
 
-You look at the Update.html file and see that the callback is located
+You look at the F<Update.html> file and see that the callback is located
 right after the Time Worked field. To add some code that RT will
 run at that point, you would create the directory:
 
     html/Callbacks/RT-Extension-Demo/Ticket/Update.html/
 
-Note that Update.html is a file in the RT source, but it becomes a directory
+Note that F<Update.html> is a file in the RT source, but it becomes a directory
 in your extension code. You then create a file with the name of the
-callback, in this case C<AfterWorked>, and that's where you put your code.
+callback, in this case F<AfterWorked>, and that's where you put your code.
 So the full path and file would be:
 
     html/Callbacks/RT-Extension-Demo/Ticket/Update.html/AfterWorked
 
 If you see a callback that doesn't have a C<CallbackName> parameter, name
-your file C<Default> and it will get invoked since that is the default
+your file F<Default> and it will get invoked since that is the default
 callback name when one isn't provided.
 
 =head2 Callback Parameters
@@ -234,7 +290,7 @@ extension distribution. In general, you should only provide patches
 if you know they will eventually be merged into RT. Otherwise, you
 may have to provide versions of your patches for each release of RT.
 You can read more about getting changes accepted into RT in the
-L<hacking> document.
+L<hacking> document. We generally accept patches that add new callbacks.
 
 Create a C<patches> directory in your extension distribution to hold
 your patch files. Name the patch files with the latest verison of RT
@@ -251,8 +307,6 @@ the patch.
 
 # TODO:
 
-# Add docs about how to set up testing
-
 # Add docs about final distribution steps (make dist, etc.)
 
 # Add docs about best way to extend email handling with
@@ -261,9 +315,3 @@ the patch.
 # Add info on creating additional web pages in html, where
 # they are installed, and how to add to the RT menu
 
-# Perhaps clarify callback paths more.  For non-plugins, it gets put
-# into local/html, but that's neither where plugins install into
-# (local/plugins/RT-Extension-Demo/html) nor the path to use inside your
-# extension.
-
-# Mention that we generally just accept patches to add callbacks

commit abafceffa27be1d2f61bfe38d7e6dff54afb03a2
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Jan 3 10:29:20 2014 -0500

    Add docs on final CPAN release steps

diff --git a/docs/writing-extensions.pod b/docs/writing-extensions.pod
index 5ab592f..81e66b2 100644
--- a/docs/writing-extensions.pod
+++ b/docs/writing-extensions.pod
@@ -303,6 +303,38 @@ patches using the same naming convention.
 Also remember to update your install documentation to remind users to apply
 the patch.
 
+=head1 Preparing for CPAN
+
+When you have your extension ready and want to release it to the world, you
+can do so with a few simple steps.
+
+Assuming you have run C<perl Makefile.PL> and you created the F<inc/.author>
+directory as described above, a F<README> file will be created for you. You can
+now type:
+
+    make manifest
+
+and a F<MANIFEST> file will be created. It should contain all of the needed
+to install and run your extension. If you followed the steps above, you'll have
+also have a F<inc> directory which contains L<Module::Install> code. Note that
+this code should also be included with your extension when you release it as
+it's part of the install process.
+
+Next, check to see if everything is ready with:
+
+    make distcheck
+
+If anything is missing, it will be reported and you can go fix it.
+When the check is clean, run:
+
+    make dist
+
+and a new distribution will be created in the form of a tarred and gzipped
+file.
+
+Now you can upload to cpan with the F<cpan-upload> utility provided by
+L<CPAN::Uploader> or your favorite method of uploading to CPAN.
+
 =cut
 
 # TODO:

commit f3565c2b871c334b3fee4b357c17bb5c7599e125
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Jan 3 11:09:46 2014 -0500

    Add menu example plus some link cleanup

diff --git a/docs/writing-extensions.pod b/docs/writing-extensions.pod
index 81e66b2..fef6c2f 100644
--- a/docs/writing-extensions.pod
+++ b/docs/writing-extensions.pod
@@ -36,7 +36,7 @@ not putting your code on CPAN.
 If this is your first time using L<Dist::Zilla>, you can set up your
 CPAN detals by running:
 
-    # dzil setup
+    dzil setup
 
 You can read about L<Dist::Zilla> and the C<dzil> command at L<http://dzil.org>.
 
@@ -44,7 +44,7 @@ Change to the directory that will be the parent directory for your new
 extension and run the following, replacing Demo with a descriptive name
 for your new extension:
 
-    # dzil new -P RTx RT-Extension-Demo
+    dzil new -P RTx RT-Extension-Demo
 
 You'll see something like:
 
@@ -116,16 +116,15 @@ allow users to easily run the F<initialdata> file when installing with:
 
     make initdb
 
-Make sure to note this step in your installation instructions. You can read
-more about F<initialdata> files in the
-L<RT initialdata documentation|http://bestpractical.com/docs/rt/latest/initialdata.html>.
+Make sure to note this step in your installation instructions. The
+L<Initialdata> documentation has details on the format.
 
 =head2 Module::Install Files
 
 As mentioned above, the RT extension tools are set up to use L<Module::Install>
 to manage the distribution. When you run
 
-    # perl Makefile.PL
+    perl Makefile.PL
 
 for the first time, L<Module::Install> will create an C<inc> directory for all
 of the files it needs. Since you are the author, a C<.author> directory
@@ -156,7 +155,7 @@ one. To start with testing, set the C<RTHOME> environment variable to the base
 directory of your RT instance so your extension tests run against the right
 instance. This is especially useful if you have your test RT installed in a non-standard location.
 
-Next, you need to subclass from L<RT::Test|http://bestpractical.com/docs/rt/latest/RT/Test.html>
+Next, you need to subclass from L<RT::Test>
 which gives you access to the test RT and a test database for running
 tests. For this, you'll create a F<Test.pm> file in your C<lib> tree.
 The easiest way to set up the test module to pull in F<RT::Test> is to look at
@@ -176,7 +175,7 @@ Once you have that set up, add this to the top of your test files:
     use RT::Extension::Demo::Test tests => undef;
 
 and you'll be able to run tests in the context of a fully functioning RT
-instance. The L<RT::Test|http://bestpractical.com/docs/rt/latest/RT/Test.html>
+instance. The L<RT::Test>
 documentation describes some of the helper methods available and you can
 look at other extensions and the RT source code for examples of how to
 do things like create tickets, queues, and users, how to set rights, and
@@ -274,6 +273,47 @@ to give you idea what you can do in your callback code. You can also look
 at other extensions for examples of how people use callbacks to modify
 and extend RT.
 
+=head1 Adding and Modifying Menus
+
+You can modify all of RT's menus using callbacks as described in L</Callbacks>.
+The file in RT that controls menus is:
+
+    share/html/Elements/Tabs
+
+and you'll find a Privileged and SelfService callback which gives you access
+to those two sets of menus. In those callbacks, you can add to or change
+the main menu, the page menu, or the page widgets.
+
+You can look at the F<Tabs> file itself for examples of adding menu items.
+The menu object is a L<RT::Interface::Web::Menu> and you can find details on
+the available parameters in the documentation.
+
+Here are some simple examples of what you might do in a callback:
+
+    <%init>
+    # Add a brand new root menu item
+    my $bps = Menu()->child(
+        'bps', # any unique identifier
+        title => 'Corporate',
+        path  => 'http://bestpractical.com'
+    );
+
+    #Add a submenu item to this root menu item
+    $bps->child(
+        'wiki',
+        title => 'Wiki',
+        path  => 'http://wiki.bestpractical.com',
+    );
+
+    #Retrieve the 'actions' page menu item
+    if (my $actions = PageMenu->child('actions')) {
+        $actions->child(
+            'newitem',
+            title => loc('New Action'), path => '/new/thing/here',
+        )
+    }
+    </%init>
+
 =head1 Changes to RT
 
 When writing an extension, the goal is to provide all of the new functionality
@@ -337,13 +377,3 @@ L<CPAN::Uploader> or your favorite method of uploading to CPAN.
 
 =cut
 
-# TODO:
-
-# Add docs about final distribution steps (make dist, etc.)
-
-# Add docs about best way to extend email handling with
-# mail plugins
-
-# Add info on creating additional web pages in html, where
-# they are installed, and how to add to the RT menu
-

-----------------------------------------------------------------------


More information about the rt-commit mailing list