More seriously, Yii has a good doc, an easy-to-learn API and has some interesting concepts, like we will see further in this article.
Installation
Grab the last release and uncompress it. I suggest that you put it at the same level than your webserver’s root (but not in it, for the sake of the security)If you’re under Unix, you may find fine to create a symlink like this, so the updates will be easy, even if you have a lot of Yii apps.
$ ln -s yii-1.1.3.r2247 yii-stable
Then move into your webroot and type:$ php yii-1.1.3.r2247/framework/yiic webapp demo
You will be prompted to create a new app called demo
. Answer Yes
and the
yiic
command-line utility will create a whole directory structure for you.Opposite to symfony, a yii project contains only one application, so there’s only one webcontroller,
index.php
. This file essentially find the framework.The interesting parts are located in the
protected
folder. Note that Yii has
security in mind and has add a .htaccess
file in it, so the protected
folder
can not be opened from the webserver.Assuming your webserver is correctly configured to serve files from your webroot, you should view the default page when browsing to
http://localhost/demo/
.The Yii “form” component
Unlike to symfony (and django) forms, Yii doesn’t have a dedicated component to handle forms. Every model class can be a form, from the business logic point of view. So the validation is not done in a separate class, and has not to be done twice, like sometimes you are lead to with symfony or django. This is the reason why django introduces in the 1.2 release the concept of validator, which can be used in a model and in a form.The
CForm
class only is the glue between a view and the model. Yii is probably
more MVC than symfony/django here, because we don’t create a class where we mix
the validation and the displaying of the widgets.For more details, see the form builder documentation.
Create a form wizard
A nice functionnality I’ve recently came into is the ability of Yii to easily creates form wizards.All model’s classes in Yii can be used in different contexts, called scenarii. A scenario will trigger a dedicated validation rule. For exemple, a LoginForm can be used on registration or when login:
- In the first case, we require the name and the 2 passwords fields to be filled in, and the 2 passwords to match.
- In the second case, we require the name and the password fields to be filled in, and we add an option to allow the app to remember the user.
This functionality can be used to create wizards.
Create in
protected/models/
a file called WizardForm.php
. Paste the code
below in it:<?php
class WizardForm extends CFormModel
{
public $step ;
public $name ;
public $body ;
public $pub_date ;
public $authors ;
public static function getPubDates() {
return array('' => '----',
'-1' => 'yesterday',
'0' => 'today',
'1' => 'tomorrow') ;
}
public static function getAuthors() {
return array('' => '----',
'me' => 'Me',
'myself' => 'Myself') ;
}
public function preview() {
$pub_dates = $this->getPubDates() ;
$authors = $this->getAuthors() ;
return strtr('<h2>%name%</h2><div>%body%</div><hr/><span>Published %pub_date% by %authors%</span>',
array('%name%' => $this->name,
'%body%' => nl2br($this->body),
'%pub_date%' => $pub_dates[$this->pub_date],
'%authors%' => $authors[$this->authors])) ;
}
public function rules() {
return array(
// name, email, subject and body are required
array('step, name, body', 'required', 'on' => 'step1'),
array('step, name, body, pub_date, authors', 'required', 'on' => 'step2'),
array('step, name, body, pub_date, authors', 'required', 'on' => 'step3'),
) ;
}
}
?>
This model defines 3 rules, which will be our wizard steps: In the first step,
we display only the name
and body
fields. The step
field is hidden and
contains … the current step!
On submit, if the validation passes, we display the second step, where the
pub_date
and the authors
are shown. The name
and body
fields are hidden
and filled with the values of the previous step.In the
DefaultController
file, and replaces the code of the actionIndex
method with the one below:<?php
public function actionIndex() {
// get the step. If a previous step has been posted, the step is
// found in this previous form's fields. Otherwise we set it to
// 1
$step = isset($_POST['WizardForm']) && isset($_POST['WizardForm']['step']) ?
$_POST['WizardForm']['step'] : 1 ;
$model = new WizardForm('step' . $step) ;
$form = new CForm('application.views.site.wizard_step' . $step,
$model) ;
// validate the previous step
if(isset($_POST['WizardForm'])) {
$model->attributes=$_POST['WizardForm'] ;
if ($form->validate()) {
// The previous step has validated
if ($step < 3) {
// build the current step form if we're
// not at the last step
$step++ ;
$model = new WizardForm('step' . $step) ;
$model->attributes=$_POST['WizardForm'] ;
$form = new CForm('application.views.site.wizard_step' . $step,
$model) ;
}
}
}
$preview = $step == 3 ? $model->preview() : '' ;
$this->render('wizard', array('form' => $form,
'preview' => $preview,
'step' => $step)) ;
}
This action uses a template called wizard.php
and located in
views/site/wizard.php
. So create this file and add the following content:<h1>Step <?php echo $step ; ?></h1>
<div class="form">
<?php echo $form ; ?>
</div><!-- form -->
<?php if ($preview) : ?>
<?php echo $preview ; ?>
<?php endif;
The view is dead-simple because the actual content is in the form “templates”.
For each step, we have a dedicated one:// views.site.wizard_step1.php
<?php return array(
'elements' => array(
'step' => array(
'type' => 'hidden',
'value' => 1,
),
'name' => array(
'type' =>'text'
),
'body' => array(
'type' => 'textarea'
)
),
'buttons' => array(
'submit' => array('type' => 'submit',
'value' => Yii::t('default', 'Step2'))
)
) ;
// views.site.wizard_step2.php
<?php return array(
'elements' => array(
'step' => array(
'type' => 'hidden',
'value' => 2,
),
'name' => array(
'type' =>'hidden'
),
'body' => array(
'type' => 'hidden'
),
'pub_date' => array(
'type' => 'dropdownlist',
'items' => WizardForm::getPubDates()
),
'authors' => array(
'type' => 'dropdownlist',
'items' => WizardForm::getAuthors()
)
),
'buttons' => array(
'submit' => array('type' => 'submit',
'value' => Yii::t('default', 'Publish'))
)
) ;
// views.site.wizard_step3.php
<?php return array(
'elements' => array(
'step' => array(
'type' => 'hidden',
'value' => 2,
),
'name' => array(
'type' =>'hidden'
),
'body' => array(
'type' => 'hidden'
),
'pub_date' => array(
'type' => 'hidden',
#'values' => array('yesterday', 'today', 'tomorrow')
),
'authors' => array(
'type' => 'hidden'
)
)
) ;
And that’s all ! You can see your wizard working in your browser.The code is available on
No comments:
Post a Comment