Proposal

I propose a hook_configuration() API.

For a while now, Drupal has had a hook_install and a hook_uninstall for it's contrib modules. These two hooks allow us to bolt additional code onto the core framework to do almost anything we want. Anything, that is, except define a standard way of coding the configuration options available to a single module. That can change.

There's been a lot of talk at Drupalcon Boston 2008 regarding an idea that modules should be able to access a standardized array of config options that are typically provided to a Site Admin via the admin/build/* or admin/configure/* pages. If contrib modules could have an API and a preset array of arrays that they could use to specify anything from "Should this node that's made by my module be automatically promoted to the front page or not?", and "Should comments be enabled or disabled for this forum post?", and even "If my module wants to make a content type with a $title, $body, and a single additional CCK text field, can I turn off the log_message box (revisions) for these? I'm the only one editing them, after all."

These "contrib config" settings should be sensible defaults, but offer the Site Admins an ability to override or change a module's settings at any point in the post-installation future. There may be a situation where this is unacceptable because it might kill the site, so that has to be taken into account.

Basically, what we're attempting to do here is provide a supporting framework for the eventual Configuration Wizard or Package Manager type application to be used by a module during installation or re-enablement. Existing sites or sites being created by an experienced admin *might* want to shut this feature off, so the first version will need to incorporate either a per-user or a per-role "disable" feature. Of course the $uid->disable_auto_config = TRUE would be an opt-in, so that brand new users and freshly downloaded core packages would offer the automated assistance by default.

How It Should Look

If we give each module a .conf file with a hook_configuration function that houses an array of arrays full of settings for every content type, block, or other (stuff that relates to dependent modules), this is what it might look like:

<?php
function hook_install() {
  db_install_schema();
}
function hook_configuration () {
  $module_config = array[];
  // The API should be able to handle the case of which nodes were created by
  //    this module's hook_node_info, and also the block>deltas, right?
  $module_config['modulename']['node_options'] = array(
        // Default Options
        'published' => TRUE,
        'promoted' => FALSE,
        'sticky' => TRUE,
        'revisions' => FALSE,
        // Multilingual Support (check to see if locale.module is on.)
        'multilingual' => 2, // Enabled with translation.
        // Attachments (check to see if upload.module is on.)
        'attachments' => FALSE,
        // Comment Settings (check to see if comment.module is on.)
        'default_comments' => 2, // Read & Write.
        'default_display' => 1, // Flat list, expanded.
        'default_order' => 1, // Oldest first.
        'comments_per_page' => 28, // Can this be any integer under 300?
        'comment_controls' => 2, // display above and below the comments.
        'anon_users' => 2, // This must be checked against permissions table.
        'comment_subject' => 1, // Enabled.
        'preview_comment' => 0, // Optional.
        'form_location' => 1, // Display below posts and/or comments.
      );
    );

    $module_config['modulename']['block_options']['delta-id'] = array(
      'block_title' => 'string of text',
      'visibility_setings' => 2,
      'role-specific_visibility' => array('anonymous' => TRUE, 'authenticated' => FALSE), // If array is empty, block is shown to all roles. (core default)
      'page-specific_visibility' => array(),
      'preferred_region' => 'sidebar_left',
      'secondary_region' => 'content',
      'preferred _weight' => -6,
    );
}

    $module_config['variable_settings'] = array(
      // Make some standard settings using variable_get and variable_set,
      //    but check for user alterations and previous installations first.
      'og_default_theme' => 'minnelli-red',
      'some_node_setting' => TRUE,
      'views_executive_homepage' => 'this.tpl.php',
      /// And on and on for anything that inserts data into the variables table.
    );

?>

How It Should Work: The top three ideas.

Idea #1 is an auto_configure link next to each enabled contrib module's checkbox on the admin/build/modules page if that module supports hook_configuration(). If the link is clicked, the auto configuration hook is run.

