HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Code Snippets

There are some tasks I face more often when trying to write a plugin and I always have to search in order to get started. I do not want to write a full blown skeleton with each and every possibility, I favor a collection of useful snippets. That's why I've started this discussion where I will post some useful snippets without much explanation. Maybe some of you want to join in...

Comments

  • R_JR_J Admin

    First one is a skeleton for a page of the look and feel of a standard vanilla page

    public function VanillaController_MyPlugin_Create($Sender) {
       $Sender->MasterView = 'default';
    
       $Sender->ClearCssFiles();
       $Sender->AddCssFile('style.css');
       $Sender->AddCssFile('myplugin.css', 'plugins/MyPlugin');
    
       $Sender->AddModule('UserBoxModule');
       $Sender->AddModule('CategoriesModule');
       $Sender->AddModule('BookmarkedModule');
       $Sender->AddModule('GuestModule');
       $Sender->AddModule('NewDiscussionModule');
       $Sender->AddModule('DiscussionFilterModule');
       $Sender->AddModule('SignedInModule');
       $Sender->AddModule('CategoryFollowModule');
       $Sender->AddModule('DraftsModule');
       $Sender->AddModule('CategoryModeratorsModule');
       $Sender->AddModule('Ads');
    
       $Sender->SetData('Breadcrumbs', array(array('Name' => T('My Plugin'), 'Url' => '/vanilla/myplugin')));
    
       $Sender->Render(parent::GetView('myplugin.php'));
    }
    
  • Please can we get some more, awesomeness

  • I never posted any follow ups, but there are a lot of things I need more often...

    This one put at the end of a view will force a reload of the page after a popup has been closed.

    <script>
    var myFunc = $.popup.close;
    $.popup.close = function () {
      myFunc.apply(this, arguments);
      location.reload(); 
    };
    </script>
    

    Needful if you have a "edit" popup on a page and want the page to reload after you have made your changes

  • R_JR_J Admin
    edited December 2016

    Although using pluginController for the plugins setting screen is recommended, I prefer using the settingsController:

    A settings screen where you do some validations:

        public function settingsController_..._create($sender) {
            $sender->permission('Garden.Settings.Manage');
    
            $sender->addSideMenu('dashboard/settings/plugins');
    
            $sender->setData('Title', t('...'));
    
            $validation = new Gdn_Validation();
            $configurationModel = new Gdn_ConfigurationModel($validation);
            $configurationModel->setField(
                [
                    '....Field1',
                    '....Field2',
                    '....Field3',
                    ...
                ]
            );
            $sender->Form->setModel($configurationModel);
    
            if ($sender->Form->authenticatedPostBack() === false) {
                // If form is displayed "unposted".
                $sender->Form->setData($configurationModel->Data);
            } else {
                // Validate posted form.
                $sender->Form->validateRule('....Field1', 'ValidateRequired');
                $sender->Form->validateRule('....Field1', 'ValidateInteger');
                $sender->Form->validateRule('....Field2', 'ValidateRequired');
                // Enum validation.
                $field = (object)[];
                $field->Enum = ['Monday', 'Tuesday']; // etc
                $field->AllowNull = true;
                $sender->Form->validateRule('....Field3', ['Name' => 'ValidateEnum', 'Args' => $field]);
                // "Manual" errors:
                if (! some condition ) {
                    $sender->Form->setValidationResults(
                        [
                            '....Field2' => [
                                'Any number of error messages',
                                'provided as an array'
                            ]
                        ]
                    );
                }
    
                // Try saving values.
                if ($sender->Form->save() !== false) {
                    $sender->informMessage(
                        sprite('Check', 'InformSprite').t('Your settings have been saved.'),
                        ['CssClass' => 'Dismissable AutoDismiss HasSprite']
                    );
                }
            }
            $sender->render($this->getView('settings.php'));
        }
    
  • If you click on a link (let's call it "FormB") without .Popup, the link is simply followed and the page FormB opens. After you click the submit button, the you will still be on FormB. That is not what you would like to see if you submit FormB as a popup from Main, nor? o.O >

    No. We defined the logic that pressing some specific Button-B on FormMain redirects to another formB which upon some Button-Return pressing returns to Main. So there is an implicit parent-child flow relationship. Clearly, pressing Button-Return gives control to the code that renders FormB. Then that code tries to redirect for the Main, and that's working fine without the Popup but breaks if FormB was in a popup. So again, I think for FormB logic should work identically regardless of the Popup state (in other words, Vanilla should handle it internally upon realizing that a different view is rendered). Here is the ideal FormB logic in pseduocode:

    FormB:
       if (postback) 
          If (Button-Return)
             redirect to Main     //Ideally that should work regardless of whether it is in a popup or not
          fi
       fi
    
  • KasparKaspar ✭✭✭

    Thanks to @R_J 's <a href="https://open.vanillaforums.com/discussion/comment/255689/#Comment_255689">post</a> I figured how to avoid Plugin ThemeChooser from applying a custom theme to dashbard.

    public function base_render_before($sender) {
       // The first argument passed to that function is the current controller, the instance calling the method is named "$sender" by default in Vanilla.
       // Most probably you do not want to do anything in the dashboard.
       if (inSection('Dashboard')) {
          return;
       }
    


    In /plugins/ThemeChooser/class.themechooser.plugin.php - just after:

    class ThemeChooserPlugin extends Gdn_Plugin {
        public function Base_Render_Before($Sender) {
            $Session = Gdn::Session();
            if (!$Sender->Data || !$this->Enabled()) {
                return;
            }
    

    I added:

    if (inSection('Dashboard')) {
          return;
       }
    
Sign In or Register to comment.