pegasus
Well-known member
- Affected version
- 2.2.11
At first glance, maybe this doesn't sound like a big issue, but let's start off with the first point: inconsistency. When an add-on is disabled, its event listeners and template modifications are also disabled, meaning that code is not run. If we are in the habit of not running an add-on's code while it's disabled, why not include template code in that?
As a coder myself, this inconsistency has been documented in bug reports for my add-ons to lead to fatal errors. Here's how:
XenForo allows for add-ons to implement something called "template functions", which can be added to \XF\Template\Templater using event listeners (calling $templater->addFunctions in event templater_setup) and/or applying class extensions to \XF\Template\Templater. Add-ons can then use these template functions that they've created within their own templates.
But if the add-on is disabled, XenForo disables the event listeners and class extensions that setup the custom template functions.
Meanwhile, it is still possible to render a template that calls such a template function.
Most egregious is when a custom template function has been used in an add-on's .less template. In this case, XenForo's guest cache (and other server side caches) caches HTML responses that include calls to css.php which use the .less template, while the add-on is disabled, and while the code setting up the template functions is disabled. This leads to \XF\Template\Templater throwing:
This is not limited to just CSS output. It may be typical for multiple add-ons by a single developer, or multiple add-ons that simply have support for each other's features, to attempt to render the template of another add-on, while one add-on is disabled and the other is not. Then we have the same problem.
It seems close to impossible for an add-on developer to resolve this situation on their own (any code trying to implement a workaround would also just be disabled when the add-on is disabled). While XenForo also provides the template function is_addon_active, it seems unreasonable to have to use this in a conditional around every potential usage of a template function.
There are a number of ways for XenForo devs to resolve this design issue and ideally the solution is some combination of these:
#1 Do NOT trigger_error for a missing template function unless the forum is in development mode, AND the add-on for the containing template is also enabled.
#2 Automatically clear the XenForo guest cache when an add-on's active state is changed.
#3 Do NOT render a template if the template is provided by a disabled add-on. This requires a number of modifications to \XF\Template\Compiler and how it is implemented:
As a coder myself, this inconsistency has been documented in bug reports for my add-ons to lead to fatal errors. Here's how:
XenForo allows for add-ons to implement something called "template functions", which can be added to \XF\Template\Templater using event listeners (calling $templater->addFunctions in event templater_setup) and/or applying class extensions to \XF\Template\Templater. Add-ons can then use these template functions that they've created within their own templates.
But if the add-on is disabled, XenForo disables the event listeners and class extensions that setup the custom template functions.
Meanwhile, it is still possible to render a template that calls such a template function.
Most egregious is when a custom template function has been used in an add-on's .less template. In this case, XenForo's guest cache (and other server side caches) caches HTML responses that include calls to css.php which use the .less template, while the add-on is disabled, and while the code setting up the template functions is disabled. This leads to \XF\Template\Templater throwing:
Code:
trigger_error("Function $name is unknown", E_USER_WARNING);
This is not limited to just CSS output. It may be typical for multiple add-ons by a single developer, or multiple add-ons that simply have support for each other's features, to attempt to render the template of another add-on, while one add-on is disabled and the other is not. Then we have the same problem.
It seems close to impossible for an add-on developer to resolve this situation on their own (any code trying to implement a workaround would also just be disabled when the add-on is disabled). While XenForo also provides the template function is_addon_active, it seems unreasonable to have to use this in a conditional around every potential usage of a template function.
There are a number of ways for XenForo devs to resolve this design issue and ideally the solution is some combination of these:
#1 Do NOT trigger_error for a missing template function unless the forum is in development mode, AND the add-on for the containing template is also enabled.
#2 Automatically clear the XenForo guest cache when an add-on's active state is changed.
#3 Do NOT render a template if the template is provided by a disabled add-on. This requires a number of modifications to \XF\Template\Compiler and how it is implemented:
- A new setAddonId method:
Code:public function setAddonId($addonId) { $this->addonId = $addonId; }
Implemented by \XF\Service\Template\Compile::recompile:
Code:$compiler->reset(); $compiler->setAddonId($template->addon_id);
- New code in the getCompletedTemplateCode method:
Code:$parts[] = "'addon_id' => {$this->addonId}";
- Finally, apply a test in \XF\Template\Templater::renderTemplate against $data['addon_id'] and only render an empty string if the add-on is disabled.
Last edited: