SlideShare une entreprise Scribd logo
1  sur  38
Télécharger pour lire hors ligne
HTML::FormFu 
Efficient web forms. 
So you can leave at 5pm each day. 
Dean Hamstead 
dean@bytefoundry.com.au
Web frameworks like Catalyst, Mojolicious & Dancer 
take care of repetitive things in web app development such as: 
Connecting your code to an environment 
mod_perl1/2, cgi, fastcgi, nginx_perl etc. 
Mapping URI requests to code 
Authentication, Authorization, Sessions 
Connecting to Databases & ORM’s 
Serialization/Deserialization (JSON, XML etc) 
Templating 
Often built on TT, Alloy etc 
Logging/Debugging levels 
Often built on Log4perl or Log::Dispatch 
SiteMaps, Caching, Browser detection 
Code Bootstrappers
Whats missing? 
Form generation and validation. 
Very rare not to have form’s in software - business applications have lots of them. 
Forms are very boring and repetitive, prone to mistakes and bugs as a result. 
Field data types are frequenly the same things. 
names, addresses, emails, phone numbers, etc. 
State often isn’t tracked properly, making forms vulernable to attacks / mistakes. 
Reliance on client side javascript only to enforce form data integrity is insufficient 
Inconsistent browser handling of js makes this more fun
HTML::FormFu 
A solution that implements a framework and lots of helpers to 
handle forms. 
Simple define your form using a ’DSL’ of sorts. 
(It uses Config::Any so maybe its not a DSL?) 
Plug code in to the various events where things need to happen.
Alternatives deserve a mention: 
CGI::FormBuilder 
even has a Padre plugin! 
HTML::FormHandler 
WWW::Form? 
Others? 
Try them and see what suits you!
HTML::FormFu is a stand alone module... 
in this presentation I will present it via the Catalyst::Controller::HTML::FormFu 
module. 
Find it all on the CPAN. 
cpanm HTML::FormFu 
cpanm Catalyst::Controller::HTML::FormFu 
apt-get install libhtml-formfu-perl libcatalyst-controller-html-formfu-perl
Examples taken from ’PhotoGame’ 
A more than trivial but still small Catalyst app 
(which I authored) 
Catalyst + MySQL using HTML::FormFu and Imager 
https://github.com/djzort/PhotoGame 
Basically a "hot or not" voting game clone 
Used to encourage people to take and upload photos at our LANparty events (so 
we can use them later!) 
Provides a ’tournament’ for photography enthusiasts
How PhotoGame works... 
People register and upload photos 
Uploads are saved to disk, then resized in a cron batch 
Photos can be voted on (A>B or B>A) 
once per A+B combination per user 
Presents a leader board 
Gradually a winner emerges 
Runs just fine on an early Intel Atom
Screenshots...
Screenshots...
Screenshots...
Screenshots...
Screenshots...
Screenshots...
Getting started 
You can use the helper... 
script/myapp_create.pl HTML::FormFu forms 
Which will create the ’root/forms’ directory where form configs will go 
This default location can be changed via config 
(See also perldoc Catalyst::Helper::HTML::FormFu)
Getting started 
Your controller can be converted to using FormFu by changing the extends line to 
this... 
BEGIN { extends ’Catalyst::Controller::HTML::FormFu’ } 
Everything will work as normal, until you add the ’FormConfig’ attribute to a 
subroutine 
(or the ’Form’ or ’FormMethod’ attributes) 
HTML::FormFu can output either HTML or Template Toolkit streams - which are then 
processed by a TT based view.
Getting started 
Configure as you would expect in Catalyst: 
$c->config( ’Controller::HTML::FormFu’ => %my_values ); 
or 
MyApp->config( ’Controller::HTML::FormFu’ => %my_values ); 
or, in myapp.conf 
<Controller::HTML::FormFu> 
default_action_use_path 1 
</Controller::HTML::FormFu>
Form Validation 
Form field input goes through 4 stages, in order, and as long as the result of each 
stage is successful: 
filters - e.g. remove leading/trailing spaces 
constraints - low-level checks 
"is this a number?", "is this a valid e-mail address?" 
inflators - turn a value into an object, ready to be passed to validators 
validators - application-level checks 
"is this username unique?" 
See also http://wiki.catalystframework.org/wiki/howtos/forms/formfu.view
Using FormFu in Catalyst 
You have two options: 
use the $c->stash->{form} object methods, or 
’Special Action Name’ subs 
In either case you add the ’FormConfig’ sub attribute.
Object Methods 
Unload the HTML::FormFu object with $form = $c->stash->{form} 
$form->submitted 
true if form submitted 
$form->has_errors 
true if form has validation errors 
$form->submitted_and_valid 
shorthand for $form->submitted && !$form->has_errors 
$form->param/s, $form->get_error/s 
as per perldoc HTMl::FormFu 
if ($form->submitted_and_valid) { 
#do something 
return 1 
} 
elsif ( ! $form->submitted ) { 
# defaults 
return 1 
} 
else { 
# error handling 
}
Special Action Names 
_FORM_VALID 
Run when the form has been submitted and has no errors. 
_FORM_SUBMITTED 
Run when the form has been submitted, regardless of whether or not there was errors. 
_FORM_COMPLETE 
For MultiForms, is run if the MultiForm is completed. 
_FORM_NOT_VALID 
Run when the form has been submitted and there were errors. 
_FORM_NOT_SUBMITTED 
Run when the form has not been submitted. 
_FORM_NOT_COMPLETE 
For MultiForms, is run if the MultiForm is not completed. 
_FORM_RENDER 
For normal Form base classes, this subroutine is run after any of the other special methods, unless 
$form->submitted_and_valid is true. 
For MultiForm base classes, this subroutine is run after any of the other special methods, unless 
$multi->complete is true.
Lets use ’Special Action Name’ subs to make a login 
form. 
Here is our perl code...
sub login : Path(’login’) : Args(0) : FormConfig { 
my ( $self, $c ) = @_; 
if ( my $me = $c->session->{iam} ) { 
$c->stash->{message} = 
sprintf( ’You’re already logged in as %s, go play!’, $me->{full_name} ); 
$c->detach(’message’); 
} 
} 
sub login_FORM_RENDER { } 
sub login_FORM_NOT_SUBMITTED { } 
sub login_FORM_VALID { 
my ( $self, $c ) = @_; 
if ( my $me = 
$c->model(’DB’)->check_user( 
$c->req->param(’username’), 
$c->req->param(’password’) 
) ) 
{ 
$c->session->{iam} = $me; 
$c->stash->{message} = 
sprintf( ’Welcome %s, lets play!’, $me->{full_name} ); 
$c->detach(’message’); 
} 
else { 
$c->stash->{error} = ’Failed to log in’; 
} 
}
Now lets create the form itself. 
Defined in a config file, named based upon the sub name 
FormFu uses Config::Any - So use a format that suits you 
YAML, JSON, Perl, etc. 
(I have no idea why I used YAML) 
Example follows
root/forms/login.yml 
--- 
action: /login 
indicator: submit 
elements: 
- type: Fieldset 
name: login 
elements: 
- type: Src 
content_xml: "<legend>Login</legend>" 
- type: Text 
name: username 
label: "Username:" 
add_label_attributes: 
class: auto 
attributes: 
id: username 
title: Enter your username 
constraints: 
- Required 
- type: Password 
name: password 
label: "Password:" 
add_label_attributes: 
class: auto 
attributes: 
id: password 
title: Enter your password 
constraints: 
- Required 
- type: Submit
The format/syntax more or less follows what the HTML will look like. 
<form> encompasses a <fieldset> (if you like fieldsets) 
I had to use the ’Src’ tag to manually add xml (html) to add a <legend> tag 
<text> for username and password then a submit button 
These are all implemented in HTML::FormFu::Element::* modules 
Various attributes are defined for each. id, title, class etc 
Constraints are how we tell FormFu how data should be validated 
These are all implemented in HTML::FormFu::Constraint::* modules 
Required means a field must have a value. 
SingleValue ensures multiple values are not submitted.
Out of the box, you get just about everything you can imagine. 
You can easily add more. 
text, textarea, hidden, password 
radio, select, checkbox, 
image, file 
submit/reset buttons. 
derivatives such as email, date, datetime, url 
html elements like hr, fieldset, Src 
constraints for min, max, length, min & max length, number, range 
regex, ascii, email, datetime, word, printable characters, 
set, singlevalue, bool, equal 
Plus many many others (homework for you).
Observation... 
Elements and Constraints are role based 
This makes extending things easy 
But you often have to chase through 2-3 levels of modules’s perldoc to work out 
all available options 
Here is a more complex example in the registration form...
sub register : Path(’register’) : Args(0) : FormConfig { 
my ( $self, $c ) = @_; 
unless ( $c->model(’DB’)->get_setting(’registration_open’) ) { 
$c->stash->{message} = ’Registrations are closed’; 
$c->detach(’message’); 
} 
} 
sub register_FORM_RENDER { 
} 
sub register_FORM_NOT_SUBMITTED { 
} 
sub register_FORM_VALID { 
my ( $self, $c ) = @_; 
$c->model(’DB’)->create_photographer( 
username => $c->req->param(’username’), 
password => $c->req->param(’password’), 
full_name => $c->req->param(’full_name’), 
email_addr => $c->req->param(’email_addr’), 
creation_ip => $c->req->address, 
); 
$c->stash->{message} = ’user created’; 
$c->detach(’message’); 
} 
sub register_FORM_NOT_VALID { 
my ( $self, $c ) = @_; 
$c->stash->{error} = ’Submission failed, see comments above’; 
}
config is root/forms/register.yml 
--- 
action: /register 
indicator: submit 
output_processors: 
- Indent 
elements: 
- type: Fieldset 
name: register 
elements: 
- type: Src 
content_xml: "<legend>Register to Compete!</legend>" 
- type: Text 
name: full_name 
label: "Full Name:" 
attributes: 
id: fullname 
title: Full Name 
constraints: 
- type: Required 
- type: Text 
name: email_addr 
label: "Email:" 
attributes: 
id: emailaddr 
title: Email Address
- type: Text 
name: username 
label: "Username:" 
attributes: 
id: username 
title: Username 
constraints: 
- type: Required 
- type: Length 
min: 2 
max: 255 
validators: 
- ’+PhotoGame::Validator::UniqueUsername’ 
- type: Password 
name: password 
label: "Password:" 
attributes: 
id: password 
title: Password 
constraints: 
- type: Required 
- type: Length 
min: 6 
max: 255 
- type: Equal 
others: repeat-password 
- type: Password 
name: repeat-password 
label: "Repeat:"
- type: Submit 
name: submit 
value: Go 
constraints: 
- SingleValue
The registration form has lots of examples of what can be used. 
’Required’ constraing in all cases 
’Email’ constraint used on email field 
’Min’ and ’Max’ lenfth used on username and password field 
’Equal’ to ensure sameness of dual password fields 
’Src’ and ’Hr’ used for a bit of formatting 
Output processor of ’Indent’ makes the HTML look pretty 
adds cpu, but soothes perfectionist urges :) 
Custom constraint ’+PhotoGame::Validator::UniqueUsername’ 
which checks the DB for username uniqueness
Calls in to the model to check if the username is already used. 
Dies with a HTML::FormFu::Excepton object 
PhotoGame/Validator/UniqueUsername.pm 
package PhotoGame::Validator::UniqueUsername; 
use strict; 
use warnings; 
use base ’HTML::FormFu::Validator’; # use parent might be better? 
sub validate_value { 
my ( $self, $value, $params ) = @_; 
my $c = $self->form->stash->{context}; 
if ($c->model(’DB’)->username_taken($value)) { 
die HTML::FormFu::Exception::Validator->new({ 
message => ’username taken’, 
}); 
} 
return 1 
} 
1
As you can see its very easy to add/edit/remove form elements. 
It’s easy enough that junior or non-programmers can get it right. 
Lots and lots of boring code is gone, 
which is still good even if you use YAML. 
Web Designers can whip up form modifications for clients and finalize them, 
before handing them to developers to tie in to the database (an ORM may avoid that 
step entirely) 
Using common type constraints will give you consistency through out your 
software (instead of email being a different regex in different locations, sometimes 
with MX look ups) 
HTML::FormFu may add more CPU usage, 
depending on how good/bad your coding is.
You can do cool AutoCRUD stuff with FormFu and DBIC. 
A talk for another day. 
HTML::FormFu::ExtJS exists. 
Promising to generate Javascript forms for you based on ExtJS.
Questions?
ENDE

