Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Options

Plugin Question Concerning Views

R_JR_J Ex-FanboyMunich Admin
edited June 2013 in Vanilla 2.0 - 2.8

This time I will have to show some code, because I can not really describe what's happening. I've created a subdirectory "views" and put a file "testview.php" in it with this content
<?php if (!defined('APPLICATION')) exit(); ?>
Hello!</h 1>

In my plugin, I want to show this content:
class TestView extends Gdn_Plugin {
public function DiscussionsController_AfterDiscussionTitle_Handler($Sender) {
$this->ShowTestView($Sender);
}
protected function ShowTestView($Sender) {
$Sender->View = $this->GetView('testview.php');
$Sender->Render();
}
}

This totally screws up my page! The panel and a lot of other things are shown multiple times and I do not even know how to describe what's happening. If I replace the content of my function "ShowTestView" with a simple "echo something" it looks tidy. Could anyone please tell me why this is happening and how to avoid it?

Many thanks!

Comments

  • Options
    hgtonighthgtonight ∞ · New Moderator

    You are calling $Sender->Render()' multiple times. This will cause your DiscussionsController to render multiple times (including the master template).

    Try:

    $View = $this->GetView('testview.php');
    $Sender->Render($View, '', 'plugins/TestView');
    

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    AAH! I understand: $Sender is a DiscussionsController and anytime I reach "...AfterDiscussionTitle..." I ask it to be rendered repeatedly. Over and over again... No wonder it is all messed up :-/

    Great! There was a knot forming up in my brain and it feels released now. But my problem still remains.

    I've tried to find out what the arguments are, that you gave me: $Sender is class.discussionscontroller.php which is derived from class.vanillacontroller.php. Both do not have a render function. VanillaController is derived from class.controller.php which has no render function either, but a xRender function and that seems to be the function that is executed - not too easy to find.
    Anyway: I've found the function and as far as I've understood, your call to Render only specifies where my view can be found, but that should already be clear after using GetView. And in fact, using only $Sender->Render($View) leads to the same result.

    That said, I suppose I was wrong in my first statement. Shouldn't the controllers render function only echo the contents of the specified file? It is not working for my case (by the way: I am using Vanilla 2.0.18, but I suppose it is a general understunding problem)

    My brains knotting up again :-(

  • Options
    hgtonighthgtonight ∞ · New Moderator

    The xRender() method is a special type of method that is overrideable. The 'x' lets the function support magic events.

    I believe you should be rendering the plugin controller. I.e. $this->Render($View);

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    Sounds totally reasonable, but now I've got bonked! And funny we spoke about xRender - the clear text error I've got is The "DiscussantsPlugin" object does not have a "xRender" method.

    Freaky and now I'm totally lost - up to now I thought I will understand what's happening, if I think about it a second or third time. Now I'm not so sure anymore...
    I'll go through other plugins that use views and try to find out what they did. I'm out of ideas here.

    (A little off topic - sorry, but I really love to be off topic - but I always have to smile when seeing this error: for one year in school I had an English teacher called Bonk and, to put it nicely, we agreed to not being friends. I assume he could have done a thousand jobs better than being a teacher. So I really like an error screen being called "Bonk")

  • Options
    hgtonighthgtonight ∞ · New Moderator
    edited June 2013

    I don't have my dev comp in front of me. Looking at the source, it seems like $Sender->Render($this->GetView('testview.php')); should work.

    It may be more of a design issue. I know modules fully support views (and therefore are themeable). I have overridden a controller's view. But I have never inserted a view into an existing controller.

    I am not sure this helps you though :S

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    I really appreciate your help and if you tell me that my design is wrong, I have learned something, too!

    But I do not understand how to render a view from inside a plugin in a way, that it is not executed recursivly, but only once? I do not need something like this now, but I'm sure that something like this at least should exist.

    I will not try to solve this problem, though. That was my last issue and now I'm sure I will not find a solution for this on the short hand. I'll shrink what I have done and get rid of the view. And then I'll release my first plugin! :-)

  • Options
    peregrineperegrine MVP
    edited June 2013

    . never mind wrong thing.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • Options
    peregrineperegrine MVP
    edited June 2013

    I could be wrong.

    My concept is when you render a view you are rendering to asset e.g. it totally replaces the view to the module in the asset panel in some plugins, or displays a totally different page via a render and redirect.

    It looks like you are possibly mistakenly trying to render view to "content" but then you would be replacing the entire asset (that is the content panel) and that is not what you want probably want to do.

    You seem like you just want to display more info in a specific area in the content panel and you probably just want to compartmentalize so put it in a function.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • Options
    hgtonighthgtonight ∞ · New Moderator

    @R_J said:
    I really appreciate your help and if you tell me that my design is wrong, I have learned something, too!

    I am not saying it is wrong, just that I can't think of a "proper" way to do this. If I needed my inserted content to be themeable, I would create a module that is themeable and just render it.

    E.g.

    protected function ShowTestView($Sender) {
      $Module = new MyTestViewModule($Sender);
      return $Module->ToString();
    }
    

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    I think @peregrin is right: I'm trying to render to content, although I just wanted to add some extra information. Seems like render function is not what I thought it is. I would need something like the ToString. But I will think about it when I need it and that is not now: I'm finished!

Sign In or Register to comment.