This allows users a finite control over whether to allow that module to set itself up with it's own sensible defaults, or whether not to. The choice is yours, even when turning on and off a module multiple times during a site build. It also takes into account the fact that a certain user may in fact be a pro with $disable_auto_config turned off, but for this one unfamiliar module and just this one time, they want to see what it does and try it out.

Idea #2 (by DmitriG) is a series of additional steps after the admin/build/modules form is submitted. This idea allows for stuff like module dependencies, and in a very sleek manner too. After the form is submitted and the dependencies are checked, the extra steps of configuration are presented to the user, but only if the module has implemented a hook_configuration, the defaults specified are not the same as what exists in the database already (which would indicate that the module has simply been re-enabled), and the user has not opted out of $disable_auto_config.

Idea #3 (by cwgordon) is to intercept the modules admin form, and form_alter something in there that would trigger a configuration wizard if the module supported it, and if it needed to run, and if the $user->uid hadn't opted out of the configuration wizardry. This is a more fluid, seamless way to handle the auto-setting of certain things in the background without any needed user interaction. Unless a conflict is encountered and user input is needed, the process would be imperceptible, as if the module maintainer had taken the time to simple code all this stuff line by line.

There will be a working model of this idea's implementation posted "very soon". [UPDATE] The first version of this idea has been posted to the Awesome Install project as a theoretical example.

I will also be adding a couple of use cases as followup comments. Posibly even by the end of this week. Maybe.

Comments

jbrauer’s picture

We should keep an eye on how this could relate to the SoC proposal (and likely project that Dmitri is mentoring) around a help system. Especially a system that would allow a calling site to override the source for help files so that a site- or industry-specific help system could provide specialized configuration that goes beyond the general how-to and options for the module being installed but could also make suggestions for how that specific site may want to configure the options for that module...

Morbus Iff’s picture

I haven't thought this through, and I know little about the existing profile system but: could one bootstrap this off the existing profile system? Could there be "module profiles", store in MODULENAME/profiles/?

metzlerd’s picture

I'd suggest the idea of having a messaging interface that would be used by admin for messages that need followup action. Not just a log, but something more persistent than set message. A light weight messaging interface for core. Markup only, no attachments, with a light api for sending admin messages upon install and upgrade.

Dave

David_Rothstein’s picture

Subscribe. Sounds like a great idea...

Wim Leers’s picture

Subscribing.

This should also support:
- import/export of configs
- grouping of configs, e.g. node settings, group settings, whatever settings
- integration with the deploy module

Senpai’s picture

Wim, yeah good point. Deploy.mod integration would be critical.

And another thing that this hook could do? If a module didn't comply with aggressive caching, and aggressive caching was turned on, the hook could warn the admin about that condition and either offer to turn off aggressive caching or re-disable the module.

alex_b’s picture

I'm exploring a related idea with the port module and I wonder how compatible we are.

Port module basically provides a hook that allows modules to declare export / import function pairs. This simple trick allows you to collect all export function results, var_export() them and "paste" them into another site. Or use them in an installer profile, or paste them into code for version control, etc.

This is a concept also present in deploy module and I'm in touch with heyrocker on how to merge efforts http://drupal.org/node/291921.

We're using port module internally mostly for generating installer profiles from sites we build: build site, export configuration. An installer profile should _theoretically_ be something that can be generated automatically. If we just new what' s structure and what's content in Drupal :)

Port module forces implementing modules to declare what's structure and what's content. So further down the line, it's perfectly possible that implementing modules declare structure 'ports' AND content 'ports'.

So here is my question: What's the idea with this proposal on how to handle configurations internally? I mean, from the declaration in .conf on: how does the configuration find it's way back into the module? How does it deal with configuration options that are not stored as Drupal variable?

Boris Mann’s picture

Echoing Morbus' comment, when dmitri and Adrian and I were discussing this, it's almost like having a recommending or mini "install profile" on a per module basis. The reasoning goes that the module author probably knows what a default, sane config should look like. Really, this is both what Dmitri and cwgordon suggested -- if there is a wizard, it runs, otherwise sane defaults get applied.