Contenu connexe

Tendances

Slimme Joomla! Templating Tips en Truuks
Slimme Joomla! Templating Tips en TruuksSlimme Joomla! Templating Tips en Truuks
Slimme Joomla! Templating Tips en TruuksThemePartner
 
Django Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksDjango Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksShawn Rider
 
Jinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask MeetupJinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask MeetupAlan Hamlett
 
Testing ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using RubyTesting ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using RubyBen Hall
 
Php forms and validations by naveen kumar veligeti
Php forms and validations by naveen kumar veligetiPhp forms and validations by naveen kumar veligeti
Php forms and validations by naveen kumar veligetiNaveen Kumar Veligeti
 
Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16Shashikant Bhongale
 
Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16Shashikant Bhongale
 
One App Cloud - Custom CSS and Javascript
One App Cloud - Custom CSS and Javascript One App Cloud - Custom CSS and Javascript
One App Cloud - Custom CSS and Javascript One App Cloud
 
Data validation in web applications
Data validation in web applicationsData validation in web applications
Data validation in web applicationssrkirkland
 
Building Potent WordPress Websites
Building Potent WordPress WebsitesBuilding Potent WordPress Websites
Building Potent WordPress WebsitesKyle Cearley
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkDirk Haun
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascriptambuj pathak
 
