Config in Code (CINC) is intended to make it quick and easy to create Drupal configuration in code.

Using CINC in your modules

CINC is typically called in hook_enable(). Here's an example of what that looks like:

<?php
function example_enable() {
  // Create a field
  $example_field = CINC::init('TextField')
    ->set('field_name', 'field_example_field')
    ->set_instance('label', 'Example Field')
    ->create();
  // Create a content type with a field.
  CINC::init('ContentType')
    ->set('type', 'example') // Display name is (optionally) auto-generated from type.
    ->set('title_label', 'Example Title')
    ->create()
    ->add_field($example_field);
?>

Note that the content type object in this example did not need to be assigned to a variable at all, because it is not used beyond the initial chain of functions. The field was assigned to $example_field only so that could be passed to the ->add_field() function.

It is recommended, but not required, to add configuration on hook_enable() rather than hook_install() (and remove configuration on hook_disable() rather than hook_uninstall()) to simplify testing for developers (e.g. drush dis example -y && drush en example -y) and keep a clear relationship between modules and configuration for site builders.

Figuring out what to add

If you're not sure what to change on a given configuration, you should start by reading the empty class. For example, if you're creating a content type, you can do something like this to see what a content type object looks like:

  $test = CINC::init('ContentType');
  dpm($test);

If the output from that is clear enough, you can just edit the object with ->set() and call ->create() to create it. If that's not clear enough you can also make your changes in the UI and then ->read() them to see what the code should look like. You might also open an issue explaining what could be clearer. One of the main goals of CINC is to make configuration possible entirely outside the UI.

Adding CINC integration

CINC is all object-oriented, so adding CINC integration for a given configuration type involves creating a class with some specific properties:

  • The class name should begin with "CINC_" followed by the given configuration type name. For example, the field configuration is CINC_Field, and the content type configuration is CINC_ContentType.
  • The class should be added to a module's .info file.
  • The class should have extends CINC implements CINC_CRUD. CINC provides the standard ->set() functionality, while CINC_CRUD requires each class to implement ->create(), ->read(), ->update(), and ->delete() classes.

Beyond those 4 functions, you should also create a __construct() function that calls $this->set() to set your default values. You should at least set empty values for everything so someone could inspect a new object of your class to see what they need to fill in.

Config filters

CINC classes might want to respond to setting specific config values and either take actions or change those values as they're being set. $this->config_filters is an array of value names and functions that will be called when those values are set. The functions take a single parameter, the value being set, and return that same value, after making whatever changes are needed. For example, many CINC classes will auto-set display names based on machine names using config filters.

Return $this

Nearly all CINC functions should return $this to allow chaining. The only exception to this is functions that exist specifically to read and return other data.

Syntactic sugar

While every CINC class have a basic config array that can be altered with ->set(), it is often better to have simpler functions to set the same values. For example, CINC_TermReference has an ->allow_vocab() function that simply sets values in $this->config['settings']['allowed_values']. These "syntactic sugar" functions are encouraged in CINC classes, as they make configuration code easier to read and write.