=pod
=head1 NAME
Hyper::Developer::Manual::Example - Example Hyper Application
=head1 VERSION
This document describes Hyper::Developer::Manual::Example 0.03
=head1 DESCRIPTION
Hyper is a Workflow and Service/Usecase based Web Framework.
After creating a new environment for your Hyper stuff
developing applications with Hyper can be splitted into three
different parts.
=over
=item Modelling
Define Workflows and Controls.
=item Programming
Add your own code to your pages, to interfaces and add additonal things.
=item Beautifying
Modify generated templates (HTML) and add JavaScript for Show/Hide etc.
=back
=head1 REQUIREMENTS
You need to install the following Perl packages.
=over
=item *
Hyper
=item *
Hyper::Developer
=item *
Authen::Htpasswd
=back
=head1 SAMPLE
Let's look at our sample:
You want to create a workflow for changing passwords. Usernames
and passwords are stored in a .htpasswd file. The tasks should
be placed on three different pages.
=over
=item Page 1 - choose_username
With a username select, where the selection is required. There
should be an button to go to the next page.
=item Page 2 - change_password
Two fields - one for the new password and another one to confirm the
new password. Both entered passwords must match, before the password
will be changed. The fields are required fields. There should be
a button to go to next page.
=item Page 3 - confirmation
Confirm the password change and show page 1 again.
=back
=head1 CREATE NEW ENVIRONMENT
Depending on your operating system you maybe need to change the permissions
of the directory /srv using chmod.
Then run the following command:
hyper.pl --base_path=/srv/www.example.com/ --namespace=Example --type=env
If this is your first Hyper Usecase you have to create a new environment.
=head1 MODELLING
=head2 Page 1
Create a file
/srv/www.example.com/etc/Example/Control/Container/User/CSelectUsername.ini
with the following Content
[Control]
[Control user]
class=Hyper.Control.Base.BSelect
[Control submit]
class=Hyper.Control.Base.BPushButton
[Step]
[Step START]
[Step START Show]
[Step Show]
controls=<<EOT
user
submit
EOT
[Step Show END]
condition=submit.pushed();
[Step END]
To get rid of the syntax, have a look at L<Hyper::Config::Reader::Container>
To generate code and a template from this file call
hyper.pl --template --file=/srv/www.example.com/etc/Example/Control/Container/User/CSelectUsername.ini
=head2 Page 2
Create a file
/srv/www.example.com/etc/Example/Control/Container/User/CChangePassword.ini
with the following content
[Control]
[Control compare_passwords]
class=Hyper.Control.Validator.Group
[Control compare_passwords Validator Group Hyper.Validator.Group.Compare]
[Control new_password]
class=Hyper.Control.Base.BInput
[Control new_password Validator Single Hyper.Validator.Single.Required]
[Control new_password Validator Named compare_passwords]
act_as=first
[Control repeat_new_password]
class=Hyper.Control.Base.BInput
[Control repeat_new_password Validator Single Hyper.Validator.Single.Required]
[Control repeat_new_password Validator Named compare_passwords]
act_as=second
[Control submit]
class=Hyper.Control.Base.BPushButton
[Step]
[Step START]
[Step START Show]
[Step Show]
controls=<<EOT
new_password
repeat_new_password
compare_passwords
submit
EOT
[Step Show END]
condition=submit.pushed() && this.is_valid();
[Step END]
To get rid of the syntax, have a look at L<Hyper::Config::Reader::Container>
To generate code and a template from this file call
hyper.pl --template --file=/srv/www.example.com/etc/Example/Control/Container/User/CChangePassword.ini
=head2 Page 3
Create a file
/srv/www.example.com/etc/Example/Control/Container/User/CConfirmation.ini
with the following content
[Control]
[Control submit]
class=Hyper.Control.Base.BPushButton
[Step]
[Step START]
[Step START Show]
[Step Show]
controls=<<EOT
submit
EOT
[Step Show END]
condition=submit.pushed();
[Step END]
To get rid of the syntax, have a look at L<Hyper::Config::Reader::Container>
To generate code and a template from this file call
hyper.pl --template --file=/srv/www.example.com/etc/Example/Control/Container/User/CConfirmation.ini
=head2 Connecting the Pages
Create a file
/srv/www.example.com/etc/Example/Control/Flow/User/FChangePassword.ini
with the following content
[Control]
[Control select_username]
class=Example.Control.Container.User.CSelectUsername
[Control change_password]
class=Example.Control.Container.User.CChangePassword
[Control confirmation]
class=Example.Control.Container.User.CConfirmation
[Step]
[Step START]
[Step START select]
[Step select]
controls=<<EOT
select_username
EOT
[Step select change]
condition=select_username.state eq 'END'
[Step change]
controls=<<EOT
change_password
EOT
[Step change confirm]
condition=change_password.state eq 'END'
[Step confirm]
action=<<EOT
select_username.state='START';
EOT
controls=<<EOT
confirmation
EOT
[Step confirm select]
condition=confirmation.state eq 'END'
[Step END]
To get rid of the syntax, have a look at L<Hyper::Config::Reader::Flow>
To generate code and a template from this file call
hyper.pl --file=/srv/www.example.com/etc/Example/Control/Flow/User/FChangePassword.ini
=head1 Verify your work
Before we do the programming part it's time to see what we've created since yet.
You can use the integrated Developer Webserver to do this
perl /srv/www.example.com/bin/example/server.pl
Now connect to your page via your webbrowser using
Now you see your first Hyper usecase. You can't go from Page 1 to Page 2
because the username select is a required field. So we have to fill
the username select with some data.
=head1 Programming
=head2 Create Data Source
Create the file
/srv/www.example.com/.htpasswd
with the following content
Andreas:X
Martin:X
Helmut:X
=head2 Fill the username select
Open the generated file
/srv/www.example.com/lib/Example/Control/Flow/User/FChangePassword.pm
and add the following code before the __END__ mark
use Authen::Htpasswd;
sub _get_authen_object :PRIVATE {
return Authen::Htpasswd->new('/srv/www.example.com/.htpasswd');
}
sub ACTION_select {
my $self = shift;
$self->get_object('select_username')->get_object('user')->set_elements([
map {
{ value => $_->username(), data => $_->username() };
} $self->_get_authen_object()->all_users()
]);
return $self;
}
sub ACTION_confirm {
my $self = shift;
$self->_get_authen_object()->update_user(
$self->get_object('select_username')
->get_object('user')
->get_value(),
$self->get_object('change_password')
->get_object('new_password')
->get_value(),
);
return $self;
}
To get more information (e.g. why should you name this subroutines ACTION_* ?)
have a look at L<Hyper::Control::Flow>
=head1 Verify your work
Now restart your Developer Webserver and
connect again to your page via your webbrowser using
Your usecase should be completely useable (but maybe it looks ugly).
=head1 Beautifying
Now you can edit the default templates *.htc located below
/srv/www.example.com/var/Example/
=head1 INCOMPATIBILITIES
=head1 BUGS AND LIMITATIONS
=head1 RCS INFORMATIONS
=over
=item Last changed by
$Author: ac0v $
=item Id
$Id: Example.pod 320 2008-02-16 02:04:51Z ac0v $
=item Revision
$Revision: 320 $
=item Date
$Date: 2008-02-16 03:04:51 +0100 (Sat, 16 Feb 2008) $
=item HeadURL
=back
=head1 AUTHOR
Andreas Specht C<< <ACID@cpan.org> >>
=head1 LICENSE AND COPYRIGHT
Copyright (c) 2007, Andreas Specht C<< <ACID@cpan.org> >>.
All rights reserved.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut