• log out

Config

Qbix uses JSON for its config system. The config file for your app is APP_DIR/config/app.json.

Each config field is namespaced by the module that introduced that particular config field. For example, the Q/app config field stores your app's name, such as "First". Meanwhile, your app might store the maximum number of widgets under First/widgets/max.

After loading your app's general config file, Qbix loads the APP_DIR/local/app.json file. We will make use of this later in the guide.

At Run-Time

You can access the config fields dynamically from your code. To get the foo/bar config field, you would do:

$value = Q_Config::get('foo', 'bar', $default)

If the field was not defined in the config (not even null), then the $default would be returned. If you expect the field to be there, you should instead write:

$value = Q_Config::expect('foo', 'bar')

and an exeption would be thrown if the field was undefined.

It can be useful to store string literals and other such things in custom JSON files, and load them into the config like this:

Q_Config::load("config/First/themes.json")

To set the value of the foo/bar config field, for some reason, you would write:

Q_Config::set('foo', 'bar', $value)

At Bootstrap Time

Qbix loads config files in the following order:

  1. Q_DIR/config/Q.json — default Qbix settings
  2. Then, Qbix merges your app's config and local config (see next two items), and looks at the Q/Q/plugins array. It loads PLUGIN_DIR/config/plugin.json for every plugin named there.
  3. APP_DIR/config/app.json — your app's config
  4. APP_DIR/local/app.json — specific to local machine
  5. Finally, Qbix loads any config files that were named in the Q/configFiles config field.

Notice that Qbix never scans any directories for config files. This is for efficiency reasons: searching directories on every request is slow.

When a config file is loaded, its contents are merged over the previously loaded config. For example, if the previously loaded config was:

{
  "a": "something",
  "b": "something too",
  "c": { 
    "k1": 1, 
    "k2": 2 
  },
  "d": { 
    "k1": { "associative": "array" }, 
    "k2": ["a", "b", "c"],
	"k3": ["a", "b", "c"]
  }
}

and we loaded the following config file:

{
  "a": "something else",
  "c": { 
    "k1": "replaces 1", 
    "k3": "new value",
  },
  "d": { 
    "k1": "just a string", 
    "k2": ["a", "b", "z"] ,
	"k3": {"replace": ["a", "b"]}
  }
}

then the resulting config would be:

{
  "a": "something else",
  "b": "something too",
  "c": { 
    "k1": "replaces 1", 
    "k2": 2,
    "k3": "new value",
  },
  "d": { 
    "k1": "just a string", 
    "k2": ["a", "b", "c", "a", "b", "z"],
	"k3": ["a", "b"]
  }
}

In short, scalar values replace whatever is there, associative arrays merge over it (on all levels), and regular arrays append to it.

Why JSON?

Qbix is designed to be very efficient and work with built-in PHP functions. The format for config files was chosen to be safe (no executable code), able to represent an arbitrary hierarchy of data, readable by humans, and natively parsed by PHP. That ruled out other possible formats such as YAML. Also, since JSON is already being used to communicate with Javascript in other parts of Qbix, it made sense to keep the number of languages you have to know down to a minimum: PHP and Javascript.

Qbix does take the time to strip /* comments of this form */ from JSON files that it loads, so developers can add comments to their JSON.

You can, of course, use another format for config files if you wish. One of the ways Qbix extends itself is with event hooks. All you have to do is add a hook before the "Q/tree/load" event, but you'll have to read about events first.

Node.js

The config is also loaded during Qbix bootstrap in Node.js, and can be accessed using

Q.Config.set(['foo', 'bar'], value);
value = Q.Config.get(['foo', 'bar'], defaultVal);
value = Q.Config.expect(['foo', 'bar']);