Making this per module would make install profiles easier, too -- the trouble I'm running into with crud.inc / install profile api is that once you start messing around with contrib, you've got this monster file filled with little functions. In my not working yet D6 port of install profile api, I'm messing around with a structure where includes for each module in the install profile are automatically included.

Rather than awesome install, maybe work on actual code for install profile API? Quicksketch is getting involved there, too.

alex_b: as I said before, what you're doing on the import side is essentially what the profile wizard does that is a sub module of install profile API. Especially if you're using my hackish crud.inc. Please check out what I have for D6 to see if it makes more sense: http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/install_pro...

alex_b’s picture

as I said before, what you're doing on the import side is essentially what the profile wizard does that is a sub module of install profile

True, with an important twist: it defines a very simple convention to define export/import pairs in modules: hook_port().

Having a convention in place makes the problem of exporting / importing configurations crowd sourceable. In many cases such an export/import definition is merely the matter of implementing very light wrappers, because modules do offer import and export of configs anyway - see

- imagecache http://cvs.drupal.org/viewvc.py/drupal/contributions/sandbox/alex_b/port...
- or nodeprofile http://cvs.drupal.org/viewvc.py/drupal/contributions/sandbox/alex_b/port...
- or module status http://cvs.drupal.org/viewvc.py/drupal/contributions/sandbox/alex_b/port...

In other cases like content_copy module it could encourage better programmatical import/export APIs - see

http://cvs.drupal.org/viewvc.py/drupal/contributions/sandbox/alex_b/port...

This is something that install profile wizard could build upon. I don't see this in install profile wizard atm though - am I missing something?

Boris Mann’s picture

I'm not saying install profile wizard does ANY of this.

My point being -- please consider taking over the functionality of install profile wizard with port itself, and depend on / help with the new install profile api "module" rather than copy / pasting crud.inc :P

If you see how I've started to try and structure install profile api for D6, it has an .inc file for each module...just like port. Let's figure out how to join forces.

alex_b’s picture

Let's figure out how to join forces.

Let's do that, definitely.

ChrisBryant’s picture

Subscribing....

alex_b’s picture

Please have a look at the proposal of port API here: http://groups.drupal.org/node/14395

port module might show a concrete way forward here.

Chris Charlton’s picture

subscribing.

JacobSingh’s picture

I've posted a little stop gap for D7 which allows maintainers to specify a message when a module is enabled, and shows a link to the help page if they have not.
IMO will solve a hige potion of this, although I also see the need for the excellent writeup Senpai provided above.

http://drupal.org/node/407022#comment-1375454

I'm all for what is written above, but seeing as that was a year ago, and I see about 10 amazing developers who are interested, but haven't found the time to deal with it ( and now one mediocre one is throwing his hat in the ring), I'm proposing a usability improvement which is simple to implement and can be a first step towards a decent module on-ramp experience.

1. A module owner can implement hook_configuration_info()

$basic_setup = array('link' => 'mymodule/setup', 'title' => 'Basic Setup Wizard', 'desc' => 'lorem ipssum');
$auto_setup = array('link' => 'mymodule/setup/auto', 'title' => 'Auto configure');
return array array($basic_setup, $auto_setup);

