<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html" />
  <link rel="self" type="application/atom+xml" href="http://forums.movabletype.org/atom.xml" />
  <id>tag:forums.movabletype.org,2011://24/tag:forums.movabletype.org,2008://24.10562-</id>
  <updated>2011-09-01T02:26:55Z</updated>
  <title>Comments for HOWTO: Define custom plugin settings</title>
  
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.292</generator>
  <entry>
    <id>tag:forums.movabletype.org,2008://24.10562</id>
    <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.movabletype.org/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=24/entry_id=10562" title="HOWTO: Define custom plugin settings" />
    <published>2008-11-04T01:25:36Z</published>
    <updated>2008-12-12T09:56:05Z</updated>
    <title>HOWTO: Define custom plugin settings</title>
    <summary>Working on an addition to the Movable Type developer guide which I wanted to post here first for feedback: Plugin Settings Often plugins need a way to allow their users to customize and configure their behavior in some way. For...</summary>
    <author>
      <name>Byrne Reese</name>
      <uri>http://www.majordojo.com</uri>
    </author>
    
    <category term="Documentation" />
    
    <content type="html" xml:lang="en" xml:base="http://forums.movabletype.org/">
      <![CDATA[<p>Working on an addition to the Movable Type developer guide which I wanted to post here first for feedback:</p>

<h1>Plugin Settings</h1>

<p>Often plugins need a way to allow their users to customize and configure their behavior in some way. For example, an Amazon plugin may want collect your Amazon Associates ID to embed within a link it generates. Or perhaps a theme or template set wants to make it easy for users to change the color scheme, or header image. Regardless of what options you need to surface to your users, Movable Type offers a relatively simple system for doing so.</p>

<p>This system works by editing your plugin's <code>config.yaml</code> and registering a set of plugin settings, and the templates that will be used for rendering the user interface and form for editing those settings.</p>

<p>The following guide will take you through this process, and then show you some alternatives that make this process even easier.</p>

<h2>Registering Plugin Settings</h2>

<p>Step one is registering each of the individual settings you will need to make available to your users. In this first step we are not defining the UI for these settings, just that the settings exist, their default values, their scope and what names will be used for storing and retrieving the values they hold. </p>

<p>Here is a small excerpt from a plugin that defines a single setting with a look up key of <code>my_setting</code>:</p>

<p><strong>Sample config.yaml</strong></p>

<pre><code>name: Example Plugin for Movable Type
id: Example
description: This plugin is an example plugin for Movable Type.
settings:
  my_setting:
    default: "Byrne"
    scope: blog
</code></pre>

<p><strong>Registry Properties</strong></p>

<ul>
<li><p><strong>default</strong> - the default value for this plugin setting when no value has been explicitly provided by the user.</p></li>
<li><p><strong>scope</strong> - the scope for which this setting applies. A value of "system" will indicate to Movable Type to store only one value for this setting across the entire installation, whereas a value of "blog" will instruct Movable Type to store a value for this setting for each blog in the system.</p></li>
</ul>

<h2>Registering a Plugin Settings Template</h2>

<p>Once you have declared what settings will be collected, the next thing you need to do is create the UI for editing them. First you will need to register the config template that will be used for the system level or blog level (or both) settings interfaces. There are two registry properties you can use:</p>

<ul>
<li><code>system_config_template</code></li>
<li><code>blog_config_template</code></li>
</ul>

<p>Each of these properties takes a single value as input, the name of the template file used to render your settings. The template file you will create will need to be placed in your plugins <code>tmpl</code> directory.</p>

<p>Here is a sample <code>config.yaml</code> that shows these registry properties in action:</p>

<pre><code>
name: Example Plugin for Movable Type
id: Example
description: This plugin is an example plugin for Movable Type.
<strong>system\_config\_template: system_config.tmpl
blog_config_template: blog_config.tmpl</strong>
settings:
  my\_setting:
    default: "Byrne"
    scope: blog
</code></pre>

<h2>Implementing a Settings Template</h2>

<p>With your settings template or templates registered, time to actually implement one. Let's begin by creating a template called <code>blog_config.tmpl</code> and placing it in your plugins <code>tmpl</code> directory.</p>

<p>The first template we will create will expose a single text field with the label "My Setting." Here is the template code you would use:</p>

<pre><code>&lt;mtapp:setting
  id="my_setting"
  label="My Setting"
  hint="Enter any value you want here."
  show_hint="1"&gt;
    &lt;input type="text" name="my_setting" id="my_setting" 
       value="&lt;mt:var name="my_setting"&gt;" /&gt;
&lt;/mtapp:setting&gt;
</code></pre>

<p>A couple things to note:</p>

<ol>
<li><p>The template above only defines the input elements themselves, the <code>&lt;form&gt;</code> tag that wraps your input element will be generated for you automatically by Movable Type.</p></li>
<li><p>Movable Type automatically populates your template with variables that hold the current value of each of your plugin configuration settings. You can use any normal Movable Type template to access these values.</p></li>
</ol>

<p>Finally, the single most important detail in making all of this work is utilizing a name for your form elements that are synchronized with the setting you defined for them in your <code>config.yaml</code>. Let's look at one more example. First your <code>config.yaml</code>:</p>

<pre><code>
settings:
  <strong>my\_favorite\_color</strong>:
    default: "Blue"
    scope: blog
</code></pre>

<p>And now the form element that will allow a user to provide a value for this setting:</p>

<pre><code>
&lt;mtapp:setting
   id="my_setting"
   label="My Setting"
   hint="Enter any value you want here."
   show_hint="1"&gt;
&lt;select name="<strong>my\_favorite\_color</strong>"&gt;
  &lt;option&gt;Red&lt;/option&gt;
  &lt;option&gt;Yellow&lt;/option&gt;
  &lt;option&gt;Green&lt;/option&gt;
  &lt;option&gt;Blue&lt;/option&gt;
&lt;/select&gt;
&lt;/mtapp:setting&gt;
</pre></code>

You can include as many form elements that you want. To help you with the styling of these form elements, Movable Type provides the helper `<mtapp:setting>` tag which makes creating the HTML markup for your forms much, much simpler. Let's take a closer look at the this template tag so that you can use its fullest benefit.

**`<mtapp:setting>` Properties**



7b827900ab2b886329042f835387c07e


<h2>Fetching Plugin Data</h2>

By now you should have successfully created a plugin that exposes a simple user interface that makes it possible for you to collect from your users configuration data for your plugin and for that information to be faithfully stored by Movable Type. The following section will instruct you on how to access that information once it has been stored.

**Fetching a System-Level Setting**

If you need to retrieve the value stored for a setting that is consider a system wide setting, then the following code should do the trick:

<pre><code>my $plugin = MT-&gt;component("MyPlugin");
my $my_setting = $plugin-&gt;get_config_hash('my_setting','system');
</code></pre>

<p><strong>Fetching a Blog-Level Setting</strong></p>

<p>Retrieving a blog-specific setting is very similar, and requires only one additional piece of information: the ID of the blog for which this setting applies:</p>

<pre><code>my $plugin = MT-&gt;component("MyPlugin");
my $scope = "blog:" . $blog_id;
my $my_setting = $plugin-&gt;get_config_value('my_setting',$scope);
</code></pre>

<p>And finally, you can fetch <em>all of the values</em> associated with your plugin's preferences at once by using the <code>get_config_hash</code> method like so:</p>

<pre><code>my $plugin = MT-&gt;component("MyPlugin");
my $scope = "blog:" . $blog_id;
my $config = $plugin-&gt;get_config_hash($scope);
my $my_setting = $config-&gt;{'my_setting'};
</code></pre>

<h2>Using Configuration Assistant</h2>

<p>Even with Movable Type's capable API for letting developers define their own custom user interfaces for collecting plugin preferences from their user's, there exists a far easier method by way of a plugin prototype called "Config Assistant." Config Assistant is useful because it reduces all of the work associated with collecting and accessing plugin configuration data to editing a config file. </p>

<p>To illustrate let's take a second look at the example explained in gory detail previously that surfaced a single text field called "My Setting." To accomplish that task you needed to:</p>

<ol>
<li>Register the setting in your <code>config.yaml</code>.</li>
<li>Register a template for rendering your settings form.</li>
<li>Create a template to display your setting form elements.</li>
</ol>

<p>That <em>entire</em> process can be reduced to the following <code>config.yaml</code> file:</p>

<pre><code>name: Example Plugin for Movable Type
id: Example
description: This plugin is an example plugin for Movable Type.
settings:
  my_setting:
    default: Byrne
    scope: blog
blog_config_template: '&lt;mt:PluginConfigForm id="Example"&gt;'
plugin_config:
    Example:
        fieldset_1:
            my_setting:
                type: text
                label: "My Setting"
                hint: "Enter anything here."
                tag: 'MySetting'
</code></pre>

<p>After all that, this is what Config Assistant will output for your plugin's settings UI:</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://www.movabletype.org/documentation/2008/11/03/Picture%201.png"><img alt="Config Assistant Example Screenshot" src="http://www.movabletype.org/documentation/assets_c/2008/11/Picture 1-thumb-500x155.png" width="500" height="155" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<h3>Config Assistant Registry Settings</h3>

<p>Config Assistant is driven 100% by configuration data you place in your plugin's <code>config.yaml</code>. In addition to defining a new data structure for use within your <code>config.yaml</code>, Config Assistant makes use of the following registry keys as well:</p>

<ul>
<li><code>settings</code> - you still need to register the values that will be stored in the database.</li>
<li><code>blog_config_template</code> and <code>system_config_template</code> - you also need to provide templates to properly display the form defined by the <code>plugin_config</code> registry data structure.</li>
</ul>

<p>The new registry data structure parsed exclusively by Config Assistant is associated with the registry key <code>plugin_config</code>. This element has a single child element, corresponding to the plugin's id for which you are defining configuration options. It is this element which will contain each of your plugin's configuration options and input elements, grouped by fieldset. Let's look at an example that stubs out one possible <code>plugin_config</code> data structure:</p>

<pre><code>plugin_config:
  MyPluginID:
    ServerInfo:
      server_host: *snip*
      server_port: *snip*
    PluginOptions: 
      use_https: *snip*
      http_auth_username: *snip*
      http_auth_password: *snip*
</code></pre>

<p>The sample above defines two field sets:</p>

<ul>
<li>ServerInfo</li>
<li>PluginOptions</li>
</ul>

<p>Each of these field sets will be encapsulated by the HTML element from which they get their name:</p>

<pre><code>&lt;fieldset id="ServerInfo"&gt;
  &lt;!-- form elements go here --&gt;
&lt;/fieldset&gt;
&lt;fieldset id="PluginOptions"&gt;
  &lt;!-- form elements go here --&gt;
&lt;/fieldset&gt;
</code></pre>

<p>Field sets like this provide the benefit of visually grouping related configuration options together. They have no bearing on the functionality of your plugin.</p>

<p>Within each of these field sets, Config Assistant will render their associated form input elements, or "fields."</p>

<p>Each field then supports the following registry properties:</p>

<ul>
<li><p><strong>type</strong> - the type of the field. Supported values are: text, textarea, select, checkbox.</p></li>
<li><p><strong>label</strong> - the label to display to the left of the input element</p></li>
<li><p><strong>hint</strong> - the hint text to display below the input element</p></li>
<li><p><strong>tag</strong> - the template tag that will access the value held by the corresponding input element</p></li>
<li><p><strong>values</strong> - valid only for fields of type "select" - this contains a comma delimitted list of values to present in the pull down menu</p></li>
<li><p><strong>rows</strong> - valid only for fields of type "textarea" - this corresponds to the number of rows of text displayed for the text area input element</p></li>
</ul>

<p>Finally, in order for Config Assistant to properly surface the form under your plugin's settings area, you will need to define a blog configuration template using the <code>blog_config_template</code> registry property like so:</p>

<pre><code>blog_config_template: '&lt;mt:PluginConfigForm id="MyPluginID"&gt;'
</code></pre>

<h3>Auto-Generated Template Tags</h3>

<p>Each plugin configuration field can define a template tag by which a designer or developer can access its value. If a tag name terminates in a question mark then the system will interpret the tag as a block element. Here are two example configs:</p>

<pre><code>feedburner_id:
    type: text
    label: "Feedburner ID"
    hint: "This is the name of your Feedburner feed."
    tag: 'FeedburnerID'
use_feedburner:
    type: checkbox
    label: "Use Feedburner?"
    tag: 'IfFeedburner?'
</code></pre>

<p>And here are corresponding template tags that make use of these configuration options:</p>

<pre><code>&lt;mt:IfFeedburner&gt;
  My feedburner id is &lt;mt:FeedburnerID&gt;.
&lt;mt:Else&gt;
  Feedburner is disabled!
&lt;/mt:IfFeedburner&gt;
</code></pre>
]]>
      

    </content>
  </entry>

  <entry>
    <id>tag:forums.movabletype.org,2008://24.10562-comment:14218</id>
    <thr:in-reply-to ref="tag:forums.movabletype.org,2008://24.10562" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html"/>
    <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html#c14218" />
    <title>Comment from Mike T on 2008-11-09</title>
    <author>
        <name>Mike T</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Looking good.</p>]]>
    </content>
    <published>2008-11-09T15:40:33Z</published>
  </entry>

  <entry>
    <id>tag:forums.movabletype.org,2008://24.10562-comment:14296</id>
    <thr:in-reply-to ref="tag:forums.movabletype.org,2008://24.10562" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html"/>
    <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html#c14296" />
    <title>Comment from Rob Staveley on 2008-11-11</title>
    <author>
        <name>Rob Staveley</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>I've just been having a go at this for a custom tag, and it is a great-looking procedure.</p>

