WB is a yet another [small] [editable] [mobility] perl web [PSGI] framework with [predeclared behaviour]
- DB
- File - Class support for upload files
- Model - Control of /lib/Model
- ModelCore - Base class for all models
- Request
- Response
- Router - Main work class
- Template
- Util
- get repository
https://github.com/western/wirtualbox
- run
make
command - developer environment start for default 8090 port - run
make run
- start daemon for default 8090 port - run
make kill
- kill daemon
System support follow requests on low level:
get( '/path/to/' => 'Package::Full::Name::and_his_action' )
post( '/path/to/' => 'Package::Full::Name::and_his_action' )
- root - declare action for
root "/"
request - resource
- scope - combine some sources with location
Resource is a automatic generator for all source methods REST support Example, resource 'namething' make:
- GET
/namething/new
forNamething::new
sub - POST
/namething
-Namething::create
- GET
/namething/:id/edit
-Namething::edit
- GET
/namething/:id/del
-Namething::del
- POST
/namething/:id
-Namething::update
- GET
/namething/:id
-Namething::show
- GET
/namething/
-Namething::index
# app.pl code source
use lib 'lib';
use WB::Router qw(:def); # export some functions
my $app = sub {
WB::Router->new(
env => shift,
template_engine => 'HTML::Template',
secret => '0IkJmbamAN@cboU&hHJxtruU1cI!5Lf4',
)->dispatch(
root 'Page::index',
get( '/auth' => 'Auth::index' ),
);
};
- / - will work with
/lib/Controller/Page.pm
- /auth - with
/lib/Controller/Auth.pm
# app.pl code source
use lib 'lib';
use WB::Router qw(:def); # export some functions
my $app = sub {
WB::Router->new(
env => shift,
template_engine => 'HTML::Template',
secret => '0IkJmbamAN@cboU&hHJxtruU1cI!5Lf4',
)->dispatch(
root 'Page::index',
get( '/auth' => 'Auth::index' ),
post( '/auth/login' => 'Auth::login' ),
get( '/auth/logout' => 'Auth::logout' ),
get('/admin' => 'Admin::Page::index'),
scope('/admin' => [
get('/vm/:uuid' => 'Admin::Vm::show'),
get('/vm/new' => 'Admin::Vm::new'),
resource 'photo',
scope('/admin/inside' => [
resource 'doc',
]),
]),
);
};
- get / - will work with
/lib/Controller/Page.pm
- get /auth -
/lib/Controller/Auth.pm
- post /auth/login
- get /auth/logout - 'Auth::logout' if you declare "one package name and one action" - path is /lib/Controller/Auth
- get /admin -
/lib/Admin/Page.pm
- 'Admin::Page::index' if you set "several package names Admin::Page:: and one action" - path is/lib/Admin/Page.pm
- get /admin/vm/:uuid - 'Admin::Vm::show' with param 'uuid' ( $args->{uuid} )
- get /admin/vm/new - 'Admin::Vm::new'
- resource 'photo' - make several actions. See Resource next.
- /admin/inside/ + /doc/ resource
Common code of controller:
# file /lib/Controller/Photo.pm
package Controller::Photo;
use utf8;
use WB::Util qw(:def);
1;
Full controller source:
# file /lib/Controller/Photo.pm
package Controller::Photo;
use utf8;
use WB::Util qw(:def);
required 'App::auth_required'; # Controller::App with action "auth_required"
template_layout 'admin'; # main template
sub new {
my($self, $r, $args) = @_;
}
sub create {
my($self, $r, $args) = @_;
}
sub edit {
my($self, $r, $args) = @_;
}
sub del {
my($self, $r, $args) = @_;
}
sub update {
my($self, $r, $args) = @_;
}
sub show {
my($self, $r, $args) = @_;
}
sub index {
my($self, $r, $args) = @_;
}
1;
app.pl
get('/photo/some/:uuid' => 'Photo::some_change'),
Controller:
# file /lib/Controller/Photo.pm
package Controller::Photo;
use utf8;
use WB::Util qw(:def);
sub some_change {
my($self, $r, $args) = @_;
warn $args->{uuid};
}
By default you can create only package empty. And templates will be use.
# file /lib/Controller/Photo.pm
package Controller::Photo;
use utf8;
use WB::Util qw(:def);
sub some_change {
my($self, $r, $args) = @_;
# by default, system get find /template/Controller/Photo/some_change.html
# and 'main' layout
$r->response->template_args(
head_title => 'some title of page',
);
}
Controller:
# file /lib/Controller/Photo.pm
package Controller::Photo;
use utf8;
use WB::Util qw(:def);
template_layout 'admin'; # main template
#template_layout 'none'; # continue without main template
# if you do not set template_layout, system set by default 'main'
# define /photo/some/:uuid
# and call /photo/some/111-222-333
sub some_change {
my($self, $r, $args) = @_;
if ( $args->{uuid} ) {
# by default, system get find /template/Controller/Photo/some_change.html
$r->response->template_args(
list => [1, 2, 3],
uuid => $args->{uuid},
head_title => 'some title of page',
);
# but you can change template file
$r->response->template_file(
'template_file', 'template_layout'
);
}
}
Send json data:
# file /lib/Controller/Photo.pm
package Controller::Photo;
use utf8;
use WB::Util qw(:def);
sub some_change {
my($self, $r, $args) = @_;
if ( $args->{uuid} ) {
# send content-type: application/json;charset=utf-8
# and json data
$r->response->json({
name1 => 'xtra',
val2 => 95,
});
}
}
package Model::Article;
use base WB::ModelCore;
__PACKAGE__->config( table_name => 'articles' );
__PACKAGE__->config( define_type => {
'articles.body' => 'Wysiwyg',
'articles.title' => 'Edit',
});
__PACKAGE__->belong_to( user_id => 'users.id' );
__PACKAGE__->has_many( id => 'comments.article_id' );
1;
package Model::User;
use base WB::ModelCore;
__PACKAGE__->config( table_name => 'users' );
1;
sub index {
my($self, $r, $args) = @_;
# get database handle
$r->model->db;
# or
$r->model->Article->db;
# select * from articles
$r->model->Article->list;
# get value registered from first row
$r->model->Article->list->[0]->{registered}->value;
# $r->model->Article->join( 'users' )->list->[0];
# $r->model->Article->join( 'left users' )->list->[0];
# $r->model->Article->join( 'left users' => 'articles.user_id = users.xx' )->list->[0];
# $r->model->Article->join( 'comments' )->list->[0];
# $r->model->Article->join( 'left comments' )->list->[0];
# $r->model->Article->join( 'users' )->list()->[0];
# $r->model->Article->join( 'users' )->list->[0];
# $r->model->Article->join( 'users' )->list( -flat => 1 )->[0];
# $r->model->Article->join( 'users' )->list( -data => 1 )->[0];
# $r->model->Article->join( 'users' )->list( -data => 1 );
}
package WB::Type::Int;
use base WB::Type::Basement;
1;
package WB::Type::Wysiwyg;
use base WB::Type::Text;
sub value {
my $self = shift;
my $value = shift;
$self->{value} = $value if ( defined $value );
'[['.$self->{value}.']]';
}
1;