How to stop repeating views


I’ve seen several projects with a common problem in organizing Views in their MVC structure. The problem is that they end up with many Views slightly different from each other.
For instance, they usually need some grid lists of a single data set with various combination of data columns to display. There are also two common approaches for addressing this problem: creating a single but highly complex view file or creating several simple view files.

Is there a better approach out there ? Any best practices ?


If the problem is about rendering different set of columns then better approach is to send grid columns to single view while rendering. Problem is all about data and not static html then it’s fine to send data via controller/model.

Sending data usually leads to complex conditions in views.

Please allow me to elaborate using another example. Please, take a look at the form below.

<?php $form = ActiveForm::begin() ?>

<?= $form->field($model, 'A')->textInput() ?>

<?= $form->field($model, 'B')->textInput() ?>


if($model->scenario == 'scenario one'){

	echo $form->field($model, 'C1')->textInput();

}elseif($model->scenario == 'scenario two'){

	echo $form->field($model, 'C2')->textArea();


	echo $form->field($model, 'C3')->fileInput();



<?php ActiveForm::end(); ?>

Clearly, the form is already going down the rabbit hole. Now, imagine we would need to involve more parameters in the conditions with more complex views. It quickly turned to a nightmare which was neither readable nor maintainable. Using multiple forms wouldn’t make any better.
Further, if we render that form as part of other views in many parts of an application, it will become extremely difficult to develop and maintain.
It seems like object oriented design ends when code reaches HTML.
Could it be a better solution to apply Builder design pattern for creating a view builder in such situations?

I had this rather complex (or one may even say convoluted) conditional form. Started of with if/else as above, but finally arrived at breaking them down into two sections. All conditions were evaluated upfront and Boolean variables set first. The 2nd section used them to display the fields.

$vsomerole = (integer) Yii::$app->session->get('somesessionvariable');
$df['cond1'] = false;
$df['emailcond'] = false;
switch(Yii::$app->controller->action->id) {
    case 'createperson':
        $df['cond1'] = true;
    case 'updateperson':
        $df['somerole'] = false;
        $df['private'] = false;
        if ($vsomerole == 900) $df['cond1'] = true;
    case 'create':
        $df['emailcond'] = true;
    case 'update':
        $df['private'] = true;
        $df['emailcond'] = true;
        if ($vsomerole >= 9200) {
            $df['somerole'] = true;
        if ($vsomerole <= 1700) {
            $df['somerole'] = false;

    if ($df['private'])
        echo $form->field($model, 'private_sw')->dropDownList(ArrayHelper::map(Sometable::find()->where(['somecol' => 5])->orderBy(['acolumn'=>SORT_ASC, 'rvalue'=>SORT_ASC])->all(), 'col3, 'col7'),[ 'prompt' => '', 'style' => 'width: auto;'])



From here one can convert the switch case statements to become a set of class/functions which will make this cleaner and object oriented. I was happy with this level of abstraction so left it here.