Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

RFC: Padre::Plugin::MyTemplates

by gsiems (Chaplain)
on Oct 07, 2009 at 03:16 UTC ( #799644=perlmeditation: print w/ replies, xml ) Need Help??

Greetings fellow monastarians,

I've been looking a bit at Padre lately and thought that I'd try my hand at creating a plugin for it. While the documentation for creating plugins is rather thin, it didn't take very long or require too much poking around the source to create a useful (for me) plugin.

One of the features of Padre is the ability to create new documents from templates-- however, the templates list is hard-coded in the app which doesn't lend itself well towards creating/maintaining lots of different templates. Toward that end I decided to create a "My Templates" plugin that would allow me to maintain my own list of document creation templates.

My reasons for posting this plugin are as follows:

  • 1. I think this is actually good enough to share, so
  • 2. I'm wondering if this is worth putting up on CPAN, and
  • 3. if so, what does it take to do that.

As usual, comments/criticisms/suggestions are (probably) most welcome.

package Padre::Plugin::MyTemplates; use 5.008; use strict; use warnings; use Padre::Constant (); use Padre::Current (); use Padre::Locale (); use Padre::Plugin (); use Padre::Wx (); use File::Path qw(make_path); our $VERSION = '0.11'; our @ISA = 'Padre::Plugin'; ##################################################################### # Padre::Plugin Methods sub plugin_name { 'My Templates'; } sub padre_interfaces { 'Padre::Plugin' => 0.43; } sub menu_plugins_simple { my ($self) = @_; my $template_dir = $self->template_dir(); my $template_idx = $self->index_file(); my @menu; if ( -f $template_idx ) { # Parse the index and dynamically create the menu items for th +e various # templates listed in the index. my $IN; if ( open( $IN, '<', $template_idx ) ) { push @menu, Wx::gettext("Edit Index") => sub { $self->edit +_index() }; # TODO: Provide a spiffy graphical way to add templates # push @menu, Wx::gettext("Add Template") => sub { $self-> +add_template() }; my @entries = grep {m/^\s*[^#]/} (<$IN>); chomp @entries; close $IN; foreach my $i (@entries) { my ( $label, $file ) = split /\s+\|\s+/, $i; next unless ( $label && $file ); $file =~ s/\s+$//; # Determine if the file is fully specified or if it is + located # in the CONFIG_DIR templates directory. unless ( -f $file ) { my $test = File::Spec->catfile( $template_dir, $fi +le ); $file = $test if ( -f $test ); } next unless ( -f $file ); push @menu, sprintf( Wx::gettext("New %s"), $label ) = +> sub { $self->new_from_template($file) }; } } else { $self->show_error( "Error reading template index:", $templ +ate_idx, $! ); } } else { @menu = ( Wx::gettext("Initialize") => sub { $self->create_ind +ex() }, ); } MyTemplates => [@menu]; } ##################################################################### # Custom Methods sub template_dir { my ($self) = @_; return File::Spec->catfile( Padre::Constant::CONFIG_DIR, 'template +s' ); } sub index_file { my ($self) = @_; return File::Spec->catfile( $self->template_dir(), 'template.index +' ); } sub create_index { my ($self) = @_; # Ensure that the template directory exists my $template_dir = $self->template_dir(); make_path($template_dir) unless ( -d $template_dir ); unless ( -d $template_dir ) { $self->show_error( "Template directory does not exist:", $temp +late_dir ); return; } # Create a skeleton index file my $template_idx = $self->index_file(); my $OUT; if ( open( $OUT, '>', $template_idx ) ) { print $OUT <<"EOT"; # MyTemplate template index # # This file should contain one line for each template in this director +y. # # Entries are a pipe separated list of the form: # template label | file name # # Comment lines start with a '#' # POD | template.pod EOT close $OUT; # Create a sample template my $template = File::Spec->catfile( $template_dir, 'template.p +od' ); if ( open( $OUT, '>', $template ) ) { # We don't want this showing up in the plugin POD my @text = ( '=pod', '=head1 Heading Text', '=head2 Heading Text', '=head3 Heading Text', '=head4 Heading Text', '=over indentlevel', '=item stuff', '=back', '=begin format', '=end format', '=for format text...', '=encoding type', '=cut', ); print $OUT +( join "\n\n", @text ), "\n"; close $OUT; # Reload the plugin in order to update the menu $self->current->ide->plugin_manager->reload_plugin('Padre: +:Plugin::MyTemplates'); } else { $self->show_error( "Error creating sample template:", $tem +plate, $! ); } } else { $self->show_error( "Error creating template index:", $template +_idx, $! ); } } sub show_error { my ( $self, $text, $item, $bang ) = @_; $bang ||= ''; $self->current->main->message( sprintf( Wx::gettext("$text '%s'\n\n"), $item ) . $bang ); } sub add_template { my ($self) = @_; # TODO: # We need to prompt the user for: # 1. the file to add # 2. a label for the file # 3. whether to leave the file where it is or copy it to their tem +plate directory # Update the index # Reload the plugin in order to update the menu # $self->current->ide->plugin_manager->reload_plugin('Padre::Plugi +n::MyTemplates'); # Until we figure that all out... $self->current->main->message( Wx::gettext('This feature has not been implemented yet...'), Wx::gettext('Notice') ); } sub edit_index { my ($self) = @_; my $template_idx = $self->index_file(); $self->current->main->setup_editors($template_idx); } sub new_from_template { my ( $self, $file ) = @_; # Load up a new editor tab... $self->current->main->on_new; # ...and insert the template text into the tab. # (Rather shamelessly copied from Padre::Wx::Main b.t.w.) my $editor = $self->current->editor or return; if ( $editor->insert_from_file($file) ) { my $document = $editor->{Document}; $document->{original_content} = $document->text_get; $document->set_mimetype( $document->guess_mimetype ); $document->editor->padre_setup; $document->rebless; $document->colourize; } else { $self->show_error( "Error loading template file '%s'", $file ) +; } return; } 1; __END__ =head1 NAME Padre::Plugin::MyTemplates - A personal templates plugin =head1 DESCRIPTION Allows users to have maintain their own set of templates for use in cr +eating new files. Template information is stored in a template.index file in the user's ~/.padre/templates directory. Template entries are listed in the index file, one template per line, +as a pipe separated list of the form: template label | file name Template files are assumed to exist in the user's ~/.padre/templates d +irectory. Template file information that is stored with the full path/name of th +e file may be located anywhere that the user has read access to. Comment lines start with a '#' and are ignored. Blank lines are also i +gnored. =head1 AUTHOR Gregory Siems E<lt>gsiems@gmail.comE<gt> =head1 COPYRIGHT AND LICENSE Copyright (C) 2009 by Gregory Siems This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. =cut

-- gsiems

Comment on RFC: Padre::Plugin::MyTemplates
Download Code
Replies are listed 'Best First'.
Re: RFC: Padre::Plugin::MyTemplates
by toolic (Bishop) on Oct 07, 2009 at 19:18 UTC
Re: RFC: Padre::Plugin::MyTemplates
by LanX (Canon) on Oct 07, 2009 at 17:13 UTC
    Hi

    I have to admit that I don't have Padre running on my system but I think every professional editor needs a template system.

    Just wanna propose an idea I had last time talking with Gabor:

    I started to use yasnippet with emacs which is actually a port from the textmate template format, making snippets interchangeable between both editors. (textmate is the most hyped editor ATM and a role model in usability, but restricted to Mac OS).

    So having a universal templateformat which is editor agnostic would be a bless, maybe allowing plugins to export to vi-templates (?) or to whatever editor else.

    But exploring emacs already swallows all my energy, so maybe you want to pick up this idea as a suggestion?

    hope this helps! 8)

    Cheers Rolf

      Very nice. Way beyond the scope of what I was/am trying to accomplish ATM. FWIW, Padre has a snippet capability already built in but it appears to require menu interaction to use-- having that sort of code expansion/completion would be seriously cool...

      It's almost enough to make me want to learn emacs.

      --gsiems

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://799644]
Approved by herveus
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (10)
As of 2015-07-31 04:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (274 votes), past polls