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

How to create extra page with panel?

R_JR_J Ex-FanboyMunich Admin

I've found that code from @peregrin

public function PluginController_ExtraPage_Create($Sender) {
   $Session = Gdn::Session();
   if ($Sender->Menu)  {
      $Sender->ClearCssFiles();
      $Sender->AddCssFile('style.css');
      $Sender->AddCssFile('exp.css', 'plugins/ExtraPage');
      $Sender->MasterView = 'default';
      $Sender->Render('ExtraPage', '', 'plugins/ExtraPage');
   }
}

But I do not understand the first three lines.
1. $Session isn't used at all in the function so I think it is not necessary. I think it is there as a starting point for further functionality, right?
2. Isn't that function called only once so that $Sender->Menu is always true? If not at what occasions are the plugin conroller functions called?
3. I assume ClearCssFiles deletes every CSS files attached to this controller but what files could that be or is it just to be 100% sure that there is no garbage on the page?

But my real problem is that there is no panel. I'd like to have the same modules like there are when I look at /discussions view. I do not even see a possibility to show the panel itself and I haven't found where the modules are "attached" to the view. So could anyone tell me

  1. how to add the panel to a custom page and
  2. how to show the same content in the panel as a specific other view shows?

Many thanks!

I really try hard to find out how things work and most of the time I get the big picture. But here I see to many question marks to feel satisfied.

Best Answers

«1

