Catalyst-Controller-HTML-FormFu
view release on metacpan or search on metacpan
lib/Catalyst/Controller/HTML/FormFu.pm view on Meta::CPAN
package Catalyst::Controller::HTML::FormFu;
# ABSTRACT: Catalyst integration for HTML::FormFu
use strict;
our $VERSION = '2.04'; # VERSION
our $AUTHORITY = 'cpan:NIGELM'; # AUTHORITY
use Moose;
use HTML::FormFu;
use Config::Any;
use Regexp::Assemble;
use Scalar::Util qw/ isweak weaken /;
use Carp qw/ croak /;
use namespace::autoclean;
# see https://rt.cpan.org/Ticket/Display.html?id=55780
BEGIN {
extends 'Catalyst::Controller';
}
with 'Catalyst::Component::InstancePerContext';
has _html_formfu_config => ( is => 'rw' );
sub build_per_context_instance {
my ( $self, $c ) = @_;
return $self unless ( ref $c );
$self->{c} = $c;
weaken( $self->{c} )
if !isweak( $self->{c} );
return $self;
}
sub BUILD { }
after BUILD => sub {
my ($self) = @_;
my $app = $self->_app;
my $self_config = $self->config->{'Controller::HTML::FormFu'} || {};
my $parent_config = $app->config->{'Controller::HTML::FormFu'} || {};
my %defaults = (
request_token_enable => 0,
request_token_field_name => '_token',
request_token_session_key => '__token',
request_token_expiration_time => 3600,
form_method => 'form',
form_stash => 'form',
form_attr => 'Form',
config_attr => 'FormConfig',
method_attr => 'FormMethod',
form_action => "Catalyst::Controller::HTML::FormFu::Action::Form",
config_action => "Catalyst::Controller::HTML::FormFu::Action::FormConfig",
method_action => "Catalyst::Controller::HTML::FormFu::Action::FormMethod",
multiform_method => 'multiform',
multiform_stash => 'multiform',
multiform_attr => 'MultiForm',
multiform_config_attr => 'MultiFormConfig',
multiform_method_attr => 'MultiFormMethod',
multiform_action => "Catalyst::Controller::HTML::FormFu::Action::MultiForm",
multiform_config_action => "Catalyst::Controller::HTML::FormFu::Action::MultiFormConfig",
multiform_method_action => "Catalyst::Controller::HTML::FormFu::Action::MultiFormMethod",
context_stash => 'context',
model_stash => {},
constructor => {},
multiform_constructor => {},
config_callback => 1,
);
my %args = ( %defaults, %$parent_config, %$self_config );
my $local_path = $app->path_to( 'root', 'formfu' );
if ( !exists $args{constructor}{tt_args}
|| !exists $args{constructor}{tt_args}{INCLUDE_PATH} && -d $local_path ) {
$args{constructor}{tt_args}{INCLUDE_PATH} = [$local_path];
}
$args{constructor}{query_type} ||= 'Catalyst';
if ( !exists $args{constructor}{config_file_path} ) {
$args{constructor}{config_file_path} = $app->path_to( 'root', 'forms' );
lib/Catalyst/Controller/HTML/FormFu.pm view on Meta::CPAN
if ( $config->{request_token_enable} ) {
$form->plugins(
{ type => 'RequestToken',
context => $config->{context_stash},
field_name => $config->{request_token_field_name},
session_key => $config->{request_token_session_key},
expiration_time => $config->{request_token_expiration_time}
}
);
}
return $form;
}
sub _multiform {
my $self = shift;
require HTML::FormFu::MultiForm;
my $multi = HTML::FormFu::MultiForm->new(
{ %{ $self->_html_formfu_config->{constructor} },
%{ $self->_html_formfu_config->{multiform_constructor} },
( @_ ? %{ $_[0] } : () ),
}
);
$self->_common_construction($multi);
return $multi;
}
sub _common_construction {
my ( $self, $form ) = @_;
croak "form or multi arg required" if !defined $form;
$form->query( $self->{c}->request );
my $config = $self->_html_formfu_config;
if ( $config->{config_callback} ) {
$form->config_callback(
{ plain_value => sub {
return if !defined $_;
s{__uri_for\((.+?)\)__}
{ $self->{c}->uri_for( split( '\s*,\s*', $1 ) ) }eg
if /__uri_for\(/;
s{__path_to\(\s*(.+?)\s*\)__}
{ $self->{c}->path_to( split( '\s*,\s*', $1 ) ) }eg
if /__path_to\(/;
s{__config\((.+?)\)__}
{ $self->{c}->config->{$1} }eg
if /__config\(/;
}
}
);
weaken( $self->{c} )
if !isweak( $self->{c} );
}
if ( $config->{languages_from_context} ) {
$form->languages( $self->{c}->languages );
}
if ( $config->{localize_from_context} ) {
$form->add_localize_object( $self->{c} );
}
if ( $config->{default_action_use_name} ) {
my $action = $self->{c}->uri_for( $self->{c}->{action}->name );
$self->{c}->log->debug("FormFu - Setting default action by name: $action")
if $self->{c}->debug;
$form->action($action);
}
elsif ( $config->{default_action_use_path} ) {
my $action = $self->{c}->{request}->base . $self->{c}->{request}->path;
$self->{c}->log->debug("FormFu - Setting default action by path: $action")
if $self->{c}->debug;
$form->action($action);
}
my $context_stash = $config->{context_stash};
$form->stash->{$context_stash} = $self->{c};
weaken( $form->stash->{$context_stash} );
my $model_stash = $config->{model_stash};
for my $model ( keys %$model_stash ) {
$form->stash->{$model} = $self->{c}->model( $model_stash->{$model} );
}
return;
}
sub create_action {
my $self = shift;
my %args = @_;
my $config = $self->_html_formfu_config;
for my $type (
qw/
form
config
method
multiform
multiform_config
multiform_method /
) {
my $attr = $config->{"${type}_attr"};
if ( exists $args{attributes}{$attr} ) {
$args{_attr_params} = delete $args{attributes}{$attr};
}
elsif ( exists $args{attributes}{"$attr()"} ) {
$args{_attr_params} = delete $args{attributes}{"$attr()"};
}
else {
next;
}
push @{ $args{attributes}{ActionClass} }, $config->{"${type}_action"};
last;
}
$self->SUPER::create_action(%args);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Catalyst::Controller::HTML::FormFu - Catalyst integration for HTML::FormFu
=head1 VERSION
version 2.04
lib/Catalyst/Controller/HTML/FormFu.pm view on Meta::CPAN
The form C<< __uri_for(URI, PATH, PARTS)__ >> is also supported, which is
equivalent to C<< $c->uri_for( 'URI', \@ARGS ) >>. At this time, there is no
way to pass query values equivalent to C<< $c->uri_for( 'URI', \@ARGS,
\%QUERY_VALUES ) >>.
The second codeword that is being replaced is C<__path_to( @DIRS )__>. Any
instance is replaced with the result of passing the C<DIRS> arguments to
L<Catalyst/path_to>. Don't use qoutationmarks as they would become part of the
path.
Default value: 1
=head2 default_action_use_name
If set to a true value the action for the form will be set to the currently
called action name.
Default value: C<false>.
=head2 default_action_use_path
If set to a true value the action for the form will be set to the currently
called action path. The action path includes concurrent to action name
additioal parameters which were code inside the path.
Default value: C<false>.
Example:
action: /foo/bar
called uri contains: /foo/bar/1
# default_action_use_name => 1 leads to:
$form->action = /foo/bar
# default_action_use_path => 1 leads to:
$form->action = /foo/bar/1
=head2 model_stash
Arguments: \%stash_keys_to_model_names
Used to place Catalyst models on the form stash.
If it's being used to make a L<DBIx::Class> schema available for
L<HTML::FormFu::Model::DBIC/options_from_model>, for C<Select> and other
Group-type elements - then the hash-key must be C<schema>. For example, if your
schema model class is C<MyApp::Model::MySchema>, you would set C<model_stash>
like so:
<Controller::HTML::FormFu>
<model_stash>
schema MySchema
</model_stash>
</Controller::HTML::FormFu>
=head2 context_stash
To allow your form validation packages, etc, access to the catalyst context, a
weakened reference of the context is copied into the form's stash.
$form->stash->{context};
This setting allows you to change the key name used in the form stash.
Default value: C<context>
=head2 languages_from_context
If you're using a L10N / I18N plugin such as L<Catalyst::Plugin::I18N> which
provides a C<languages> method that returns a list of valid languages to use
for the currect request - and you want to use formfu's built-in I18N packages,
then setting L</languages_from_context>
=head2 localize_from_context
If you're using a L10N / I18N plugin such as L<Catalyst::Plugin::I18N> which
provides it's own C<localize> method, you can set L<localize_from_context> to
use that method for formfu's localization.
=head2 request_token_enable
If true, adds an instance of L<HTML::FormFu::Plugin::RequestToken> to every
form, to stop accidental double-submissions of data and to prevent CSRF
attacks.
=head2 request_token_field_name
Defaults to C<_token>.
=head2 request_token_session_key
Defaults to C<__token>.
=head2 request_token_expiration_time
Defaults to C<3600>.
=head1 DISCONTINUED CONFIG SETTINGS
=head2 config_file_ext
Support for this has now been removed. Config files are now searched for, with
any file extension supported by Config::Any.
=head2 config_file_path
Support for this has now been removed. Use C<< {constructor}{config_file_path}
>> instead.
=head1 CAVEATS
When using the C<Form> action attribute to create an empty form, you must call
L<< $form->process|HTML::FormFu/process >> after populating the form. However,
you don't need to pass any arguments to C<process>, as the Catalyst request
object will have automatically been set in L<< $form->query|HTML::FormFu/query
>>.
When using the C<FormConfig> and C<FormMethod> action attributes, if you make
any modifications to the form, such as adding or changing it's elements, you
( run in 1.123 second using v1.01-cache-2.11-cpan-39bf76dae61 )