posted by jwerner on Thursday, January 22, 2015 5:40 PM

The Yii2 framework was released recently - time to push up the sleeves and dig into it!

Introduction

This How To will cover some basic aspects of creating a web application using the Yii2 Framework.

  • Basic setup of a Yii2 application
  • Activating the User module
  • Activating I18N

Installation

Install Composer

curl -s http://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

On Windows, you may download and run Composer-Setup.exe.

  • Install Yii and create an application template:
/var/www> composer global require "fxp/composer-asset-plugin:^1.2.0"
/var/www> composer create-project --prefer-dist yiisoft/yii2-app-basic timetracker
/var/www> cd timetracker

Configuring the Database

  • In your MySQL admin tool (e.g. phpMyAdmin), create a new database named yii2_timetracker
  • For the collation, use utf8_unicode_ci

  • Edit config/db.php:

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2_timetracker',
    'username' => 'root',
    'password' => 'YOUR_PASSWORD',
    // Enable table names prefixes: 
    // 'tablePrefix' => 'tbl_',
    'charset' => 'utf8',
];

Activating the User Module

dektrium's yii2-user module covers a lot of functionality regarding users management, e.g.

  • User registration
  • Login/Logout
  • Profile maintenance
  • Management etc.

Installation

  • In a console, run:

    composer require dektrium/yii2-user "0.9.*@dev"

  • Edit config/web.php. Addthe user module and de-activate the user component:

'components' => [
    /*
    'user' => [
        ...
    ], */
    ....
'modules' => [
    'user' => [
        'class' => 'dektrium\user\Module',
    ],
],

The yii2-user module provides some migration scripts to initialize user related tables in the database.

  • In a console, run:

    yii migrate/up --migrationPath=@vendor/dektrium/yii2-user/migrations

This creates the user, profile, social_account and token tables.

Registering a First User

Register yourself as a first user.

  • In a browser, open http://localhost/timetracker/index.php?r=user/registration/register .
  • Enter your username, email and password, then submit the form

In the examples below, we use theadminuser as an example username.

Check the folder timetracker/runtime/mail/ for a new email file (*.eml); open the confirmation link being in the email in a browser.

The link looks something like this::

http://localhost/timetracker/web/index.php?r=user%2Fregistration%2Fconfirm&id=1&code=...


Changing Menu Links

Now some links regarding user functionality in the page template need to be changed, e.g.

  • Login
  • Logout
  • Change user settings

  • Edit views/layout/main.php:

// Setup menu items
$menuItems = [];
$menuItems[] = ['label' => 'Home', 'url' => ['/site/index']];
if(!Yii::$app->user->isGuest and in_array(Yii::$app->user->identity->username, Yii::$app->params['userAdmins'])) {
    $menuItems[] = ['label' => 'Users Admin', 'url' => ['/user/admin']];
}
$menuItems[] = ['label' => 'About', 'url' => ['/site/about']];
$menuItems[] = ['label' => 'Contact', 'url' => ['/site/contact']];
if (Yii::$app->user->isGuest) {
    $menuItems[] = ['label' => 'Signup', 'url' => ['/user/registration/register']];
    $menuItems[] = ['label' => 'Login', 'url' => ['/user/security/login']];
} else {
    $menuItems[] = ['label' => 'Settings', 'url' => ['/user/settings']];
    $menuItems[] = ['label' => 'Logout (' . Yii::$app->user->identity->username . ')', 'url' => ['/user/security/logout'], 'linkOptions' => ['data-method' => 'post']];
}
 
echo Nav::widget([
    'options' => ['class' => 'navbar-nav navbar-right'],
    // Change:
    'items' => $menuItems,
]);

Adding an Admin User

The yii2-user module provides an administration view to manage users.

In order to access it, you need to configure a list of usernames who are allowed to use the view.

  • Edit config/params.php:
return [
    ...
    // Users Module / Admin usernames
    'userAdmins' => ['theadminuser'],
];
  • Edit config/web.php:
'modules' => [
    'user' => [
        'class' => 'dektrium\user\Module',
        // Admin users: see config/params.php
        'admins' => $params['userAdmins'],
    ],
],

You may now open the user administration screen using the URL

http://localhost/timetracker/web/index.php?r=user/admin


Activating I18N

If you want to display the application using different languages, you may switch on Internationalization (I18N).

Edit config/web.php:

'language' => 'de-DE',
// ...
'components' =>
    // ...
    'i18n' => [
        'translations' => [
            '*' => [
                'class' => 'yii\i18n\PhpMessageSource',
                'basePath' => '@app/messages',
                'sourceLanguage' => 'en-US',
                'fileMap' => [
                    'app' => 'app.php',
                    'app/error' => 'error.php',
                ],
            ],
        ],
    ],
  • Create the messages directory:

    /var/www/timetracker> mkdir messages

  • Create the messages config file:

    /var/www/timetracker> yii message/config messages/config.php

  • Edit the config file messages/config.php:

return [
    'sourcePath' => __DIR__ . DIRECTORY_SEPARATOR . '..',
    'messagePath' => __DIR__,
    'languages' => ['de'],
    'translator' => 'Yii::t',
    'sort' => false,
    'removeUnused' => false,
    'only' => ['*.php'],
    'except' => [
        '.svn',
        '.git',
        '.gitignore',
        '.gitkeep',
        '.hgignore',
        '.hgkeep',
        '/messages',
        '/vendor',
    ],
    'format' => 'php',
    'overwrite' => true,
    // 'catalog' => 'messages',
    'ignoreCategories' => [],
];
  • To get phrases translated, you may write:
<?php
echo Yii::t('category', 'Hello World');
?>
  • Extract messages:

    /var/www/timetracker> yii message/extract messages/config.php

Using the example above, this will create a file category.php in messages/de:

<?php
return [
  'Hello World' => '',
];
  • Insert your translation in the assignments on the right sides:
  'Hello World' => 'Hallo Welt',

Activating the Gii Code Generation

Edit config/web.php:

<?php
return [
    'bootstrap' => ['log','gii'],
    'modules' => [
        'gii' => [
            'class' => 'yii\gii\Module',
            'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*'],
        ],
        // ...
    ],
    // ...
];