Answers

  • Options

    _Create is a magic method that essentially extends the plugin controller. it should only be called by the dispatcher one time per request.

    If you want the panel you could just extend VanillaController, and then you can add modules to the Panel.

    grep is your friend.

  • Options
    vrijvlindervrijvlinder Papillon-Sauvage MVP

    Think of the page as another master.php

    Build it with the html components that exist in he master.

    To include the panel, just add the div

    Make your page with these:

    #Body
    
    #Content
    
    #Panel
    
    #Foot
    

    You could also download one of the plugins I made with extra page to see how I removed or added the Panel.

  • Options
    peregrineperegrine MVP
    edited September 2013

    @hgtonight said:
    In response to your questions about this code:

    1. Doesn't look like $Session is needed. However, it does (in a roundabout way) verify that the framework has been loaded.
    2. It prevents rendering when there isn't a menu on the plugin controller. You will have to ask peregrine exactly what this is for.
    3. Controller's pick up CSS files in the following order: Default CSS files (e.g. /applications/dashboard/design/default.screen.css), Application default (e.g. /applications/app_name/design/default.screen.css), Garden-wide theme view (e.g. /themes/theme_name/design/default.screen.css), and Application-specific theme css (e.g. /themes/theme_name/app_name/design/default.screen.css).

    As far as adding a panel, add the panel asset and then add the modules. You just need to determine what modules to show.

    EDIT: Looks like others already answered and I cross-posted again!

    but you've added more explanation. and thats good. proving to be an interesting thread!

    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
    R_JR_J Ex-Fanboy Munich Admin

    Many thanks for your input. I'll have to read that more than one time, though. Too much information for me right now. I'll get back on that later and give feedback on what I did!

  • Options
    peregrineperegrine MVP
    edited September 2013

    I think x00 was alluding to ..

    . rescinded per x00 below. :)

    @hgtonight said

    It prevents rendering when there isn't a menu on the plugin controller. You will have to ask >@peregrine exactly what this is for.

    • if ($Sender->Menu) {

    was a relict from cutting and pasting code when needed on other functions e.g. renderbefore

    as was stated isn't necessary (but cause no harm other than adding another if).

    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 September 2013

    @x00 said:
    peregrine what? no I was talking about magic methods and extending controllers, like so

    public function VanillaController_ExtraPage_Create($Sender) {}

    cool. I'm always learning from your posts. thanks. Someday you will have to write a book. "How to do anything with vanilla through proper coding techniques" :)

    Thanks for clearing that up. I removed my misinterpreted allusion. It's a tough life (me being new to alot of the mvc and oops stuff).

    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
    R_JR_J Ex-Fanboy Munich Admin

    @hgtonight said:
    As far as adding a panel, add the panel asset and then add the modules. You just need to determine what modules to show.

    I've tried this:

    foreach(C('Modules.Vanilla.Panel') as $ModuleName) {
       $Sender->AddModule($ModuleName, 'Panel');
    }
    

    If not logged in, I just see the GuestModule (makes sense). But if I log myself in I get following error

    Could not find a `newdiscussion` view for the `NewDiscussionModule` module in the `dashboard` application.
    

    I think this also makes sense, because I'm using the plugin controller at that time. So it's time to add @x00 s suggestion:

    @x00 said:
    I was talking about magic methods and extending controllers, like so

    public function VanillaController_ExtraPage_Create($Sender) {}

    My problem was that I didn't know how to access that page, but in fact it's obvious: if I create a Vanilla controller, I'll find it at /vanilla/extrapage!

    So after all that Try & Error & UnderstandingWhyThereWereErrors I've ended up with the following:

       public function VanillaController_ExtraPage_Create($Sender) {
          $Sender->ClearCssFiles();
          $Sender->AddCssFile('style.css');
          $Sender->AddCssFile('extrapage.css', 'plugins/ExtraPage');
    
          // render a normal vanilla page
          $Sender->MasterView = 'default';
    
          // add all the standard vanilla modules
          foreach(C('Modules.Vanilla.Panel') as $ModuleName) {
             $Sender->AddModule($ModuleName, 'Panel');
          }
    
          // get the view to show
          $Sender->Render('extrapage', '', 'plugins/ExtraPage');
       }
    
    

    Thank you all!

  • Options
    peregrineperegrine MVP
    edited September 2013

    @R_J said:
    My problem was that I didn't know how to access that page, but in fact it's obvious: if I create a Vanilla controller, I'll find it at /vanilla/extrapage!

    Nice followup @R_J

    also disable plugin.

    and change target in default.php

    $target = 'Vanilla/ExtraPage$1';

    and verify in routes in dashboard that it reflects that.

    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

    A little tip which is goign to be part of my Worker Domain pattern utility functions if you want to dynamically route this page to say /extrapage or to suit the url you'd like:

      /**
       *  @@ DynamicRoute @@
       *
       *  Add a route on the fly
       *
       *  Typically set in Base_BeforeLoadRoutes_Handler
       *
       *  @param string $Routes loaded
       *  @param string $Route RegExp of route
       *  @param string $Destination to rout to
       *  @param string $Type of redirect (optional), default 'Internal' options Internal,Temporary,Permanent,NotAuthorized,NotFound
       *  @param bool $OneWay if an Internal request prevents direct access to destination  (optional), default FALSE
       *
       *  @return void
       */
    
      public function DynamicRoute(&$Routes, $Route, $Destination, $Type = 'Internal', $Oneway = FALSE){
        $Key = str_replace('_','/',base64_encode($Route));
        $Routes[$Key] = array($Destination, $Type);
        if($Oneway && $Type == 'Internal'){
          if(strpos(strtolower($Destination), strtolower(Gdn::Request()->Path()))===0){
            Gdn::Dispatcher()->Dispatch('Default404');
            exit;
          }
        }
      }
    
      public function Base_BeforeLoadRoutes_Handler($Sender, &$Args){
        // parsing desired uri, and blocking external access to vanilla/extrapage
        $this->Utility()->DynamicRoute($Args['Routes'],'^extrapage(/.*)?$','vanilla/extrapage$1','Internal', TRUE);
      }
    

    You could even make it settable.

    grep is your friend.

  • Options
    peregrineperegrine MVP
    edited September 2013

    I added the @x00 dynamic route routine and the @R_J modules in panel option (via settings page). in version 2.2 of plugin

    and put an easy line in default.php to uncomment if you want the link and page viewable to signed in users using only with Session :). Too tired to add a another config setting :).

    thanks

    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
    vrijvlindervrijvlinder Papillon-Sauvage MVP

    I was under the impression that $Sender->MasterView = 'default'; already renders the panel too, at least for me it did , using display:block!important on the Panel . And constructing the page with the corresponding divs.

  • Options

    I was under the impression that $Sender->MasterView = 'default'; already renders the panel too, at least for me it did , using display:block!important on the Panel . And constructing the page with the corresponding divs.

    there was a panel div but did you have category module added for instance?

    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 September 2013

    Also depends on version of vanilla.

    I revised it again version 2.3 - reverted to old routing, and changed the module loading config statement. see the readme.

    if it don't work use version 2.1 :)

    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
    R_JR_J Ex-Fanboy Munich Admin

    @peregrine: if you've added that foreach config construct, get rid of it. It looks better than it is. I get 2x "Howdy, Stranger!" if I'm not logged in. Will have to dig in that further.

    @x00: have you ever been high on a drug and thinking "don't know what's going on but it feels good"? That's how I feel when I read your code. I could not imagine what dynamic routing is and why it might be better than the - I suppose - static routing that I have already done. But looking longer on your code, I see beautifully patterns in the mist and that looks brilliant: your dynamic route is - somehow magically - routing all /extrapage/sub/calls to corresponding functions in the plugin, right?

    I had the (static) routing already finished when I was struggling with the panel because I haven't started with ExtraPage but found it when I was searching for that panel issue. It would have saved me time.
    The routing by the way was what it made hard to understand why using VanillaController kind of didn't work for me at first: I made a route to "plugin/MyPage" and when replacing PluginController with VanillaController it stopped working.
    My original understanding was that the routing was pointing to directory "/Plugins/MyPage" and that's why I have to do that routing that way. It took me some time to see that the route was "plugin/MyPage" and not "PluginS/MyPage". I have done routing in .htaccess before but not in controllers - I think that's where my misunderstanding came from :-/
    I received some error message about my function couldn't be found in dashboard and that was the hint I needed to know how I had to change my route.

    @vrijvlinder: that's all I've got if I don't add modules by myself

    < div id="Body">
    < div id="Content">
    < h1>TEST!< /h1>< /div>
    < div id="Panel">< /div>
    < /div>
    

    Just an empty div#Panel (at least when you use PluginController!)

    HUA!

    You might think I'm crazy, but I commented out that addmodule part for easily showing vrijvlinder the source code and now it shows the "Howdy, Stranger!" and I do not have added anything! That must be the power of using VanillaController instead of PluginController!

    So I would need something like ClearCssFiles for Modules in order to start with a fresh panel or check if module already exists before adding it (my preferred solution). I'll look at where I can find function AddModule and I'm sure I will find something like a CheckForModule function there.

    Exciting! :-)

  • Options
    x00x00 MVP
    edited September 2013

    There is an error in my code it should be

    $this->DynamicRoute($Args['Routes'],'^extrapage(/.*)?$','vanilla/extrapage$1','Internal', TRUE);

    not

    $this->Utility()->DynamicRoute($Args['Routes'],'^extrapage(/.*)?$','vanilla/extrapage$1','Internal', TRUE);

    $this->Utility() is taken from the worker domain pattern, I just forgot to change it. Sorry.

    grep is your friend.

  • Options
    peregrineperegrine MVP
    edited September 2013

    @x00

    I had the version 2.2 of the plugin with $this (caught that). It may have been my imagination, but it seemed that when I logged out and in while viewing the Extrapage view, the sign in process didn't seem to work properlly. It had trouble with routing using the dynamic routing routine if you were signing on while viewing extrapage.

    However, while clicking in menu from discussions back to the Extrapage worked and vice versa whether I was signed in or not. So routing was there correctly.

    So I switched back to static route in version 2.3 of plugin.

    I also noticed that with version that PluginController_ExtraPage_Create automatically picks up modules in vanilla version 2.2.x but will not automatically pick up modules in 2.18.x

    VanillaController_ExtraPage_Create automatically picks up modules in both versions.

    @R_J -
    I noticed that duplication before you posted yes the foreach routine duplicated some modules if they were in the config statement.
    I suppose they could be unset first.

    Turns out vanilla 2.0.18 and >=2.1 behave quite different with respect to Plugincontroller and VanillaController.

    I'm leaving the plugin at version 2.3 - anyone can use and adjust as they like.
    or use version of plugin at 2.1.

    2.2 shouldn't be used.

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

Sign In or Register to comment.