Plugins that have global settings need to define a “settings model”, which is responsible for storing the setting values, and validating them.
Settings models are just like any other model. To create it, create a models/
directory within your plugin’s source directory, and create a Settings.php
file within it:
<?php
namespace ns\prefix\models;
use craft\base\Model;
class Settings extends Model
{
public $foo = 'defaultFooValue';
public $bar = 'defaultBarValue';
public function rules()
{
return [
[['foo', 'bar'], 'required'],
// ...
];
}
}
Next up, add a createSettingsModel()
method on your main plugin class, which returns a new instance of your settings model:
<?php
namespace ns\prefix;
class Plugin extends \craft\base\Plugin
{
protected function createSettingsModel()
{
return new \ns\prefix\models\Settings();
}
// ...
}
With your settings model and createSettingsModel()
method in place, you can now access your settings model, populated with any custom values set for the current project, via a getSettings()
method on your main plugin class:
// From your main plugin class:
$foo = $this->getSettings()->foo;
// From elsewhere:
$foo = \ns\prefix\Plugin::getInstance()->getSettings()->foo;
Or you can use the $settings
magic property:
// From your main plugin class:
$foo = $this->settings->foo;
// From elsewhere:
$foo = \ns\prefix\Plugin::getInstance()->settings->foo;
Your setting values can be overridden on a per-project basis from a PHP file within the project’s config/
folder, named after your plugin handle. For example, if your plugin handle is foo-bar
, its settings can be overridden from a config/foo-bar.php
file.
The file just needs to return an array with the overridden values:
<?php
return [
'foo' => 'overriddenFooValue',
'bar' => 'overriddenBarValue',
];
It can also be a multi-environment config:
<?php
return [
'*' => [
'foo' => 'defaultValue',
],
'.dev' => [
'foo' => 'devValue',
],
];
{note} The config file cannot contain any keys that are not defined in the plugin’s settings model.
Plugins can also provide a settings page in the Control Panel, which may make it easier for admins to manage settings values, depending on the plugin.
To give your plugin a settings page, create a templates/
directory within your plugin’s source directory, and create a settings.html
file within it:
{% import "_includes/forms" as forms %}
{{ forms.textField({
first: true,
label: "Foo",
name: 'foo',
value: settings.foo
}) }}
{{ forms.textField({
label: "Bar",
name: 'bar',
value: settings.bar
}) }}
Then, within your main plugin class, set the $hasCpSettings
property to true
, and define a settingsHtml()
method that returns your new rendered template:
<?php
namespace ns\prefix;
class Plugin extends \craft\base\Plugin
{
public $hasCpSettings = true;
protected function createSettingsModel()
{
return new \ns\prefix\models\Settings();
}
protected function settingsHtml()
{
return \Craft::$app->getView()->renderTemplate('plugin-handle/settings', [
'settings' => $this->getSettings()
]);
}
// ...
}
With all that in place, your plugin will now get its own icon on the Settings page, and a cog icon in its row on the Settings → Plugins page, which will link to /admin/settings/plugin-handle
.
When the /admin/settings/plugin-handle
Control Panel URL is requested, your plugin is ultimately in charge of the response. Namely, your plugin’s getSettingsResponse()
method. The default getSettingsResponse()
implementation in craft\base\Plugin
will call your plugin’s settingsHtml()
method, and then tell the active controller to render Craft’s settings/plugins/_settings
template (the layout template for plugin settings pages), passing it the HTML returned by settingsHtml()
.
If a plugin needs more control over its settings page(s), it can override its getSettingsResponse()
method and do whatever it wants with the request.
It can choose to render its own template, rather than being confined to Craft’s settings/plugins/_settings
layout template:
public function getSettingsResponse()
{
return \Craft::$app->controller->renderTemplate('plugin-handle/settings/template');
}
It can redirect the request to a completely different URL, too:
public function getSettingsResponse()
{
$url = \craft\helpers\UrlHelper::cpUrl('plugin-handle/settings');
return \Craft::$app->controller->redirect($url);
}
Just note that whatever it returns needs to make sense as something a controller action would return, because that’s exactly what’s happening. The craft\controllers\PluginsController::actionEditPluginSettings()
method returns whatever getSettingsResponse()
returns directly.