Controllers in Plugins
I am writing a plugin that adds a page and I have run into an issue with making a pretty route for it (see below). I'm considering adding a controller to the plugin and it got me thinking: is it alright to add controllers to plugins and simple one-method controllers in general, or is it better to save controllers for larger applications? I would like to know your thoughts on this.
Perhaps it depends on how we define applications vs. plugins. Most of the time, we only see controllers in applications, but they are supported in plugins, and plugins tend to be smaller and extend the Vanilla application. This plugin I'm writing is a good example for discussing this, specifically when it comes to adding a simple one-method controller to the plugin.
The Plugin as an Example
The plugin adds one simple page that displays a Twitch live stream video embed and live chat embed, represented as the website's official live stream.
It creates a /plugin/twitchpage
endpoint in the PluginController and also creates a /settings/twitchpage
endpoint in SettingsController where ConfigurationModule is used to let you set the Twitch channel name to be displayed.
Also, it has code to display link shown as "Live" to /plugin/twitchpage
in the main menu. I would like to let you add a pretty route to this such as /live
. For example, they can add an internal route from the dashboard with live$
(substituting "live" with whatever route you want) with the target plugin/twitchpage
.
The issue is that the link in the main menu won't reflect the new route if one is added. This can't be solved by calling the Gdn::Router()->matchRoute()
method because it checks the route expression, which can be whatever the user has set, and not the target (should be plugin/twitchpage
).
Some solutions:
- Assume the user only would ever use
/live
as the route (I'd use this) and add an option to the settings page to add the route in; however, that means I wouldn't be able to use the ConfigurationModule, where all settings are meant to be saved in the/conf/config.php
whereas the route is set by other methods. Although I can write a custom settings page, this just adds complexity to a small plugin. It would be simpler to make the endpoint/plugin/live
instead. - Add a LiveController within the plugin with one method.
What solution do you think is best for this plugin to achieve the pretty routing?
Add Pages to Vanilla with the Basic Pages app
Comments
Have you tried ?
❌ ✊ ♥. ¸. ••. ¸♥¸. ••. ¸♥ ✊ ❌
@vrijvlinder, that would be good to place on the settings page as a "add and use
/twitchpage
route instead of/plugin/twitchpage
" check box, but is there a way to execute that logic when the settings are saved with the ConfigurationModule?Edit: You probably mean to run that code on the plugin enable and disable events--or anywhere else that isn't saving the settings page for that matter? I have no idea why I hadn't thought of this earlier. That's what happens when I get caught up in seeing how controllers work out in a plugin haha I think most users will be okay with the assumed route name, so this would work great, actually!
Add Pages to Vanilla with the Basic Pages app
That code works flawless in a setting screen. I've used this in a plugin I've never released. My approach was making the route translatable. That way I didn't have to mess around with a setting
Although your problem is already solved: x00 often uses a lot of controllers in his plugins. I have thought about doing this in complex plugins to keep the plugins controller readable, but never did that. It always was enough for me to use external models and views.
If I had splitted my controllers tasks, I would have separated setup(), structure() and settings() in a background/dashboard controller.
@R_J, I didn't know x00 used controllers in his plugins. I might take a look to see how they're put into effect.
Also, controllers being supported in plugins is a recent addition since Vanilla 2.2. It'll be interesting to see how developers incorporate controllers in their plugins.
In case anyone finds it useful, here is a snippet of code I just wrote for creating and deleting the route and showing a link to the page in the main menu accordingly from within the plugin:
Apparently,
Gdn::router()->matchRoute()
returns route info when I'd expected only a boolean, even though there's agetRoute()
method.After all, if I'm only adding one simple method to a controller, it seems better to create a route for it instead of adding the overhead of a whole new controller.
Add Pages to Vanilla with the Basic Pages app
A controller that is not a settings controller is now called a Vanilla Controller…. in the latest stuff. Plugin controller has bugs when it comes to style from the admin.css interfering with the Master view.
Things like this can happen, where the admin theme is shown instead of the master view…
https://vanillaforums.org/badge/community-coder
❌ ✊ ♥. ¸. ••. ¸♥¸. ••. ¸♥ ✊ ❌
Nice find! Has a discussion been made about that yet? Viewing details about a badge has been a front-end page, so the
/badge
endpoint shouldn't show the dashboard view at all unless it was recently made that way on purpose. Is this a bug in the official badges addon, @Linc?Add Pages to Vanilla with the Basic Pages app
Yes I let Linc know and he confirmed it's a bug…. a nasty smelly stink bug… lol
❌ ✊ ♥. ¸. ••. ¸♥¸. ••. ¸♥ ✊ ❌
Afaik this differentiation is going to go away soon. I don't see a reason not to use controllers for larger plugins.
My themes: pure | minusbaseline - My plugins: CSSedit | HTMLedit | InfiniteScroll | BirthdayModule | [all] - PM me about customizations
VanillaSkins.com - Plugins, Themes and Graphics for Vanillaforums OS
A controller is definitely the best way to go about this. It's straightforward, clear, and less prone to future issues. @Bleistivt is correct: applications will one day be folded into plugins. There is precious little difference between them at this point. Personally I wouldn't start a new application for anything less than a new standalone product that didn't rely on the forum in any way.
We actually have the patch for that badge view already merged internally, I just hadn't cherry-picked it to our temporary production release branch yet. We're working on merging our six-month dashboard rebuild project so it's been a bit distracting to our normal workflow.