2. Upon enabling module(s), admin is presented with a "You are done" screen (unless you set some don't bug me switch) which shows a short description and the links to each of the setup routines for the modules they just enabled.

--------------
Foo
- Basic Setup
- Auto Setup
- Mark as configured

Bar
- Wizard Magic!
-------------------

3. From that point on, the un-configured modules go into a block which nags the admin and says:

You have 2 unconfigured modules:
* Foo
* Bar

Click here to configure them.

4. The link would take them to essentially the same page they saw when they finished enabling the modules.

5. The admin would be responsible for triggering a "module configured" action when the configuration was complete (any modules not implementing hook_configuration_info, would be marked configured as soon as they were installed.

This "configured" bit would be set in system as a new field. It could also accept 3 values if we want to get fancy (No, In progress, Yes).

How does that sound? It's simple, I can whack it out in a day, and I feel non-obtrusive and useful.

alex_b’s picture

At DrupalCon DC there was a BoF on change management (see minutes here http://groups.drupal.org/node/20063) that sparked some very interesting work with exporting configuration as 'features': There is a demo here http://groups.drupal.org/node/20119 and there is code here http://drupal.org/project/features

Features takes care of the problem that modules don't map cleanly to sections of your site - you usually would like to export not module configuration, but e. g. 'my events section' configuration.

Dries’s picture

I'm not sure I understand the different between 'basic setup' and 'auto setup'.

1) Most installers I know have only one setup.

2) Because there is a 'basic setup', it seems to imply that there might be an 'advanced setup' (third option) too?

I'm supportive of this idea, but I'd prefer to have one setup, and to give module maintainers the ability to have the one setup skip certain configuration steps when it makes sense to.

JacobSingh’s picture

Hi Alex,

I read all those links. The Features stuff is wicked!

While I think this is all relevant and cool, I'm really talking more about a very simple framework for module owners to build wizards for when their mod is enabled and a notification system for admins that there is configuration needed.

This isn't a change management issue really, it's a usability one and I don't think it is in any way contradictory to features (actually, might be used by features to prompt users for certain variables to use when that feature is turned on).

JacobSingh’s picture

Okay, agreed. So if we only allow one setup link it makes it easier to streamline as well.

ChrisBryant’s picture

We've been working on a similar concept with Patterns and the Configuration Framework. The idea that a module should be able to not only set it's default configuration, but also ship with supplementary optional configurations that extend the module's setup, setup a demo, or even setup other modules at the same time.

For instance, the blog module could have it's default configuration and also ship with a pattern that sets up little demo by enabling the blog menu item, moving it to the primary links menu, setting up a view for it including a block for an archive of posts and then putting that block into your left or right sidebar. It could also optionally enabled and setup the Blog Information and Blog Add-ons modules if you have those available.

The pattern(s) formats could be PHP arrays, XML or YAML.

The new Features module is really great, but in use cases like this it might not make sense to have a whole other module on your site just to setup or define some optional configuration or features that extend and existing module.

Anyways, +1 for the usability improvements around installing modules and helping users get them setup and configured.

sun.core’s picture

Version: 7.x-dev » 8.x-dev
mlncn’s picture

Issue tags: +SettingsAPI

Subscribe, general +1, and tagging SettingsAPI.

heyrocker’s picture

Status: Active » Closed (won't fix)

Given that all this functionality is essentially covered by the new configuration system, I am closing.

Senpai’s picture

Status: Closed (won't fix) » Postponed (maintainer needs more info)

Good call, @heyrocker, but one question about the new Configuration System. Will it be able to support the inclusion of a contrib module's desired "sensible default" configuration settings *before* the module is ever installed on a site? Cause that's what we're going for in this issue.

David_Rothstein’s picture

Title: Can we create a configuration hook for contrib modules? » Allow modules to provide optional configuration profiles (e.g., for use in a "setup wizard")
Status: Postponed (maintainer needs more info) » Active
Issue tags: +Needs issue summary update

This issue still looks relevant to me, but the title is a bit out of date. It also could probably do with an updated issue summary...

sun’s picture

Status: Active » Postponed (maintainer needs more info)
Issue tags: -configuration, -module install, -SettingsAPI +Configuration system

Will it be able to support the inclusion of a contrib module's desired "sensible default" configuration settings *before* the module is ever installed on a site?

I do not understand this question. Why would you want to have configuration for a module that is not installed?

In D8, each module ships with its own default configuration. The default configuration is installed when the module is installed.

An installation profile is able to override/replace the default configuration of a module at install time (only).

Does that answer the question?

Senpai’s picture

Issue summary: View changes

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.