<p>It isn't clear, however, how you get the configuration settings from the context parameter in a tag subroutine. Could you add something for that?</p>

<p>I've got my tag plugin up and running following this recipe: <a href="http://www.movabletype.org/documentation/developer/template-tag-handler.html." rel="nofollow">http://www.movabletype.org/documentation/developer/template-tag-handler.html.</a> It gets its config from 'config_settings' in the config.yaml. </p>

<p>Your procedure configures settings in 'settings' rather than 'config_settings'. It isn't obvious - without deeper knowledge - what to change to get both to work.</p>

<p>Is there a way to reference 'settings' from the ctx parameter passed to the tag subroutine, or does it need to work with...</p>

<p><br />
   my $plugin = MT->component("MyPlugin"); <br />
   # etc.<br />
</p>

<p>...instead?</p>]]>
    </content>
    <published>2008-11-11T12:31:06Z</published>
  </entry>

  <entry>
    <id>tag:forums.movabletype.org,2008://24.10562-comment:14300</id>
    <thr:in-reply-to ref="tag:forums.movabletype.org,2008://24.10562" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html"/>
    <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html#c14300" />
    <title>Comment from Mike T on 2008-11-11</title>
    <author>
        <name>Mike T</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Try $ctx->stash('blog_id') where $ctx is a MT::Template::Context object in your tag code to get the current blog id number.</p>]]>
    </content>
    <published>2008-11-11T12:54:12Z</published>
  </entry>

  <entry>
    <id>tag:forums.movabletype.org,2008://24.10562-comment:14302</id>
    <thr:in-reply-to ref="tag:forums.movabletype.org,2008://24.10562" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html"/>
    <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html#c14302" />
    <title>Comment from Rob Staveley on 2008-11-11</title>
    <author>
        <name>Rob Staveley</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Beware, there's a typo in this:</p>

