Yii Framework Forum: Views as objects - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

Views as objects

#1 User is offline   phpnode 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 141
  • Joined: 18-April 11

Posted 23 March 2012 - 08:19 AM

In the current system, views are directly bound to the controller, so quite often you end up with views like this.
<?php
/*
 * User view file
 * @var User $user
 * @var CController $this
 */
?>
<h1><?php echo CHtml::link(CHtml::encode($user->name),array("/user/view", "id" => $user->id))); ?></h1>
<p>Some Text</p>
<?php
if ($user->status == "active") {
    echo "This user is active";
    if ($someOtherCondition) {
        // do something else
    }
}
else {
    echo "This user is not active";
}
?>
<br />
<?php
    echo CHtml::link("Some Label", "#fish");
    echo "Current Controller ID: ".$this->getId();
    $this->widget("myCustomWidget", array("foo" => "bar"));
?>


I think it would be useful to introduce a specialized View class so that this kind of logic, which relates only to one or two specific views can be encapsulated outside of the template itself. This makes it easier for designers to work with views, and for views to be localized. The base view class could also provide access to the current CHtml methods, which would make it easy to replace CHtml with your own class, solving a lot of the issues regarding supporting different CSS frameworks. Importantly, it also makes it much easier to test your views without relying on selenium.

<?php
/**
 * User view helper
 */
class UserView extends CView {
    public $someOtherCondition = true;
    public function displayUserStatus($user) {
        if ($user->status == "active") {
            return "This user is active".($this->someOtherCondition ? $this->doSomethingElse() : "");
        }
        else {
            return "This user is inactive";
        }
    }
    public function doSomethingElse() {
        return "foo";
    }
    public function userLink($user) {
        return $this->link($this->encode($user->name),array("/user/view", "id" => $user->id));
    }
}
?>

<?php
/**
 * User view file
 * @var User $user
 * @var UserView $this
 */
?>
<h1><?php echo $this->displayUserLink($user); ?></h1>
<p>Some Text</p>
<?php
echo $this->displayUserStatus($user);
?>
<br />
<?php
    echo $this->link("Some Label", "#fish");
    echo "Current Controller ID: ".$this->controller->getId(); // still provide access to the controller if required
    $this->widget("myCustomWidget", array("foo" => "bar")); // views can render widgets just like controllers do now
?>

0

#2 User is offline   Fesor 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 02-March 09
  • Location:Belarus, Minsk

Posted 24 March 2012 - 04:21 AM

There are models for things like that.
Bend Before The Ways Of Heavy Metal! © Six-String Samurai
0

#3 User is offline   phpnode 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 141
  • Joined: 18-April 11

Posted 24 March 2012 - 05:04 AM

Presentation logic does not belong in the model
0

#4 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 24 March 2012 - 05:30 AM

It belongs in the controller.
Or, in a widget.
Or even a helper.

Why can't $this->displayUserStatus($user); be a controller function?
I would put it in a helper/component, or - if only used once or twice - in the controller.

I like how flexible it is currently.

Turning the view into an object is unnecessary.
It would require more memory. For what?
"Less noise - more signal"
1

#5 User is offline   Da:Sourcerer 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,222
  • Joined: 30-March 11
  • Location:Berlin, Germany

Posted 24 March 2012 - 08:51 AM

I think phpnode is trying to propagate a MVP or MVA paradigma for Yii 2 :rolleyes:

It would have its merrits. But it were no longer MVC.
programmer /ˈprəʊgramə/, noun: a device that converts ►coffee into ►code
0

#6 User is offline   phpnode 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 141
  • Joined: 18-April 11

Posted 24 March 2012 - 01:48 PM

View Postjacmoe, on 24 March 2012 - 05:30 AM, said:

It belongs in the controller.
Or, in a widget.
Or even a helper.

Why can't $this->displayUserStatus($user); be a controller function?



Because that breaks the separation of concerns: models deal with manipulating data, views deal with displaying data, controllers just decide what model to display with which view. The controller shouldn't affect the presentation. Besides it's perfectly reasonable to use the same view with different controllers, so which controller should displayUserStatus() go in? The only real candidate is a helper class, but why not make that helper class part of the view?

I'm not saying we drop MVC at all, I'm saying that we should flesh out the V so that it's more in line with the original definition of MVC, with the view controlling the presentation rather than just being a template. This allows views to be extended and reused more easily, at the moment Yii is more like MTC - model template controller. Creating a custom view class would be totally optional, it would use the CView base class by default, which would leave things almost exactly the same as they are now, the only difference being that $this refers to the view, rather than the controller, and you no longer need static method calls to CHtml for generating text boxes and links etc.
0

#7 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 24 March 2012 - 01:59 PM

This subject has been discussed here already.
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#8 User is offline   Jaggi 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 90
  • Joined: 05-September 11

Posted 24 March 2012 - 05:49 PM

I agree this can be handled in the controller. Doing this would just complicate the application.
See my development site @ www.CodeTheInter.net (BETA)

Posted Image Posted Image

Quote

If you make it idiot proof, they'll build a better idiot
0

#9 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 24 March 2012 - 06:34 PM

Widgets and clips is made for the purpose of using the same view with different controllers.

Er, did you write 'using the same view with different controllers' ?

Wow, that would really fuck things up, wouldn't it?

I can't really see any benefits of having a view object.
"Less noise - more signal"
0

#10 User is offline   phtamas 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 531
  • Joined: 26-February 11
  • Location:Mezőtúr, Hungary

Posted 25 March 2012 - 01:34 AM

View Postjacmoe, on 24 March 2012 - 05:30 AM, said:

Why can't $this->displayUserStatus($user); be a controller function?


Why can't $this->validateUserInput($_POST); be a controller function? Having a real View layer in your applications has exactly the same advantages as having a Model layer.
1

