Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

RFC: Padre::Plugin::MyTemplates

by gsiems (Deacon)
on Oct 07, 2009 at 03:16 UTC ( [id://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

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 (Saint) 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
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-04-23 12:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found