wiki:PadrePluginCookbookRecipie05

Version 38 (modified by bowtie, 3 years ago) (diff)

--

<-menu

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,

Deceleration

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 Padre::Plugin::Name.pm.
    our $VERSION = '0.01';
    

Methods

plugin_name

  • 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 text to be displayed in a Wx-object, more to follow relating to translations.
  3. If you chose to use menu_plugins , you should consider the use of an ellipsis.
    #######
    # Define Plugin Name required
    #######
    sub plugin_name {
        return Wx::gettext('Plugin Cookbook');
    }
    

plugin_menu

You have a Choice, you can have a menu and sub menus, or just an item on the tools.

plugin_menu_simple

sub menu_plugins_simple {
    my $self = shift;
    return $self->plugin_name => [
        'About' => sub { $self->show_about },

        # 'Another Menu Entry' => sub { $self->other_method },
        # 'A Sub-Menu...' => [
        #     'Sub-Menu Entry' => sub { $self->yet_another_method },
        # ],
    ];
}

From My Plugin, covered in screen cast.

If you chose this option, you should consider the use of an ellipsis in plugin_name.

sub menu_plugins {
    my $self = shift;
    my $main = $self->main;

    # Create a manual menu item
    my $item = Wx::MenuItem->new( undef, -1, $self->plugin_name, );
    Wx::Event::EVT_MENU(
        $main, $item,
        sub {
            local $@;
            eval {
                $self->load_dialog_main($_[0]);
            };
        },
    );

    return $item;
}

see Padre::Plugin::FormBuilder


padre_interfaces

  • 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.91',
      
              # used by Main, About and by Padre::Plugin::FormBuilder
              'Padre::Wx'             => '0.91',
              'Padre::Wx::Main'       => '0.91',
              'Padre::Wx::Role::Main' => '0.91',
              'Padre::Logger'         => '0.91',
          );
      }
      
  • draft needs tiding up
    bowtie
        Padre::Plugin POD, padre_interfaces, lists Padre modules and version numbers.
        1, is it upto date
        2, it appairs to me you only need, 'Padre::Plugin' => 0.nn,
    Alias
        You need to declare everything you use
        So if you use Padre::Logger, you need to declare that
        If you do $plugin->main->some_method you need to do Padre::Wx::Main
        etc
        You declare the parts of Padre that you use
        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
    bowtie
        but plugins still work and don't through any errors or warnings at present
    Alias
        You THINK they work
        They MIGHT work
        But you can't know that
        This is about failure modes
        We have a choice about how we want plugins to fail
        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
        2. Disable some plugins due to "compatibility" which really will still work, just in case one was using the specific part you changed
        In the first case, we have unknown and uncontrolled impact, and random side effects, any of which are potentially disastrous
        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
        The second is much more responsible, and much safer when there's no firewall between the plugins and the core
        Firefox doesn't even give THAT much leeway
        Every plugin is automatically disabled, until they SPECIFICALLY test they still work
        We are at least doing piece-meal disable on a per class basis
        Which is more cpan friendly
    bowtie
        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?
    Alias
        Usually yes
        But someone might have checked that one specific class hasn't changed in the place we care about further back
        Or one plugin might depend on another plugin
        And so on
    bowtie
        I will add this to cookbook wiki then, ok
    Alias
        But USUALLY they will all be the same
    bowtie
        the POD shows diffrent versions
    Alias
        Well, it IS theoretically possible
    bowtie
        so hidden some whare in your brain is an padre-plugin api version v padre version numbers then :)
    Alias
        api version is the same
        Padre::Plugin is just another class that the plugin "depends on"
    bowtie
        from POD, Padre::Plugin - Padre plug-in API 2.2
    Alias
        oh, that
        That's mostly just a way of mentally marking time
        It's not really any kind of official thing
    bowtie
        yes it's confuses me
    Alias
        Basically it just says "We've completely rewritten it twice, and made some big additions twice since then"
        It's for humans, not machines
        A bit like Padre::Task 2.0
    bowtie
        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
    Alias
        You don't have to
        You just say the most recent version of Padre you are SURE that the plugin works with
        And Padre itself tracks compatibility for you
    bowtie
        ie developed against :)
    Alias
        our $COMPATIBLE = '0.43';
        That's in Padre::Plugin
        So at a guess, the last time I broke compatibility for ALL plugins was likely 2.0 landing
    bowtie
        POD shows 0.29
    Alias
        Which means 2.0 probably arrived around about 0.43
    bowtie
        can I do perl dev -t Class::Name, Class::Name2
    Alias
        Nope
    bowtie
        only one :(
        all modules used by a Plugin that are not part of Padre core should be in sub plugin_disable
        even if required
    Alias
        All plugin modules should be
        Don't unload third party modules
        You have no idea if anything else needs them
    bowtie
        you mean Mouse for example
    Alias
        right
        Only unload the plugin's own modules
    bowtie
        ok if a Plugin over loads sub plugin_icon
    Alias
        You can overload pretty much anything you like
    bowtie
        you are so happy it must be your un-Birthday again :), thanks
    