Then open the Gii pages through the this URL:

    http://localhost/timetracker/index.php?r=gii

Date Formatting

Install Krajee's Date Control

  • In a console, run:
composer require kartik-v/yii2-datecontrol "dev-master"
composer require kartik-v/yii2-widget-datepicker "@dev"
  • Edit config/web.php:
<?php
// ...
'modules' => [
    // ...
    'datecontrol' =>  [
        'class' => '\kartik\datecontrol\Module'
    ],

Configure Date Formats

  • Edit config/params.php:
<?php
use kartik\datecontrol\Module;
 
return [
    // ....
    // format settings for saving each date attribute (PHP format example)
    'dateControlSave' => [
        Module::FORMAT_DATE => 'php:Y-m-d', // saves as MySQL date
        Module::FORMAT_TIME => 'php:H:i:s',
        Module::FORMAT_DATETIME => 'php:Y-m-d H:i:s',
    ],
];

Using the Date Picker

  • In a form view, change a textInput field to a DateControl widget:
<?php
use kartik\datecontrol\DateControl;
?>
 
<?= $form->field($model, 'mydate')->widget(DateControl::classname(), [
    'type'=>DateControl::FORMAT_DATE,
    'ajaxConversion'=>false,
    // Display in locale's date format:
    'displayFormat' => \yii::$app->formatter->dateFormat,
    'widgetOptions' => [
        'pluginOptions' => [
            'autoclose' => true
        ]
    ]
]); ?>
  • in a DetaiilView, get a formatted date for the eventDate attribute like this:
<?= DetailView::widget([
    'model' => $model,
    'attributes' => [
        ...
        [
            'attribute' => 'eventDate',
            'value' => Yii::$app->formatter->asDate($model->eventDate),
        ],
        ...
    ],
]) ?>
  • In a GridView, get the formatted date like this:
<?= GridView::widget([
        ...
        'columns' => [
            ...
            [
                'attribute' => 'eventDate',
                'value' => function ($model, $key, $index, $column) { return Yii::$app->formatter->asDate($model->eventDate); },
            ],
            ...

Installing Bootswatch Themes

To change the design / style of the app quickly, you can use Bootswatch themes. There is a Yii2 extension available to activate a theme in the Yii app.

Install the yii2-bootswatch-asset Extension

  • In a console window, run:
composer require --prefer-dist raoul2000/yii2-bootswatch-asset "*"
  • Edit the application parameters file config/params.php to define your theme to be used:
<?php
return [
    // ...
    'theme' => 'cerulean', 
    // or any other directory name in vendor/thomaspark/bootswatch
];
  • Switch on the theme. Edit assets/AppAsset.php:
<?php
class AppAsset extends AssetBundle
{
    public $depends = [
        'yii\web\YiiAsset',
        // let's add the BootswatchAsset here
        'raoul2000\bootswatch\BootswatchAsset',
    ];
}
?>

Select the theme name you want to use. A good place might be in the main layout.

  • Edit views/layouts/main.php:
// Select bootswatch theme, as per app paramms
raoul2000\bootswatch\BootswatchAsset::$theme = Yii::$app->params['theme'];
AppAsset::register($this);

Some Usefull Snippets

  • To extend the nav bar to the full page width, edit views/layouts/main.php:
<?php
    NavBar::begin([
        'brandLabel' => 'My Company',
        'brandUrl' => Yii::$app->homeUrl,
        // Make nav bar extend to ful width:
        'innerContainerOptions'  => [
            'class' => 'container-fluid',
        ],
        'options' => [
            'class' => 'navbar-inverse navbar-fixed-top',
        ],
    ]);
    echo Nav::widget([
    ...
  • DropDown list (e.g. for foreign keys):
<?= $form->field($model, 'projectId')->dropDownList(
    ArrayHelper::map(
        Project::find()->all(), 
        'id', 'title'),
    array('prompt'=>Yii::t('app', '(Select)'))) ?>
  • Masking text input fields:
<?php
use yii\widgets\MaskedInput;
?>
<?= $form->field($model, 'myTime')->widget(MaskedInput::classname(), ['mask' => '99:99']) ?>
  • Setting focus on the first field in a form:
<?php 
$this->registerJs(
    '$("document").ready(function(){ $("form select, input:text, form textarea").first().focus(); });'
); ?>

Comments

No comments


Please enter the letters as they are shown in the image above.
Letters are not case-sensitive.

Add comment

Change Log

Created OnJan 22, 2015 5:40:55 PM CET
Created ByJoachim Werner (jwerner)
Updated OnJan 2, 2017 2:14:56 PM CET
Updated ByJoachim Werner (jwerner)