The Perl Advent Calendar needs more articles for 2022. Submit your idea today!
=pod

=head1 NAME

Mojolicious::Plugin::ParamExpand - Use objects and data structures in your forms

=head1 SYNOPSIS

  # Mojolicious
  $self->plugin('ParamExpand', %options);

  # Mojolicious::Lite
  plugin 'ParamExpand', %options;

  # In your action
  sub action
  {
      my $self = shift;
      my $order = $self->param('order');
      $order->{address};
      $order->{items}->[0]->{id};
      $order->{items}->[0]->{price};
      # ...
  }

=head1 DESCRIPTION

L<Mojolicious::Plugin::ParamExpand> turns request parameters into nested data
structures using L<CGI::Expand>.

=head1 MOJOLICIOUS VERSION

=head2 Less than 2.52

Due to the old way C<Mojolicious::Controller> handled multi-valued request parameters
versions prior to 2.52 will not work with this plugin. If this is a problem for
you try L<Mojolicious::Plugin::GroupedParams>.

=head2 Greater than 5.57

L<Mojolicious::Controller/param> no longer returns an array.
You must call L<Mojolicious::Controller/every_param>.

=head1 OPTIONS

Options must be specified when loading the plugin.

=head2 separator

  $self->plugin('ParamExpand', separator => ',')

The character used to separate the data structure's hierarchy in the
flattened parameter. Defaults to C<'.'>.

=head2 max_array

  $self->plugin('ParamExpand', max_array => 10)

Maximum number of array elements C<CGI::Expand> will create.
Defaults to C<100>. If a parameter contains more than C<max_array>
elements an exception will be raised.

To force the array into a hash keyed by its indexes set this to C<0>.

=head1 Methods

=head2 param

This is just L<Mojolicious::Controller/param> but, when using C<Mojolicious::Plugin::ParamExpand>, a
request with the parameters

  users.0.name=nameA&users.1.name=nameB&id=123

will return a nested data structure for the param C<'users'>

  @users = $self->param('users');
  $users[0]->{name};
  $users[1]->{name};

Other parameters can be accessed as usual

  $id = $self->param('id');

The flattened parameter name can also be used

  $name0 = $self->param('users.0.name');

=head3 Arguments

C<$name>

The name of the parameter.

=head3 Returns

The value for the given parameter. If applicable it will be an expanded
data structure.

Top level arrays will be returned as arrays B<not> as array references.
This is how C<Mojolicious> behaves. In other words

  users.0=userA&users.1=userB

is equivlent to

  users=userA&users=userB

If this is undesirable you could L<< set C<max_array> to zero|/max_array >>.

=head1 SEE ALSO

L<CGI::Expand>, L<Mojolicious::Plugin::FormFields>, L<Mojolicious::Plugin::GroupedParams>