Click or drag to resize
AlchemyCustom Configuration Settings

This topic contains the following sections:

Similar to custom configuration on good old fashioned GUI Extensions, Alchemy4Tridion allows your plugin to have its own custom configuration elements via the <settings /> element in the a4t.xml file of your plugin package (if this file is not present in the NuGet package you selected to build your plugin with, it'll automatically be created as soon as you build the project).

Adding Custom Configuration to the a4t.xml File

To add custom configuration for your plugin, you can include a <settings /> element inside of your a4t.xml file. Within this element you can have any structure of Xml that you wish, with the exception of <client /> and <encrypt /> which are reserved for special meaning (see below). At its simplest form, each Xml Element's name represents the key to a setting, and the text within the element represents that setting's value.

Basic Usage
<plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.alchemywebstore.com/">
  <name>YourPluginName</name>
  <settings>
    <SomeKey>Some Value</SomeKey>
    <SomeRandomNumber>42</SomeRandomNumber>
    <IsABoolean>true</IsABoolean>
  </settings>
</plugin>
Basic Retrieval of Settings

The plugin instance has a Settings property which is a getter that returns a new instance of IPluginSettings. It's important to note that the IPluginSettings is not cached and will return a new instance every time you call the plugin's Settings property. If you are making a lot of calls to the Settings, it would be wise to store the instance in a local variable as you work with it.

Once you have the settings instance, you can use the various Get methods to get values from your custom xml configuration.

If accessing the settings from an AlchemyApiController, you can use the controller's Plugin property to get the settings.

C#
[HttpGet]
[Route("example/action")]
public void ExampleAction()
{
    IPluginSettings settings = Plugin.Settings;

    string someKey = settings.Get("SomeKey");
    int someRandomNumber = settings.Get<int>("SomeRandomNumber");
    bool isABoolean = settings.Get<bool>("IsABoolean");
    string nope = settings.Get("DoesNotExist"); // value is null since our custom configuration above does not contain this key
    string defaultValue = settings.Get("DoesNotExist", "ADefaultValue"); // value is now "ADefaultValue" as we provided 2nd argument
}
Nested Settings

As the custom configuration settings allow for nested elements, you can use the GetNestedSettings method to return an instance of IPluginSettings that represents the layer of nested elements.

C#
IPluginSettings nestedSettings = settings.GetNestedSettings("SomeKey");
string someKey = nestedSettings.Get("SomeNestedKey");
int someInt = nestedSettings.Get<int>("SomeNestedInt");
int notFoundInt = nestedSettings.Get<int>("DoesNotExist"); // will be default 0 as this is default for int
int defaultInt = nestedSettings.Get<int>("DoesNotExist", 100); // will be 100 as we provided a default value
<settings>
  <SomeKey>
    <SomeNestedKey>SomeNestedValue</SomeNestedKey>
    <SomeNestedInt>42</SomeNestedInt>
  </SomeKey>
<settings>
Deserialization of Settings

Using the Get's generic method, we also use it to deserialize the settings into a strongly typed object.

Note Note

Settings deserializtion uses Microsoft's Xml Serialization by default. You will need to follow naming conventions as they apply to the serialization rules. You can also use Attributes as well to further control how your xml will be deserialized.

C#
// your class that you will deserialize as
public class MyPluginSettings
{
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsAlchemyLover { get; set; }
}
<settings>
    <Name>Alchemy Dude</Name>
    <Age>70</Age>
    <IsAlchemyLover>true</IsAlchemyLover>
<settings>

Deserializing Entire Settings

You can use the zero argument Get method to deserialize the entire settings as a strongly typed object.

C#
MyPluginSettings settings = Plugin.Settings.Get<MyPluginSettings>();

Deserializing Nested Settings

You may have a configuration setup where you only need to deserialize a nested section of your settings. In this example, we have our MyPluginSettings representing a nested section of our settings.

C#
MyPluginSettings settings = Plugin.Settings.Get<MyPluginSettings>("MyUser");
MyPluginSettings nope = Plugin.Settings.Get<MyPluginSettings>("DoesNotExist"); // will be null as 'DoesNotExist' does not exist.
<settings>
  <SomeKey>SomeValue</SomeKey>
  <MyUser>
    <Name>Alchemy Dude</Name>
    <Age>70</Age>
    <IsAlchemyLover>true</IsAlchemyLover>
  </MyUser>
<settings>
Note Note

You probably noticed that we used <MyUser /> as our element root name rather than <MyPluginSettings /> as the Xml Serializer would expect by default out of the box. This is because the Alchemy API automatically changes the element name and adds appropriate namespaces behind the scenes for you prior to performing deserialization.

Client Settings

So far in our custom configuration settings we've had what are considered to be server side config values. But what if we want settings that can be read easily from the client side as well? Alchemy4Tridion provides a JS proxy that will grab settings that are considered to be "client" settings.

Basic Usage
<plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.alchemywebstore.com/" xmlns:c="http://www.alchemywebstore.com/configuration/definitions">
 <name>YourPluginName</name>
  <settings>
    <SomeServerKey>Some Server Value</SomeServerKey>
    <SomeClientKey client="true">Some Client Value</SomeClientKey>
    <client>
      <SomeKey>Some Value</SomeKey>
      <SomeRandomNumber>42</SomeRandomNumber>
      <IsABoolean c:type="bool">true</IsABoolean>
    </client>
  </settings>
</plugin>

The above example shows two ways of enabling a custom configuration element to be able to be read by the client API. The first is by adding the attribute "client" to any element with a value of "true". The second is by using the special <client /> element. The "client" element itself is not considered to be a "key", but rather any child elements within it act as if they have the client="true" attribute.

To be able to grab the client configuration from your plugin's JavaScript, you'll have to add the call to AddWebApiProxy from your ResourceGroup's constructor. If you've already read / developed with Alchemy's API Controllers, you'll notice that this method also is responsible for generating the JavaScript proxy to communicate with your controllers.

C#
public class MyResourceGroup : ResourceGroup
{
    public ServicerCommandFilesGroup()
        : base("CommandFiles")
    {
        AddWebApiProxy();
        AddFile("SomeCommand.js");
    }
}

This will allow you to make the following call in your JavaScript:

JavaScript
Alchemy.Plugins.MyPluginName.Api.getSettings()
    .success(function (settings) {
        console.log(settings.SomeServerKey);
        console.log(settings.IsABoolean);
    })
    .error(function (error) {

    });
Tip Tip

It's important to note that when settings are returned like this, the keys are case sensitive and will match the casing of your element names. Also the values will all be strings. If you wish to have more control over the value types, please refer to the section on strongly typed client settings.

Tip Tip

Client settings are not ignored when getting settings with IPluginSettings. The flag is only used when grabbing settings via the client API.

Strongly Typed Client Settings

In the previous example, all values were returned as string types. Alchemy4Tridion allows you to configure your plugin so that it provides a strongly typed client settings object.

C#
public class MyClientSettings
{
    public string SomeClientKey { get; set; }
    public string SomeKey { get; set; }
    public int SomeRandomNumber { get; set; }
    public bool IsABoolean { get; set; }
}

To enable the deserialization of this type, in your plugin's Configure method you can include the type.

C#
public override void Configure(IPluginServiceLocator services)
{
    services.SettingsDeserialization.ClientSettingsType = typeof(MyClientSettings);
}

Using the getSettings() client call in this way will return the values as their JSON equivalent types.

Encrypted Settings

There may be instances where you want to encrypt the values of a particular setting, such as for passwords that you may have users store. You can do this by providing either a encrypt="true" attribute on the element setting you wish to encrypt, or by adding the settings in the <encrypt /> special element.

<settings>
  <NonEncryptedKey>SomeValue</SomeKey>
  <SomeEncryptedKey encrypt="true">Some Encrypted Value</SomeEncryptedValue>
  <encrypt>
    <AlsoEncrypted>Another Encrypted Value</AlsoEncrypted>
  </encrypt>
<settings>

Providing an Encryption Key

Plugins use a default encryption key to encrypt the settings with. For extra security, you can provide a custom key via your plugin's Configure method.

C#
public override void Configure(IPluginServiceLocator services)
{
    services.SettingsEncryptor.EncryptionKey = "SomeSecretEncryptionKey";
}

Decrypting Values

Using the Get methods by default will return the encrypted values. To retrieve your decrypted settings, you will have to call the Decrypt(String) method on your Settings instance.

C#
string value = settings.Get("SomeEncryptedKey"); // wrong, will return the encrypted string

settings.Decrypt("SomeSecretEncryptionKey");
value = settings.Get("SomeEncryptedKey"); // will now return 'Some Encrypted Value'

If you did not supply your own encryption key, you can just call Decrypt without any parameters.

C#
settings.Decrypt();
value = settings.Get("SomeEncryptedKey");
Custom Settings UI

Custom settings can be configured from the Plugins area of the A4T setcion of the user interface. Each installed plugin can be viewed and configured.

See Also