Konstrukt::Doc::Tutorial::Plugin::Note::Actions - 1) Create a simple note taking plugin performing different actions
This tutorial will teach you how to create a simple plugin, which uses the CGI-action -> plugin-method mapping to perform different tasks according to an action CGI parameter.
action
This is especially useful, when writing a plugin, where the user can perform several actions like creating content, viewing it, deleting it and so on.
Note: For the setup of the usage of custom plugins see "SETUP" in Konstrukt::Doc::Tutorial::Plugin::Randomline.
We will create a plugin, that by default shows a note, that is stored in a text file on the server (if exists). It also shows a link to actions, which allow the user to edit and delete the note.
We can identify these actions:
default: show the note, if exists
edit: show a form to edit the note or save the note, if a new one is entered
delete: show a confirmation to delete to note or delete the note if the deletion has been confirmed
First, create a file (e.g. note.html) with this content:
note.html
<& note / &> <a href="?">show</a>
Create a file note.pm in your custom plugin directory with this skeleton:
note.pm
package Konstrukt::Plugin::note; use strict; use warnings; use base 'Konstrukt::SimplePlugin'; #show the note if exists sub default : Action { my ($self, $tag, $content, $params) = @_; print 'note action'; } #show a form to edit the note or save the note, if a new one is entered sub edit : Action { my ($self, $tag, $content, $params) = @_; print 'edit action'; } #show a confirmation to delete to note #or delete the note if the deletion has been confirmed sub delete : Action { my ($self, $tag, $content, $params) = @_; print 'delete action'; } 1;
You can now point your web browser to the web page (e.g. note.html) and you will see the text:
note action
which is the output of the default action.
You can manually specify the actions, that should be executed by supplying the CGI parameter note_action. For example, you could call the website with the URL note.html?note_action=edit and you'll see this text:
note_action
note.html?note_action=edit
edit action
If you enter an action, that does not exist, an error will be produced. If you enter no action, the default action will be executed. Note that you must add the : Action attribute to your methods to let them be accessible from the outside.
: Action
We want to read a file from disk and display the contents on the web page. If no note exists, display a form to create one. So we replace the print statement of the default action with this code:
print
default
my $text = $Konstrukt::File->read("/note.txt"); if (defined $text) { print $text; print ' <br /> <a href="?note_action=edit">edit</a><br /> <a href="?note_action=delete">delete</a>'; } else { $self->edit($tag, $content, $params); }
Now we add the functionality to edit the note. If no text is specified and a note already exists, a form with the existing text will be displayed. Otherwise an empty form will be displayed. If a new text is specified, we overwrite the existing node.
We replace the print statement of the edit action with this code:
edit
if (exists $params->{text}) { #overwrite note $Konstrukt::File->write("/note.txt", $params->{text}); $self->default($tag, $content, $params); } else { #display a form to edit the note my $text = $Konstrukt::File->read("/note.txt") || '(no note yet)'; print " <form action=\"\" method=\"post\"> <input type=\"hidden\" name=\"note_action\" value=\"edit\" /> <textarea name=\"text\">$text</textarea> <input type=\"submit\" value=\"Save\" /> </form>"; }
Now we only need to handle the deletion of the note. If the CGI parameter delete is true, the file will be deleted. Otherwise a confirmation to delete the file will be displayed.
delete
We replace the print statement of the delete action with this code:
if (exists $params->{delete} and $params->{delete}) { #delete note unlink $Konstrukt::File->absolute_path("/note.txt"); print "Note deleted!\n"; $self->default($tag, $content, $params); } else { #display a confirmation form print " <form action=\"\" method=\"post\"> <input type=\"hidden\" name=\"note_action\" value=\"delete\" /> <input type=\"checkbox\" id=\"delete\" name=\"delete\" value=\"1\" /> <label for=\"delete\">Really delete the note?</label> <input type=\"submit\" value=\"Delete\" /> </form>"; }
That's it! Restart/reload your Apache, and try it out.
That's a minimal example. Usually you should not print out HTML from your plugins - instead you should use templates, which contain the HTML.
Also the hardcoded filename to the file containing the note is not very flexible. You might use a filename that is specified in a tag attribute:
<& note file="/foo.txt" / &>
This can then be accessed though the $tag reference:
$tag
my $filename = $tag->{tag}->{attributes}->{file};
Additionally you could just store the note in a database.
Templating and database usage are topics of the next tutorials.
package Konstrukt::Plugin::note; use strict; use warnings; use base 'Konstrukt::SimplePlugin'; #show the note, if exists sub default : Action { my ($self, $tag, $content, $params) = @_; my $text = $Konstrukt::File->read("/note.txt"); if (defined $text) { print $text; print ' <br /> <a href="?note_action=edit">edit</a><br /> <a href="?note_action=delete">delete</a>'; } else { $self->edit($tag, $content, $params); } } #show a form to edit the note or save the note, if a new one is entered sub edit : Action { my ($self, $tag, $content, $params) = @_; if (exists $params->{text}) { #overwrite note $Konstrukt::File->write("/note.txt", $params->{text}); $self->default($tag, $content, $params); } else { #display a form to edit the note my $text = $Konstrukt::File->read("/note.txt") || '(no note yet)'; print " <form action=\"\" method=\"post\"> <input type=\"hidden\" name=\"note_action\" value=\"edit\" /> <textarea name=\"text\">$text</textarea> <input type=\"submit\" value=\"Save\" /> </form>"; } } #show a confirmation to delete to note #or delete the note if the deletion has been confirmed sub delete : Action { my ($self, $tag, $content, $params) = @_; if (exists $params->{delete} and $params->{delete}) { #delete note unlink $Konstrukt::File->absolute_path("/note.txt"); print "Note deleted!\n"; $self->default($tag, $content, $params); } else { #display a confirmation form print " <form action=\"\" method=\"post\"> <input type=\"hidden\" name=\"note_action\" value=\"delete\" /> <input type=\"checkbox\" id=\"delete\" name=\"delete\" value=\"1\" /> <label for=\"delete\">Really delete the note?</label> <input type=\"submit\" value=\"Delete\" /> </form>"; } } 1;
Copyright 2006 Thomas Wittek (mail at gedankenkonstrukt dot de). All rights reserved.
This document is free software. It is distributed under the same terms as Perl itself.
Next: Konstrukt::Doc::Tutorial::Plugin::Note::Template
Previous: Konstrukt::Doc::Tutorial::Plugin::Randomline
Parent: Konstrukt::Doc
See also: Konstrukt::SimplePlugin, Konstrukt::Doc::CreatingPlugins, Konstrukt::File
To install Konstrukt, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Konstrukt
CPAN shell
perl -MCPAN -e shell install Konstrukt
For more information on module installation, please visit the detailed CPAN module installation guide.