I am trying to develop a module extension which needs to store some settings, I went through the documentation and found this to be the way to create settings.

Now when I put default as NULL the setting is not reflected in the table, if I put any value as default the setting is added to civicrm_setting table.

Also, though the settings have option to specify attributes for admin form, I couldn't figure out a way to present a new settings form for my module.

Is there anything else which I need to do apart from adding the setting folder and the following code to extension.php

function multisite_civicrm_alterSettingsFolders(&$metaDataFolders = NULL){
  • Hi Siddharth! I'm not sure whether you're asking how to add new fields to an existing form, or to add a new settings page to the admin menu. Can you rephrase your question for clarity? Perhaps some existing extensions might provide an example for what you're after? Jun 23, 2015 at 0:45
  • I am looking for adding a new settings page in the admin menu. Just like there is for CiviEvent, etc. Jun 23, 2015 at 7:17

4 Answers 4


You'll want to start with the civix generate:form command. Alter the generated code to have your form class extend CRM_Admin_Form_Setting instead of CRM_Core_Form and then follow the example of other such forms by declaring the settings that form is supposed to manage.

You may also wish to insert a link to this form into the navigation menu.

  • I have added the settings using a normal form, what are the major differences? Jun 28, 2015 at 7:45
  • 1
    Using CRM_Admin_Form_Setting as a base class will require less code - it will automatically add your setting fields to the form, and automatically store them upon form submission.
    – Coleman
    Jun 28, 2015 at 13:51

This took me way longer than I anticipated, so I thought I'd pen a fuller answer for the most minimal settings form. It assumes you're building a modern extension, generated with civix.

Step 1: define your settings

Create a settings dir in your extension's base directory, and within that create a whateveryouwant.setting.php. Gotcha 1 is that while the directory is called settings this file must be use the singlular "setting" or it won't get picked up. But, yes, it can have multiple settings in it.

That file contains a return [ 'favourite_fruit' => [...], 'your_other_setting' => [...], ... ]; statement - see the docs

Gotcha 2: these *.setting.php files seem to be only sourced as part of a cache clear. i.e. I learnt that using the "Flush Caches" button (or running via cv api system.flush) not only flushes the caches, but also recreates some of them. This is different to Drupal, for instance.

Step 2: create a form for it

As Coleman suggests:

civix generate:form Settings civicrm/path/to/your/form

Note that the use of Settings as the form class name is up to you.

Then edit the CRM/YourMod/Form/Settings.php file. You can strip this right down to just

class CRM_YourMod_Form_Settings extends CRM_Admin_Form_Setting
   protected $_settings = [
     'favourite_fruit' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
   public function buildQuickForm() {
     $this->assign('elementNames', array_keys($this->_settings));

The $_settings array is keyed by the names you define in your *.setting.php. In the buildQuickForm() function we just call the one we inherited, but then assign all our settings to the elementNames array, because the default form created by civix loops this array to output the elements; if you don't set this your form is empty.

You can then alter it as you need to, but thought it would be useful to have this minimal example posted, hope it helps a googler (or a duckduckgo-er).

For completeness' sake (as I use this as a reference myself!), in code you can access settings with:

$fruit = Civi::settings()->get('favourite_fruit');

And, should you need to

$fruit = Civi::settings()->set('favourite_fruit', 'lychee');
  • Thanks for posting this detailed answered. I really appreciate it.
    – Sleewok
    Jul 12, 2018 at 15:20
  • I'm having issues with the protected $_settings = [ 'yourmod_your_setting_name' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, ]; This is not retrieving my setting information. Any ideas?
    – Sleewok
    Jul 12, 2018 at 19:49
  • Just to clarify. SYSTEM_PREFERENCES_NAME is set to a constant value, this results in my settings value being set to ""CiviCRM Preferences""
    – Sleewok
    Jul 12, 2018 at 20:04
  • That's the group name for the setting. The default form values should be loaded from your database by CRM_Admin_Form_Setting::setDefaultValues() which used to use the API to call setting.getvalue with the group set to the SYSTEM_PREFERENCES_NAME and the name set to your $_settings key. As of writing that code now uses a different internal process to do the same thing. Are you sure you're extending CRM_Admin_Form_Setting? Jul 16, 2018 at 8:23
  • 1
    And you have a something.setting.php file defining the fields? example Jul 19, 2018 at 7:56

If your work is targeting versions 4.7+, you may not need to create a form like Coleman suggests. Check out the work done to overhaul the CiviCRM settings administration - it's referred to in this post as "Administer Settings improvements", and a team developed it during the Colorado sprint. You may want to ask a core team member the status of that work.

  • The link is dead. May 24, 2016 at 7:01
  • @DilipRajBaral That's fine - this work is also dead and unfinished. There was some recent discussion on finishing it, but it's not going anywhere at the moment. May 24, 2016 at 23:15

I use Civi::settings()->set and Civi::settings()->get to create and retrieve CiviCRM settings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.