Web components with Angular
Web components with AngularWeb components with Angular
Web components with AngularAna Cidre
 
Form validation client side
Form validation client side Form validation client side
Form validation client side Mudasir Syed
 
Unbreakable Domain Models PHPUK 2014 London
Unbreakable Domain Models PHPUK 2014 LondonUnbreakable Domain Models PHPUK 2014 London
Unbreakable Domain Models PHPUK 2014 LondonMathias Verraes
 

Tendances (20)

Slimme Joomla! Templating Tips en Truuks
Slimme Joomla! Templating Tips en TruuksSlimme Joomla! Templating Tips en Truuks
Slimme Joomla! Templating Tips en Truuks
 
Django Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksDjango Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, Tricks
 
Jinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask MeetupJinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask Meetup
 
Testing ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using RubyTesting ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using Ruby
 
Exception handling
Exception handlingException handling
Exception handling
 
Php forms and validations by naveen kumar veligeti
Php forms and validations by naveen kumar veligetiPhp forms and validations by naveen kumar veligeti
Php forms and validations by naveen kumar veligeti
 
Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16
 
Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16
 
One App Cloud - Custom CSS and Javascript
One App Cloud - Custom CSS and Javascript One App Cloud - Custom CSS and Javascript
One App Cloud - Custom CSS and Javascript
 