<p>my $my_setting = $plugin->get_config_hash('my_setting','system');</p>

<p>Should be: get_config_value. [Use get_config_hash to get the hash.]<br />
</p>]]>
    </content>
    <published>2008-11-11T12:57:12Z</published>
  </entry>

  <entry>
    <id>tag:forums.movabletype.org,2008://24.10562-comment:14304</id>
    <thr:in-reply-to ref="tag:forums.movabletype.org,2008://24.10562" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html"/>
    <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html#c14304" />
    <title>Comment from Rob Staveley on 2008-11-11</title>
    <author>
        <name>Rob Staveley</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>For what it's worth, I've got my tag working thus:</p>

<pre>
sub tag {
        my ($ctx, $args) = @_;
        #my $cfg = $ctx->{config};
        my $plugin = MT->component("MyPlugin");
        my $cfg = $plugin->get_config_hash('system');
        my $system_setting = $cfg->{'my_system_setting'};
        my $scope = "blog:" . $ctx->stash('blog_id');
        $cfg = $plugin->get_config_hash($scope);
        my $blog_setting = $cfg->{'my_blog_setting'};
        return '';
}
</pre>

<p>It does however look a lot more bloated than simply using $ctx->{config}. </p>

<p>I promise I'll stop bombarding you with comments now! :-)</p>]]>
    </content>
    <published>2008-11-11T13:03:40Z</published>
  </entry>

  <entry>
    <id>tag:forums.movabletype.org,2008://24.10562-comment:15219</id>
    <thr:in-reply-to ref="tag:forums.movabletype.org,2008://24.10562" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html"/>
    <link rel="alternate" type="text/html" href="http://forums.movabletype.org/2008/11/howto-define-custom-plugin-settings.html#c15219" />
    <title>Comment from Richard Benson on 2008-12-12</title>
    <author>
        <name>Richard Benson</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>As asked elsewhere, how do I access config variables in tmpl files for the plugin?</p>

<p>Using tags breaks the page and using mt:var just outputs blank.</p>]]>
    </content>
    <published>2008-12-12T09:56:05Z</published>
  </entry>

</feed>

