Plugin Controller actions for entering data and redisplaying form or redirecting I'm getting confused with how to submit forms to a plugin controller as shown briefly in the docs.

I'm making a multi-page form, which saves the data on each page to the session, sending it elsewhere at the end of the process. None of the data is related to things (Entries, etc) in Craft.

But I don't understand how to do the:


Display form
POST form
Either:


Validation passes, so save the data and redirect to the next page
Or, fail validation and display the same form again



Let's say the first page asks for firstname and surname, and the second for date of birth. I have a model per form page, for validation, so there's plugins/myform/models/myForm_NameModel.php:

&lt;?php
namespace Craft;

class MyForm_NameModel extends BaseModel
{
    protected function defineAttributes()
    {
        return array(
            'firstname' =&gt; array(AttributeType::Name, 'maxLength' =&gt; 100),
            'surname' =&gt; array(AttributeType::Name, 'maxLength' =&gt; 100),
        );
    }
}


And I'll have a similar model for the form on the date of birth page.

Then I have plugins/myform/controllers/myForm_FormController.php

&lt;?php
namespace Craft;

class MyForm_FormController extends BaseController
{
    protected $allowAnonymous = true;

    // Display name form.
    public function actionName()
    {
        $this-&gt;renderTemplate('myForm/forms/name');
    }

    public function actionSaveName()
    {
        $this-&gt;requirePostRequest();

        $post = craft()-&gt;request-&gt;getPost();
        $nameModel = MyForm_NameModel::populateModel($post);

        if ($nameModel-&gt;validate()) {
            // TODO: Store in session.
            $this-&gt;redirectToPostedUrl();
        }
        else
        {
            craft()-&gt;userSession-&gt;setError('Error!');
            craft()-&gt;urlManager-&gt;setRouteVariables(array(
                'nameModel' =&gt; $nameModel
            ));
        }
    }

    // Display date of birth form.
    public function actionDob()
    {
        $this-&gt;renderTemplate('myForm/forms/dob');
    }
}


And in plugins/myform/templates/forms/name.html:

&lt;form method="post" action="" accept-charset="UTF-8"&gt;
    {{ getCsrfInput() }}
    &lt;input type="hidden" name="action" value="myForm/form/name"&gt;
    &lt;input type="hidden" name="redirect" value="myForm/form/dob"&gt;

    &lt;p&gt;First name: &lt;input type="text" name="firstname" value="{% if nameModel is defined %}{{ nameModel.firstname }}{% endif %}"&gt;&lt;/p&gt;
    &lt;p&gt;Surname: &lt;input type="text" name="surname" value="{% if nameModel is defined %}{{ nameModel.surname }}{% endif %}"&gt;&lt;/p&gt;

    &lt;input type="submit" value="Submit"&gt;
&lt;/form&gt;


I'm missing something at the moment because all I get is the name form, and submitting it simply refreshes the page; no errors, no submitted values displayed. I think I'm confused by the action and redirect in the form template, and exactly what the controller actions should be doing.

I'm also not sure if using AttributeType::foo is correct when defining these models, seeing as they're not things that will be saved in the database?
I have something working, although I'm not sure it's the "correct" way of doing this.

I've got rid of the actionSaveName() method and my actionName() method in the Controller is now like this:

public function actionName()
{   
    $templateVars = array();

    if (craft()-&gt;request-&gt;isPostRequest())
    {
        // The form was submitted.
        $post = craft()-&gt;request-&gt;getPost();
        $nameModel = MyForm_NameModel::populateModel($post);

        if ($nameModel-&gt;validate()) {
            // Successfully posted the name.
            // TODO: Store in session.
            $this-&gt;redirectToPostedUrl();
        }
        else
        {
            // Something was wrong with the submitted names.
            $templateVars['errors'] = $nameModel-&gt;getErrors();
            $templateVars['nameModel'] = $nameModel;
        }
    }

    // Either the first time viewing the form, or there were errors.
    $this-&gt;renderTemplate('myForm/forms/dob', $templateVars);
}


And then plugins/myform/templates/forms/name.html is like this:

&lt;form method="post" action="" accept-charset="UTF-8"&gt;
    {{ getCsrfInput() }}
    &lt;input type="hidden" name="action" value="myForm/form/name"&gt;
    &lt;input type="hidden" name="redirect" value="{{ actionUrl('myForm/form/dob') }}"&gt;

    &lt;!-- Just a quick example of error output. ---&gt;
    {% if errors is defined %}
        {% if errors.firstname is defined %}
            {{ errors.firstname[0] }}
        {% endif %}
        {% if errors.surname is defined %}
            {{ errors.surname[0] }}
        {% endif %}
    {% endif %}

    &lt;p&gt;First name: &lt;input type="text" name="firstname" value="{% if nameModel is defined %}{{ nameModel.firstname }}{% endif %}"&gt;&lt;/p&gt;
    &lt;p&gt;Surname: &lt;input type="text" name="surname" value="{% if nameModel is defined %}{{ nameModel.surname }}{% endif %}"&gt;&lt;/p&gt;

    &lt;input type="submit" value="Submit"&gt;
&lt;/form&gt;


This seems to work fine but feels wrong in a few little ways:


The hidden action input is ignored; I can put anything in that and nothing changes; I really don't understand how that is supposed to be used.
If the submission is successful the URL redirected to is like /index.php?p=actions/myForm/form/dob rather than /actions/myForm/dob.
Mainly, that it feels quite different from the description in http://buildwithcraft.com/docs/plugins/controllers .