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...
1

Comments
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
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')); }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 fiThanks 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; }