plugin_enable

  • 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/ );
    find(
        sub {
            if ( $_ eq 'pdflatex' ) {
                $pdflatex_exists = 1;
            }
        },
        @directories
    );

    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

  • 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}->Destroy;
            $self->{dialog} = undef;
        }
    
        # Unload all our child classes
        $self->unload(
            qw{
            Padre::Plugin::Cookbook::Recipe01::Main
            Padre::Plugin::Cookbook::Recipe01::FBP::MainFB
            Padre::Plugin::Cookbook::Recipe02::Main
            Padre::Plugin::Cookbook::Recipe02::FBP::MainFB
            Padre::Plugin::Cookbook::Recipe03::Main
            Padre::Plugin::Cookbook::Recipe03::FBP::MainFB
            Padre::Plugin::Cookbook::Recipe03::About
            Padre::Plugin::Cookbook::Recipe03::FBP::AboutFB
            Padre::Plugin::Cookbook::Recipe04::Main
            Padre::Plugin::Cookbook::Recipe04::FBP::MainFB
            Padre::Plugin::Cookbook::Recipe04::About
            Padre::Plugin::Cookbook::Recipe04::FBP::AboutFB
        }
        );
       
        $self->SUPER::plugin_disable(@_);
        
        return 1;    
    }
    

plugin_icon

  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 );
    }
    

registered_documents

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

From Padre::Plugin::LaTeX

NB don't forget to check Padre/MimeTypes.pm %EXT_MIME section already contains your type. Vivtek+


POD

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.

DEBUG

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

or

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

Translations


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

Build

  • 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/Cookbook.pm';

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

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

# 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
install_share;

WriteAll;
  • 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.


CPAN

this is probably our end goal.

  • public repository
  • about dialogue

Additional documentation

or Marketing your Plug-in and Padre

  • trac wiki
  • blogg

Tickets

Please Create New Tickets with the following additional information.

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

Miscellaneous

ellipsis

Label the menu item with a trailing ellipsis ("...") only if the command requires further input from the user before it can be performed. Do not add an ellipsis to items that only present a confirmation dialog (such as Delete), or that do not require further input (such as Properties, Preferences or About).

see sample from Padre::Plugin::Patch

FormBuilder fbp

We are now suggesting that all Plug-in Dialogues should be in a single file; as Padre::Plugin::FormBuilder now supports *.fbp with multiple dialogues enclosed. This is shown below:

├── Changes
├── lib
├── Makefile.PL
├── Padre-Plugin-ParserTool.fbp
└── t

code sample from Padre::Plugin::ParserTool

new current standard, thanks Alias :)

__END__

<-menu

Attachments (1)

Download all attachments as: .zip