Can we create a configuration hook for contrib modules?

Senpai - March 5, 2008 - 00:12
Project:Drupal
Version:7.x-dev
Component:install system
Category:feature request
Priority:normal
Assigned:Senpai
Status:active
Description

Proposal

I propose a hook_configuration() API.

For a while now, Drupal has had a hook_uninstall 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.

#1

JBrauer - April 11, 2008 - 19:39

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...

#2

Morbus Iff - April 11, 2008 - 21:19

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/?

#3

metzlerd - April 12, 2008 - 03:48

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

#4

David_Rothstein - May 23, 2008 - 05:36

Subscribe. Sounds like a great idea...

#5

Wim Leers - June 2, 2008 - 16:44

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

#6

Senpai - June 8, 2008 - 05:35

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.

#7

alex_b - August 9, 2008 - 15:45

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?

#8

Boris Mann - August 9, 2008 - 16:50

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...

#9

alex_b - August 9, 2008 - 17:47

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?

#10

Boris Mann - August 11, 2008 - 07:55

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.

#11

alex_b - August 11, 2008 - 12:42

Let's figure out how to join forces.

Let's do that, definitely.

 
 

Drupal is a registered trademark of Dries Buytaert.