Countly Documentation

Countly Resources

Here you'll find comprehensive guides to help you start working with Countly as quickly as possible.

Shared configurations

If you need some specific configurations to be saved for your plugin, that you would need on each request (and maybe even want to allow user to change the configuration value), then you can use shared document to store your configuration.

Since shared configurations are stored in database, they will be shared between both api and frontend sides, as well as between multiple processes on different cpu cores and between multiple server instances.

Setting up configurations

Starting using shared documents is easy, all you need to call is plugins.setConfigs method and pass your plugin namespace and default values for your configurations.

If you're planning to use shared configuration feature, please do not use "-" in your plugin namespace.

var plugins = require('../plugins/pluginManager.js');

plugins.setConfigs("ourplugin", {
    config1: "value1",
    config2: false,
    config3: 120
});

You should do it as soon as possible (preferably right after you required plugins manager). And you can use it either on api side or on frontend side (configs will be stored in database and shared between processes either way, so it does not matter on which side you set them up).

By default all configurations will be viewable and changeable in Web UI for configurations. If you want your configurations to be excluded from Web UI, then provide third parameter true .

plugins.setConfigs("ourplugin_hidden", {
    config1: "value1",
    config2: false,
    config3: 120
}, true);

You can use multiple namespaces for your plugin, just make sure it does not collide with other plugin namespaces, so at least try to prefix them with your plugin name.
That being said, only your plugin namespace will appear on Configurations UI, all other will be hidden from it and are made for internal use.

Getting configuration values

Since the configuration values might change (either by user in config UI, or simply changes by other server instances), it is NOT recommended to load your configs once and then use them.

It is better to load your configs on per request bases (as they are guarantee not to change during same request, but might change between different requests), or even better simply load them on per need basis, using getConfig method and providing your namespace.

In rare cases when configurations cannot be loaded, getConfig method is guaranteed to at least provide empty object, so you can easily fallback to default values.

var somevalue = plugins.getConfig("ourplugin").config1 || default_value;

Updating configurations

If for some reason you need to update configuration, you can add it to setConfigs method on next process start and it will take new values that don't exist in old configuration.

But what if you don't want to wait till next process start, like your are storing different properties for different apps, and now new app was added and you want to update configs to add new app properties. You can also update configs directly using updateConfigs method, where you need to pass db object, your namespace and new properties to add.

//for example we have an object as
plugins.setConfigs("ourplugin", {
  ob1:{
    subob1:{
      prop1:"value1"
    }
  }
};

//if we want to add prop2 to subob1, then we update configs like this
plugins.updateConfigs(common.db, "ourplugin", {ob1:{subob1:{prop2:"value2"}}}, function(){
  //config updated
  console.log("done");
});

After that config will be updated and new values available on next request.

Web UI for configurations

Plugin manager also automatically generates UI (if configuration is not excluded) to allow global administrator to change your provided configurations. It will check your data type and will provide switches for boolean values, HTML5 number input for numbers and text input for text values.

If you can not see your plugin configuration here, please make sure you set the key name as same as plugin name ‚Äčand enabled the plugin.

Customizing Web UI inputs

But you can also hide specific configuration keys or provide custom input types for your plugin's configuration options.

You can do that by using registerInput function of configurationView once document is loaded. You need to provide "path" (separated by dashes) to your configuration value and either return null to hide the value or return HTML code to replace the standard input with.

So if you set such configuration for example:

plugins.setConfigs("ourplugin", {
  	subobject:{
      subproperty:10
    },
    config1: "value1",
    config2: false,
    config3: 120
});

Then to hide subobject's subproperty from input you would need to register such function:

$( document ).ready(function() {
  //check if configuration view exists
  if(app.configurationsView){
    app.configurationsView.registerInput("ourplugin-subobject-subproperty", function(value){
      //no html for this input, will hide it
			return null;
		});
  }
});

But to override default text input for config1, you would need to firstly provide HTML code for your custom input (of course you can also style it as you want)

$( document ).ready(function() {
  //check if configuration view exists
  if(app.configurationsView){
    app.configurationsView.registerInput("ourplugin-config1", function(value){
      //return HTML code to textarea
			return "<textarea id='ourplugin-config1' class='mytextarestyle'>"+value+"</textarea>";
		});
  }
});

As well as then handle it's value changes and set them to configurations view's updateConfig method

app.addPageScript("/manage/configurations", function(){
   if(app.configurationsView){
     	$("#ourplugin-config1").keyup(function () {
        //value might have changed
     		var id = $(this).attr("id");
      	var value = $(this).val();
        //let's notify configuration view about possible changes
				app.configurationsView.updateConfig(id, value);
			});
   }
});

Customizing Web UI labels

Similar way as inputs, you can also provide custom HTML for labels, including translating them in current language and providing help tooltips, etc.

To overwrite default label name, simply use registerLabel method of configurationView and pass label id and html code to replace it with.

$( document ).ready(function() {
  //check if configuration view exists
  if(app.configurationsView){
    app.configurationsView.registerLabel("ourplugin-subobject-subproperty", 
        "<span class='help-zone-vs' data-help-localize='ourplugin.help.subproperty'>Subproperty</span>");
  }
});

Plugin specific configuration page

If you want to provide edit settings button on your plugin's view and direct user to your plugin specific configuration page (with options only for your specific plugin's namespace), then you can point that button to "#/manage/configurations/namespace" (of course, replacing namespace with your configs namespace).

And user will be redirected to the page with configs only from that namespace, and would be allowed to change them and also provided a back button to return back to your plugin's view.

Notice

When your plugin has some configuration in UI, please avoid using plugin name contains "-"(like "*countly-aws-kinesis"). Which may cause not show the configuration form in the UI.

Shared configurations