#11 User is offline   phpnode 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 141
  • Joined: 18-April 11

Posted 25 March 2012 - 03:41 AM

No it does not totally fuck things up, its a very common use case, eg displaying a list of books for an author you might use views/book/_view.php in your list view, even though the current controller is AuthorController
0

#12 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 25 March 2012 - 04:35 AM

Yes, but it's usually included from the active controllers view file?
I use widgets for that.
"Less noise - more signal"
0

#13 User is offline   Jaggi 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 90
  • Joined: 05-September 11

Posted 26 March 2012 - 08:45 AM

Yea in those use cases I usually use widgets too or have a "global" templates folder somewhere for reusable views.
See my development site @ www.CodeTheInter.net (BETA)

Posted Image Posted Image

Quote

If you make it idiot proof, they'll build a better idiot
0

#14 User is offline   Psih 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 115
  • Joined: 30-June 10

Posted 26 March 2012 - 09:16 AM

Object views are not a good idea. Right now you have access to the controller right away and it has it's benefits (I have a use case when I have a custom controller level variable initialized in "init" witch the views needs - with view object I will have to pass it all over the place and that's not helping).
Over-engineering stuff is not healthy, widgets and clips are taking care of re-usability extremely well. I believe it should stay that way, the simplicity of the system is what makes Yii so good, it does not make you use object to simply render a view and that's great (and I have to remind about the beginContent/endContent and other functionality that controller has, some of it can just not work inside a view object. And it's damn useful - too good to be removed just to make a object view.

KISS.
1

#15 User is offline   Da:Sourcerer 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,222
  • Joined: 30-March 11
  • Location:Berlin, Germany

Posted 26 March 2012 - 09:25 AM

I think phpnode is not so much into reusability. To me it looks like he just wants views that are easier to test. This is actualy a strong point in Model-View-Presenter.
programmer /ˈprəʊgramə/, noun: a device that converts ►coffee into ►code
0

#16 User is offline   phpnode 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 141
  • Joined: 18-April 11

Posted 26 March 2012 - 10:44 AM

View PostPsih, on 26 March 2012 - 09:16 AM, said:

Right now you have access to the controller right away and it has it's benefits (I have a use case when I have a custom controller level variable initialized in "init" witch the views needs - with view object I will have to pass it all over the place and that's not helping).


You wouldn't have to pass anything round at all, instead of using:
$this->foo();

You'd just use

$this->controller->foo();


It's not so painful I think.

View PostPsih, on 26 March 2012 - 09:16 AM, said:

it does not make you use object to simply render a view and that's great


I'm explicitly saying that you would never *have* to create a new View object, you could happily use the default view object and continue to put your logic in your controllers if that's what you want. So something like this
// in the controller
public function actionIndex() {
    $this->render("index", array("foo" => true));
}
public function doSomething() {
    return "blah";
}

// in the view file
if ($foo) {
    echo $this->controller->doSomething();
}


it would still work. But if you *do* want to extend the default view, you'd do something like:
// in the controller
public function actionIndex() {
    $view = $this->createView("MyCustomView");
    $view->render("index", array("foo" => true));
}

// in the MyCustomView class

public function doSomething() {
    return "blah";
}

// in the template file
if ($foo) {
    echo $this->doSomething();
}



View PostPsih, on 26 March 2012 - 09:16 AM, said:

I have to remind about the beginContent/endContent and other functionality that controller has, some of it can just not work inside a view object. And it's damn useful - too good to be removed just to make a object view.


We wouldn't need to remove them. The point is you still have access to the controller if you need it via $this->controller.
0

#17 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 26 March 2012 - 03:33 PM

I agree that it is really not MVC that Yii is using.

However, I am not totally sure I like it..
I mean, I prefer MTC.

I think one of the benefits of MTC over MVC is that you don't create as many objects and thus doesn't waste as much CPU and RAM.
I think that's why Yii is faster than /(¤&#"

For testing, couldn't the controller be mocked instead?
If that's the issue?

Still need to see something really convincing..
"Less noise - more signal"
0

#18 User is offline   Da:Sourcerer 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,222
  • Joined: 30-March 11
  • Location:Berlin, Germany

Posted 26 March 2012 - 03:46 PM

View Postjacmoe, on 26 March 2012 - 03:33 PM, said:

I prefer MTC.

?
programmer /ˈprəʊgramə/, noun: a device that converts ►coffee into ►code
1

#19 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,016
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 26 March 2012 - 03:59 PM

I tend to agree to phpnode. While you can discuss a lot about how to implement such a view class in detail, to me it's quite clear that in the current implementation the controller deals way to much with the "V" part of MVC. We use objects for pretty much everything, but we suddenly leave this path when it comes to the View part. With a view class we could benefit from the usual OOP advantages. It would just be consequent to move all rendering logic and view related methods into the view domain.

But true, we already discussed this. Maybe we should revive the old thread instead.
1

#20 User is offline   NaX 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 51
  • Joined: 13-January 12
  • Location:Johannesburg

Posted 26 March 2012 - 04:24 PM

I am a bit of a newbie when it comes to Yii and MVC but after reading everybodies thaughts on this I think we need to take a step back and define what we currently have and what want to get out of changing it.

Firstly, what is a View?
My understanding is that a view is for markup and layout and basic presentation stuff, not for logic.

So where can we put re-usable logic?
Widgets and Clips, controller methods, model methods, application helper functions, user session objects.
Any more?

The way I see it you looking for a preprocessing layer to a View where you can put logic, but then you have to ask yourself should this layer be able to alter variables/data being passed into the View from the Controller. And what about themes, are they also allowed to have logic or override the View logic?

I personally don't think another layer is necessary there are so many options already.
1

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users