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.

How to override a module view by a plugin

Hello,

I am fresh new to the vanilla Community, so just be tolerant with me a little bit. Here's my queston: I want to create a plugin that adds comments unread count next to the unread discussions in the categories module. I found in the class CategoriesModule ,placed in application/vanilla/modules, a GetData event ($this->fireEvent('GetData');) , but I'm not able to override it even if I created a function in my plugin class with that definition "public function categoriesModuleController_getData_handler($Sender)".

I also want to override the module view so I can add the counts in a label but still don't know how to override a module view with a plugin.

Thanks a lot in advance for your help.

Best Answer

Answers

  • I actually solved the event problem. The function name was wrong, I added the Controller suffix when I shouldn't. So the right definition is : "public function CategoriesModule_GetData_handler($Sender)"

    I am now stuggling with how to override the module view in my plugin.

  • In instead of overriding a module view create a new module an use that. Which is what you are really doing anyway.

    grep is your friend.

  • I solved it by creating the view in the custom even if it's not what I really want: Having the plugin working independently from themes and core vanilla sources. Thank you for your help by the way.

  • dvenckusdvenckus New
    edited December 2015

    This solution seems to be working for me. I just figured this out so its pretty fresh.

    I wanted to override the DiscussionFilterModule so I cloned the module into my plugin, renamed it xDiscussionFilterModule and made my changes to the view. I also wanted to preserve the position of the module in the page.

    In your plugin class, set up this handler as it gets called for every page.

    public function Base_Render_Before(&$Sender) {
        // Module Overrides
        // if DiscussionFilterModule is being added to the page, replace it with our custom version
        if (isset($Sender->Assets['Panel']['DiscussionFilterModule'])) {
            // create an instance of the new custom module & add it
            $xDiscussionFilterModule = new xDiscussionFilterModule($Sender, $Data);
            $Sender->AddModule($xDiscussionFilterModule);
          
            // grab the contents of the new module from the Assets Panel
            $override = $Sender->Assets['Panel']['xDiscussionFilterModule'];
    
            // replace the existing module's Assets Panel values with the new content
            $Sender->Assets['Panel']['DiscussionFilterModule'] = $override;
    
            // finally, cleanup.  we don't need this one anymore
            unset($Sender->Assets['Panel']['xDiscussionFilterModule']);
        }
    }
    

    There's probably a more efficient way to do this, but I just figured this out as a solution for my own site.

    Deb V

  • dvenckusdvenckus New
    edited December 2015

    Hey Vanilla Development:

    A slight core change can make overriding modules very easy. Can I request this change to core?

    In '/library/core/class.controller.php', in the 'AddModule()' method, there is already a call to fireEvent['BeforeAddModule']. Changing it as follows will make module overrides very easy.

        // Class:  Gdn_Controller
        public function addModule($Module, $AssetTarget = '') {
    
              // Add this line
              $this->EventArguments['Module'] = &$Module;
            
              $this->fireEvent('BeforeAddModule');
              $AssetModule = $Module;
              ...
              ...
              ...
    

    This allows modules to be overridden by adding this handler to your plugin and switching the name of the module to a custom module before it is added.

        // Class:  MyExamplePlugin
        public function Base_BeforeAddModule_Handler(&$Sender) {
            if ($Sender->EventArguments['Module'] == 'DiscussionFilterModule') {
              $Sender->EventArguments['Module'] = 'xDiscussionFilterModule';
            }
        }
    

    This is the solution I will be using for my site.

    Deb V

  • @dvenckus said:
    Hey Vanilla Development:

    A slight core change can make overriding modules very easy. Can I request this change to core?

    In '/library/core/class.controller.php', in the 'AddModule()' method, there is already a call to fireEvent['BeforeAddModule']. Changing it as follows will make module overrides very easy.

        // Class:  Gdn_Controller
        public function addModule($Module, $AssetTarget = '') {
    
              // Add this line
              $this->EventArguments['Module'] = &$Module;
            
              $this->fireEvent('BeforeAddModule');
              $AssetModule = $Module;
              ...
              ...
              ...
    

    This allows modules to be overridden by adding this handler to your plugin and switching the name of the module to a custom module before it is added.

        // Class:  MyExamplePlugin
        public function Base_BeforeAddModule_Handler(&$Sender) {
            if ($Sender->EventArguments['Module'] == 'DiscussionFilterModule') {
              $Sender->EventArguments['Module'] = 'xDiscussionFilterModule';
            }
        }
    

    This is the solution I will be using for my site.

    Deb V

    The addModule method accepts an object as well as a name of a module. Just an FYI that the __toString() method will output the view of the module in this case rather than the name. https://github.com/vanilla/vanilla/blob/c5b8153ec40e396493a47fca1e0bb7433cf6cd7b/library/core/class.module.php#L247-L248

    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.

Sign In or Register to comment.