Version 26 (modified by bowtie, 7 years ago) (diff)



Icons DEBUG and Translations DRAFT

or some sort of Conformance and all the bit's I have missed so far :)

Padre::Plugin::Cookbook Recipe-05 DRAFT

This page compleats Padre::Plugin::Cookbook series, It is just meant to be an aid, with a suggested layout and some ideas to speed you along your way, enjoy.

  • Unlike the previous recipes which have covered, Plug-ins with dialogs, this is more concerned, with conformance, playing nice with Padre.
  • The following is as a result of analysing Plug-ins for this page.
  • The examples here, where relevant will build upon Cookbook, some relate to other Plug-ins as it is more pertinent to use them,


Initial thoughts, of what a Padre::Plugin should provide, critiques welcome.

Things to do to enable Plugin Manager to load your Plug-in

Plugin must have a Version

  • For compliance you will need to have a version in your
    our $VERSION = '0.01';



  • Plugin must have a Name Don't forget to include the following sub.
  1. ok I must be stupid but with out the return the POD just confused me, it's to terse.
  2. Wx::gettext(...) this is use to wrap all test to be displayed in a Wx-object, more to follow relating to translations.
    # Define Plugin Name required
    sub plugin_name {
        return Wx::gettext('Plugin Cookbook');


  • Plugin must declare it's Interfaces, all Padre Modules should be included, just look at some other Plug-ins to see the pattern.
    • Don't forget to include the following sub.
    • Use the version number of Padre you are developing against, as shown below.
      # Define Padre Interfaces required
      sub padre_interfaces {
          return (
              # Default, required
              'Padre::Plugin' => '0.84',
              # used by Main, About and by Padre::Plugin::FormBuilder
              'Padre::Wx' => 0.84,
              'Padre::Wx::Main' => '0.86',
              'Padre::Wx::Role::Main' => 0.84,
              'Padre::Logger' => '0.84',
  • draft needs tiding up
    12:05 bowtie     Alias_, Padre::Plugin POD, padre_interfaces, lists Padre modules and version numbers.
    12:05 bowtie     1, is it upto date
    12:05 bowtie     2, it appairs to me you only need, 'Padre::Plugin' => 0.nn,
    12:05 Alias_     You need to declare everything you use
    12:05 Alias_     So if you use Padre::Logger, you need to declare that
    12:05 Alias_     If you do $plugin->main->some_method you need to do Padre::Wx::Main
    12:05 Alias_     etc
    12:06 Alias_     You declare the parts of Padre that you use
    12:06 Alias_     So when we break compatibility in one part of Padre, ALL the plugins that use it aren't loaded, but ONLY the plugins that use it are disabled
    12:07 bowtie     Alias_, but plugins still work and don't through any errors or warnings at present
    12:07 Alias_     You THINK they work
    12:07 Alias_     They MIGHT work
    12:07 Alias_     But you can't know that
    12:07 Alias_     This is about failure modes
    12:07 Alias_     We have a choice about how we want plugins to fail
    12:08 Alias_     1. Always have every plugin load, wait for each one to do something illegal in Padre and blow up, leaving it half-loaded or in some unknown state and maybe crashing PAdre
    12:08 Alias_     2. Disable some plugins due to "compatibility" which really will still work, just in case one was using the specific part you changed
    12:09 Alias_     In the first case, we have unknown and uncontrolled impact, and random side effects, any of which are potentially disasterous
    12:09 Alias_     In the second case, plugin authors need to check they still work, bump the plugin's dependency hash past the change, and do a simple incremental release
    12:10 Alias_     The second is much more responsible, and much safer when there's no firewall between the plugins and the core
    12:10 Alias_     Firefox doesn't even give THAT much leeway
    12:10 Alias_     Every plugin is automatically disabled, until they SPECIFICALLY test they still work
    12:10 Alias_     We are at least doing piece-meal disable on a per class basis
    12:10 Alias_     Which is more cpan friendly
    12:11 bowtie     Alias_, ok, so the the the modules version will be that of the Padre version it was created against, hence all module version numbers should be the same?
    12:12 Alias_     Usually yes
    12:12 Alias_     But someone might have checked that one specific class hasn't changed in the place we care about further back
    12:13 Alias_     Or one plugin might depend on another plugin
    12:13 Alias_     And so on
    12:13 bowtie     Alias_, I will add this to cookbook wiki then, ok
    12:13 Alias_     But USUALLY they will all be the same
    12:13 bowtie     Alias_, the POD shows diffrent versions
    12:13 Alias_     Well, it IS theoretically possible
    12:15 bowtie     Alias_, so hidden some whare in your brain is an padre-plugin api version v padre version numbers then :)
    12:15 Alias_     api version is the same
    12:15 Alias_     Padre::Plugin is just another class that the plugin "depends on"
    12:16 bowtie     Alias_, from POD, Padre::Plugin - Padre plug-in API 2.2
    12:16 Alias_     oh, that
    12:16 Alias_     That's mostly just a way of mentally marking time
    12:16 Alias_     It's not really any kind of official thing
    12:16 bowtie     Alias_, yes it's confuses me
    12:17 Alias_     Basically it just says "We've completely rewritten it twice, and made some big additions twice since then"
    12:17 Alias_     It's for humans, not machines
    12:18 Alias_     A bit like Padre::Task 2.0
    12:18 bowtie     Alias_, on reflection I got that, but I don't know what the padre version was then, and if I use that version will a plugin be back compatable
    12:19 Alias_     You don't have to
    12:19 Alias_     You just say the most recent version of Padre you are SURE that the plugin works with
    12:19 Alias_     And Padre itself tracks compatibility for you
    12:19 bowtie     Alias_, I developed against :)
    12:20 Alias_     our $COMPATIBLE = '0.43';
    12:20 bowtie     oops i -> ie
    12:20 Alias_     See that?
    12:20 Alias_     That's in Padre::Plugin
    12:20 Alias_     So at a guess, the last time I broke compatibility for ALL plugins was likely 2.0 landing
    12:20 bowtie     Alias_, POD shows 0.29
    12:20 Alias_     Which means 2.0 probably arrived around about 0.43
    12:23 bowtie     Alias_, ca I do perl dev -t Class::Name, Class::Name2
    12:23 Alias_     Nope
    12:23 bowtie     only one :(
    12:25 bowtie     Alias_, all modules used by a Plugin that are not part of Padre core should be in sub plugin_disable
    12:26 bowtie     even if required
    12:26 Alias_     All plugin modules should be
    12:26 Alias_     Don't unload third party modules
    12:26 Alias_     You have no idea if anything else needs them
    12:27 bowtie     Alias_, you mean Mouse for example
    12:27 Alias_     right
    12:27 Alias_     Only unload the plugin's own modules
    12:29 bowtie     Alias_, ok if a Plugin over loads sub plugin_icon
    12:30 * azawawi  home &
    12:35 Alias_     You can overload pretty much anything you like
    12:36 bowtie     Alias_, you are so happy it must be your un-Birthday again :), thanks


  • Some Plug-ins will require a plugin_enable method,
    • Why because it's using an external resource, which is not being picked up via perl (M::I).
    • You can see this only has Ubuntu locations, at precsent it needs more OS file locations adding.
# We need plugin_enable
# as we have an external dependency
sub plugin_enable {

    my $pdflatex_exists = 0;
    # ToDo add other os locations
    # Ubuntu -> /usr/bin/
    my @directories = qw( /usr/bin/ );
        sub {
        if ( $_ eq 'pdflatex' ) {
        $pdflatex_exists = 1;

return $pdflatex_exists;

From Padre::Plugin::LaTeX

Padre::Plugin::SpellCheck dose not need this as it depends upon Text::Aspell which won't install with out Aspell files being present.


  • Plugin_disable is a must so that we can load and unloaded our Plug-in repeatedly, using Tools -> Reload All Plug-ins.

Don't forget to include all the relevant sections.

  1. Wx::Dialogs, as shown
  2. your plugin modules, as shown, see Recipe-03 need link
  3. other cpan modules that are pertinent to only your plugin, such as sockets or demons, not shown.
  4. boot n braces, as shown, this is a new development, run SUPER plugin_disable, an Ode to before :)
    sub plugin_disable {
        my $self = shift;
        # Close the dialog if it is hanging around
        if ( $self->{dialog} ) {
            $self->{dialog} = undef;
        # Unload all our child classes
        return 1;    


  1. from Padre::Plugin
    sub plugin_icon {
        my $class = shift;
        my $share = $class->plugin_directory_share or return;
        my $file  = File::Spec->catfile( $share, 'icons', '16x16', 'logo.png' );
        return unless -f $file;
        return unless -r $file;
        return Wx::Bitmap->new( $file, Wx::wxBITMAP_TYPE_PNG );
  1. To define your your own icon, you can overload the method.
    # Add icon to Plugin
    sub plugin_icon {
        my $class = shift;
        my $share = $class->plugin_directory_share or return;
        my $file  = File::Spec->catfile( $share, 'icons', '16x16', 'cookbook.png' );
        return unless -f $file;
        return unless -r $file;
        return Wx::Bitmap->new( $file, Wx::wxBITMAP_TYPE_PNG );


  • only if you have them
    sub registered_documents {
        'application/x-latex' => 'Padre::Document::LaTeX',
        'application/x-bibtex' => 'Padre::Document::BibTeX',;

From Padre::Plugin::LaTeX


I have found Catalyst::Controller::POD to be the best way to view POD for me, as it correctly formats, highlights and colourise the syntax. it may be overkill but it's pretty.

  • Licence
  • Acknowledge others
    • Fail: Padre POD viewer displays an error
    • Poor: Fail < Poor < Min
    • Min, contains: NAME, AUTHOR, LICENCE
    • acceptable: Min < acceptable < Good
    • Good, contains: VERSION, BUGS AND LIMITATIONS, DEPENDENCIES. Passes xt/pod.t and xt/podcoverage.t for all Plugin files.


This is cool

  • now I can keep my say(print) statements, but turn then on when I want, with out littering the terminal :)

try the following

perl dev -a -t Padre::Plugin::Swarm::Transport::Global::WxSocket


perl dev -a -t Padre::Plugin::Cookbook::Recipe04::Main


OS Support,

don't forget to consider, your Plug-in should ideally work on all of the following platforms.

  • Linux
    • 64 bit
    • i386/i686
  • Microsoft
    • Vista
    • XP
  • Apple
    • Lion
    • Snow Leopard
    • Leopard


  • Plug-in builds so it can be install in local repository
    • We recommend using Module::Include at present, and suggest following in Makefile.PL
      • The use of Module::Include also enables the use of our plug-in via perl dev -a
  • Don't forget to include all the Perl modules, you require from CPAN
  • if install_share appears not to work, check your MANIFEST, or just re-name it to .old.
use inc::Module::Install 1.01;

# Define meta-data
abstract 'Cookbook contains recipes to assist you in making your own Padre::Plugin';

# All from our plugin
all_from 'lib/Padre/Plugin/';

# Recommended, Alias+
requires_from 'lib/Padre/Plugin/Cookbook/Recipe01/';
requires_from 'lib/Padre/Plugin/Cookbook/Recipe02/';
requires_from 'lib/Padre/Plugin/Cookbook/Recipe03/';
requires_from 'lib/Padre/Plugin/Cookbook/Recipe04/';

# Padre version, should match that of the latest version, used in padre_interfaces, 
requires 'Padre'                => '0.86';

# required modules from CPAN
requires 'Moose'                => '2.00';
requires 'namespace::autoclean' => '0.12';
requires 'Data::Printer'        => '0.19';

# Optional if you have used the share directory

  • NB Module::Install::API experimental

requires_from command takes a module file path, and looks for use statements with explicit module version (like use Foo::Bar 0.01 ), and from which it sets requires attributes.


this is probably our end goal.

  • public repository
  • about dialogue

Additional documentation

or Marketing your Plug-in and Padre

  • trac wiki
  • blogg


Please Create New Tickets with the following additional information.

  • start summary with Padre::Plugin::....
  • set component = plugins


Attachments (1)

Download all attachments as: .zip