Symfony 2
Symfony 2Symfony 2
Symfony 2
 
Escaping Dependency Hell v2
Escaping Dependency Hell v2Escaping Dependency Hell v2
Escaping Dependency Hell v2
 
Data validation in web applications
Data validation in web applicationsData validation in web applications
Data validation in web applications
 
Building Potent WordPress Websites
Building Potent WordPress WebsitesBuilding Potent WordPress Websites
Building Potent WordPress Websites
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 
Web components with Angular
Web components with AngularWeb components with Angular
Web components with Angular
 
Chat php
Chat phpChat php
Chat php
 
Presenters in Rails
Presenters in RailsPresenters in Rails
Presenters in Rails
 
Form validation client side
Form validation client side Form validation client side
Form validation client side
 
Unbreakable Domain Models PHPUK 2014 London
Unbreakable Domain Models PHPUK 2014 LondonUnbreakable Domain Models PHPUK 2014 London
Unbreakable Domain Models PHPUK 2014 London
 

Similaire à HTML::FormFu talk for Sydney PM

Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4Javier Eguiluz
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin GeneratorJohn Cleveley
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplicationolegmmiller
 
CICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your MindCICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your Mindciconf
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleKaty Slemon
 
12-security.ppt - PHP and Arabic Language - Index
12-security.ppt - PHP and Arabic Language - Index12-security.ppt - PHP and Arabic Language - Index
12-security.ppt - PHP and Arabic Language - Indexwebhostingguy
 
Implementation of GUI Framework part3
Implementation of GUI Framework part3Implementation of GUI Framework part3
Implementation of GUI Framework part3masahiroookubo
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialYi-Ting Cheng
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii FrameworkNoveo
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc trainingicubesystem
 
Joomla security nuggets
Joomla security nuggetsJoomla security nuggets
Joomla security nuggetsguestbd1cdca
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin Cataldo
 

Similaire à HTML::FormFu talk for Sydney PM (20)

Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin Generator
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
 
CICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your MindCICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your Mind
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
 
12-security.ppt - PHP and Arabic Language - Index
12-security.ppt - PHP and Arabic Language - Index12-security.ppt - PHP and Arabic Language - Index
12-security.ppt - PHP and Arabic Language - Index
 
Security.ppt
Security.pptSecurity.ppt
Security.ppt
 
Implementation of GUI Framework part3
Implementation of GUI Framework part3Implementation of GUI Framework part3
Implementation of GUI Framework part3
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Devise and Rails
Devise and RailsDevise and Rails
Devise and Rails
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii Framework
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc training
 
Joomla security nuggets
Joomla security nuggetsJoomla security nuggets
Joomla security nuggets
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 

Dernier

Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 

Dernier (20)

Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 

HTML::FormFu talk for Sydney PM

  • 1. HTML::FormFu Efficient web forms. So you can leave at 5pm each day. Dean Hamstead dean@bytefoundry.com.au
  • 2. Web frameworks like Catalyst, Mojolicious & Dancer take care of repetitive things in web app development such as: Connecting your code to an environment mod_perl1/2, cgi, fastcgi, nginx_perl etc. Mapping URI requests to code Authentication, Authorization, Sessions Connecting to Databases & ORM’s Serialization/Deserialization (JSON, XML etc) Templating Often built on TT, Alloy etc Logging/Debugging levels Often built on Log4perl or Log::Dispatch SiteMaps, Caching, Browser detection Code Bootstrappers
  • 3. Whats missing? Form generation and validation. Very rare not to have form’s in software - business applications have lots of them. Forms are very boring and repetitive, prone to mistakes and bugs as a result. Field data types are frequenly the same things. names, addresses, emails, phone numbers, etc. State often isn’t tracked properly, making forms vulernable to attacks / mistakes. Reliance on client side javascript only to enforce form data integrity is insufficient Inconsistent browser handling of js makes this more fun
  • 4. HTML::FormFu A solution that implements a framework and lots of helpers to handle forms. Simple define your form using a ’DSL’ of sorts. (It uses Config::Any so maybe its not a DSL?) Plug code in to the various events where things need to happen.
  • 5. Alternatives deserve a mention: CGI::FormBuilder even has a Padre plugin! HTML::FormHandler WWW::Form? Others? Try them and see what suits you!
  • 6. HTML::FormFu is a stand alone module... in this presentation I will present it via the Catalyst::Controller::HTML::FormFu module. Find it all on the CPAN. cpanm HTML::FormFu cpanm Catalyst::Controller::HTML::FormFu apt-get install libhtml-formfu-perl libcatalyst-controller-html-formfu-perl
  • 7. Examples taken from ’PhotoGame’ A more than trivial but still small Catalyst app (which I authored) Catalyst + MySQL using HTML::FormFu and Imager https://github.com/djzort/PhotoGame Basically a "hot or not" voting game clone Used to encourage people to take and upload photos at our LANparty events (so we can use them later!) Provides a ’tournament’ for photography enthusiasts
  • 8. How PhotoGame works... People register and upload photos Uploads are saved to disk, then resized in a cron batch Photos can be voted on (A>B or B>A) once per A+B combination per user Presents a leader board Gradually a winner emerges Runs just fine on an early Intel Atom
  • 15. Getting started You can use the helper... script/myapp_create.pl HTML::FormFu forms Which will create the ’root/forms’ directory where form configs will go This default location can be changed via config (See also perldoc Catalyst::Helper::HTML::FormFu)
  • 16. Getting started Your controller can be converted to using FormFu by changing the extends line to this... BEGIN { extends ’Catalyst::Controller::HTML::FormFu’ } Everything will work as normal, until you add the ’FormConfig’ attribute to a subroutine (or the ’Form’ or ’FormMethod’ attributes) HTML::FormFu can output either HTML or Template Toolkit streams - which are then processed by a TT based view.
  • 17. Getting started Configure as you would expect in Catalyst: $c->config( ’Controller::HTML::FormFu’ => %my_values ); or MyApp->config( ’Controller::HTML::FormFu’ => %my_values ); or, in myapp.conf <Controller::HTML::FormFu> default_action_use_path 1 </Controller::HTML::FormFu>
  • 18. Form Validation Form field input goes through 4 stages, in order, and as long as the result of each stage is successful: filters - e.g. remove leading/trailing spaces constraints - low-level checks "is this a number?", "is this a valid e-mail address?" inflators - turn a value into an object, ready to be passed to validators validators - application-level checks "is this username unique?" See also http://wiki.catalystframework.org/wiki/howtos/forms/formfu.view
  • 19. Using FormFu in Catalyst You have two options: use the $c->stash->{form} object methods, or ’Special Action Name’ subs In either case you add the ’FormConfig’ sub attribute.
  • 20. Object Methods Unload the HTML::FormFu object with $form = $c->stash->{form} $form->submitted true if form submitted $form->has_errors true if form has validation errors $form->submitted_and_valid shorthand for $form->submitted && !$form->has_errors $form->param/s, $form->get_error/s as per perldoc HTMl::FormFu if ($form->submitted_and_valid) { #do something return 1 } elsif ( ! $form->submitted ) { # defaults return 1 } else { # error handling }
  • 21. Special Action Names _FORM_VALID Run when the form has been submitted and has no errors. _FORM_SUBMITTED Run when the form has been submitted, regardless of whether or not there was errors. _FORM_COMPLETE For MultiForms, is run if the MultiForm is completed. _FORM_NOT_VALID Run when the form has been submitted and there were errors. _FORM_NOT_SUBMITTED Run when the form has not been submitted. _FORM_NOT_COMPLETE For MultiForms, is run if the MultiForm is not completed. _FORM_RENDER For normal Form base classes, this subroutine is run after any of the other special methods, unless $form->submitted_and_valid is true. For MultiForm base classes, this subroutine is run after any of the other special methods, unless $multi->complete is true.
  • 22. Lets use ’Special Action Name’ subs to make a login form. Here is our perl code...
  • 23. sub login : Path(’login’) : Args(0) : FormConfig { my ( $self, $c ) = @_; if ( my $me = $c->session->{iam} ) { $c->stash->{message} = sprintf( ’You’re already logged in as %s, go play!’, $me->{full_name} ); $c->detach(’message’); } } sub login_FORM_RENDER { } sub login_FORM_NOT_SUBMITTED { } sub login_FORM_VALID { my ( $self, $c ) = @_; if ( my $me = $c->model(’DB’)->check_user( $c->req->param(’username’), $c->req->param(’password’) ) ) { $c->session->{iam} = $me; $c->stash->{message} = sprintf( ’Welcome %s, lets play!’, $me->{full_name} ); $c->detach(’message’); } else { $c->stash->{error} = ’Failed to log in’; } }
  • 24. Now lets create the form itself. Defined in a config file, named based upon the sub name FormFu uses Config::Any - So use a format that suits you YAML, JSON, Perl, etc. (I have no idea why I used YAML) Example follows
  • 25. root/forms/login.yml --- action: /login indicator: submit elements: - type: Fieldset name: login elements: - type: Src content_xml: "<legend>Login</legend>" - type: Text name: username label: "Username:" add_label_attributes: class: auto attributes: id: username title: Enter your username constraints: - Required - type: Password name: password label: "Password:" add_label_attributes: class: auto attributes: id: password title: Enter your password constraints: - Required - type: Submit
  • 26. The format/syntax more or less follows what the HTML will look like. <form> encompasses a <fieldset> (if you like fieldsets) I had to use the ’Src’ tag to manually add xml (html) to add a <legend> tag <text> for username and password then a submit button These are all implemented in HTML::FormFu::Element::* modules Various attributes are defined for each. id, title, class etc Constraints are how we tell FormFu how data should be validated These are all implemented in HTML::FormFu::Constraint::* modules Required means a field must have a value. SingleValue ensures multiple values are not submitted.
  • 27. Out of the box, you get just about everything you can imagine. You can easily add more. text, textarea, hidden, password radio, select, checkbox, image, file submit/reset buttons. derivatives such as email, date, datetime, url html elements like hr, fieldset, Src constraints for min, max, length, min & max length, number, range regex, ascii, email, datetime, word, printable characters, set, singlevalue, bool, equal Plus many many others (homework for you).
  • 28. Observation... Elements and Constraints are role based This makes extending things easy But you often have to chase through 2-3 levels of modules’s perldoc to work out all available options Here is a more complex example in the registration form...
  • 29. sub register : Path(’register’) : Args(0) : FormConfig { my ( $self, $c ) = @_; unless ( $c->model(’DB’)->get_setting(’registration_open’) ) { $c->stash->{message} = ’Registrations are closed’; $c->detach(’message’); } } sub register_FORM_RENDER { } sub register_FORM_NOT_SUBMITTED { } sub register_FORM_VALID { my ( $self, $c ) = @_; $c->model(’DB’)->create_photographer( username => $c->req->param(’username’), password => $c->req->param(’password’), full_name => $c->req->param(’full_name’), email_addr => $c->req->param(’email_addr’), creation_ip => $c->req->address, ); $c->stash->{message} = ’user created’; $c->detach(’message’); } sub register_FORM_NOT_VALID { my ( $self, $c ) = @_; $c->stash->{error} = ’Submission failed, see comments above’; }
  • 30. config is root/forms/register.yml --- action: /register indicator: submit output_processors: - Indent elements: - type: Fieldset name: register elements: - type: Src content_xml: "<legend>Register to Compete!</legend>" - type: Text name: full_name label: "Full Name:" attributes: id: fullname title: Full Name constraints: - type: Required - type: Text name: email_addr label: "Email:" attributes: id: emailaddr title: Email Address
  • 31. - type: Text name: username label: "Username:" attributes: id: username title: Username constraints: - type: Required - type: Length min: 2 max: 255 validators: - ’+PhotoGame::Validator::UniqueUsername’ - type: Password name: password label: "Password:" attributes: id: password title: Password constraints: - type: Required - type: Length min: 6 max: 255 - type: Equal others: repeat-password - type: Password name: repeat-password label: "Repeat:"
  • 32. - type: Submit name: submit value: Go constraints: - SingleValue
  • 33. The registration form has lots of examples of what can be used. ’Required’ constraing in all cases ’Email’ constraint used on email field ’Min’ and ’Max’ lenfth used on username and password field ’Equal’ to ensure sameness of dual password fields ’Src’ and ’Hr’ used for a bit of formatting Output processor of ’Indent’ makes the HTML look pretty adds cpu, but soothes perfectionist urges :) Custom constraint ’+PhotoGame::Validator::UniqueUsername’ which checks the DB for username uniqueness
  • 34. Calls in to the model to check if the username is already used. Dies with a HTML::FormFu::Excepton object PhotoGame/Validator/UniqueUsername.pm package PhotoGame::Validator::UniqueUsername; use strict; use warnings; use base ’HTML::FormFu::Validator’; # use parent might be better? sub validate_value { my ( $self, $value, $params ) = @_; my $c = $self->form->stash->{context}; if ($c->model(’DB’)->username_taken($value)) { die HTML::FormFu::Exception::Validator->new({ message => ’username taken’, }); } return 1 } 1
  • 35. As you can see its very easy to add/edit/remove form elements. It’s easy enough that junior or non-programmers can get it right. Lots and lots of boring code is gone, which is still good even if you use YAML. Web Designers can whip up form modifications for clients and finalize them, before handing them to developers to tie in to the database (an ORM may avoid that step entirely) Using common type constraints will give you consistency through out your software (instead of email being a different regex in different locations, sometimes with MX look ups) HTML::FormFu may add more CPU usage, depending on how good/bad your coding is.
  • 36. You can do cool AutoCRUD stuff with FormFu and DBIC. A talk for another day. HTML::FormFu::ExtJS exists. Promising to generate Javascript forms for you based on ExtJS.
  • 38. ENDE