
Installation profiles allow you to easily install Drupal with additional functionality included by default. For example, you can set up an installation profile to:
- Automatically add additional users to your site
- Add additional roles to your site
- Set up permissions for default users
- Add additional contributed modules to your site
- Add additional themes to your site
- Add default content to your site
- Modify common settings to speed setup
As you can see, the options for installation profiles are nearly limitless in Drupal 7. This is especially true because installation profiles are essentially modules now, and you can do nearly anything you want to with a custom module in an installation profile.
If you are only maintaining a single site, you probably won't want to create an installation profile, but if you are setting up many new customer sites each month, you should definitely consider building a custom installation profile to set up a base site that you can then extend to meet each customer's specific needs.
Let's start by looking at the files that make up an installation profile.
- The
.info
file: The.info
file names and describes the installation profile and gives compatibility information so the installer can verify that the correct minimum requirements for the profile have been met and set up the correct modules. - The
.profile
file: The.profile
file allows you to modify the site configuration form so you can request additional information from the user performing the installation or set default values for the installation. This file is specified within the.info
file. - The
.install
file: The.install
file contains the code that should be run to set up the new site after the core Drupal installation has completed.
Let's look at the contents of the .info
file. In this example, we will look at the default profile that ships with Drupal. Let's look at the entire file and then break down each section independently.
; $Id: default.info,v 1.8 2009/11/10 17:27:54 webchick Exp $ name = Drupal description = Create a Drupal site with the most commonly used features pre-installed. version = VERSION core = 7.x dependencies[] = block dependencies[] = color dependencies[] = comment dependencies[] = dashboard dependencies[] = help dependencies[] = image dependencies[] = menu dependencies[] = path dependencies[] = taxonomy dependencies[] = dblog dependencies[] = search dependencies[] = shortcut dependencies[] = toolbar dependencies[] = field_ui dependencies[] = file dependencies[] = rdf files[] = default.profile ; Information added by drupal.org packaging script on 2009-11-21 version = "7.x-dev" core = "7.x" project = "drupal" datestamp = "1258805146"
As you can see, the file uses a basic INI style format that provides information in a series of name-value pairs using the format:
name = value
Names that end with square brackets [] are treated as arrays when they are read. Any lines which start with a semi-colon are treated as comments and ignored when the file is read.
The first line in the file is used by the version control system to insert version information. If you create your own installation profile, you should replace this line with:
; $Id;
The next four lines identify the name of the profile, a description of the profile, the current version of the profile, and the version of core this profile is compatible with.
name = Drupal description = Create a Drupal site with the most commonly used features pre-installed. version = VERSION core = 7.x
You should modify at least the name and description values for your installation profile if you are building a custom installation profile.
The dependencies lines list all of the modules that must be enabled for the profile to install correctly. The Drupal installer will automatically enable these modules for you.
dependencies[] = block dependencies[] = color dependencies[] = comment dependencies[] = dashboard ...
You can add or remove any additional modules that you will need to use your installation profile. If you are using a third-party module, make sure that it has been deployed to your site before the installation profile has been run.
The files
variable defines any files that are needed to run the installation profile. Typically, this will just be your .profile
file. However, you may also include additional files if the setup you do is very complex. To include additional files, simply add another files[]
line with the name of the file you want to include, as shown below:
files[] = default.profile
The remainder of the file contains information included automatically by the Drupal packaging script. You do not need to add these to your file if you are building a custom installation profile.
The .profile
file allows you to alter the installation and change which forms are presented to the user.
The following hooks can be added to your .profile
file:
hook_profile_details
: This hook allows you to define a language that will be used during the installation. If a language is set here, the user will be unable to set the language during the installation. In Drupal 6, you would also define the name and description for the profile. You don't need to do that anymore since the name and description are provided in the.info
file. For more information on this hook see:http://api.drupal.org/api/function/example_profile_details/7.
hook_install_tasks
: This hook allows you to define additional tasks that will be performed at the end of the installation process. Each task will be executed in the order they are defined. A task can be one of three types:- normal: The function will be run and can return either HTML to be displayed to the user or nothing if processing should continue without further user interaction.
- form: The function will return a form definition using the standard Form API. The installer will present the form to the user and then submit the form to the function you define for processing.
- batch: The function will return a batch definition, which will be run by the installer. For more information about batches, see:
http://api.drupal.org/api/function/batch_set/7.
For complete documentation on this hook see:
hook_install_tasks_alter
: This hook allows you to change, replace, or remove tasks that are to be run by the installation process. You can modify any of the tasks that will be run from the time the installation profile is selected until the installation completes. This is especially useful if you want to override functionality provided by the core installer. For more information on this hook, see:http://api.drupal.org/api/function/hook_install_tasks_alter/7.
hook_form_alter
: This hook allows you to modify a form before it is displayed. This allows you to add or remove elements from the form or modify existing elements within the form.hook_form_alter
is widely used within Drupal to make modifications to forms. For complete documentation, visit:
As with any Drupal hook, you will need to replace the word "hook" with the name of your profile so Drupal can correctly find the function. Therefore, if your profile is named drupal_rocks
, your function that implements hook_profile_details
should be named drupal_rocks_profile_details
.
The .install
file is where you will perform most of your configuration and setup work after the installation has completed.
You only need to implement one function in this file, hook_install
. If you have created custom modules, this is the same function that runs when the module is installed. Complete instructions for hook_install
are available at:
http://api.drupal.org/api/function/hook_install/7.
Let's look at the standard.install
file provided with Drupal to get an idea of what is possible. Rather than looking at the entire file at once, let's break it into sections. If you want to see the entire file, it is located in the profiles/standard
directory of your Drupal installation.
The basic structure of the file looks like the following:
<?php // $Id: default.install,v 1.18 2009/11/10 17:27:54 webchick Exp $ /** * Implement hook_install(). * * Perform actions to set up the site for this profile. */ function default_install() { //Actual work happens here! ... }
The file starts out with the opening PHP tag <?php
. Then, the Id
is again entered automatically by the version control system. If you are developing your own installation module, you should simply enter // $Id$
. Do not enter all the remaining information; that will be generated automatically. Next, the file has a comment (the information starting with /**
and ending with */
) stating what the function does. This is good coding practice and helps other people to understand what you are trying to do. It can also help you understand your own code if it's been a little while since you wrote it. You may even want to include a summary of what the installation will do, and why, to remind yourself after you have been away from the code for a while.
After the comment comes the actual implementation of hook_install
. Since this profile is named default, the function is called default_install
. The logic of the function is then included and the function ends with a closing curly bracket. By convention, Drupal files do not include the optional closing PHP tag after all functions have been written, so the file ends there.
Now, let's look at the actual logic being performed within the profile. The first section of code begins by defining several blocks which are then added to the default display.
// Enable some standard blocks. $values = array( array( 'module' => 'system', 'delta' => 'main', 'theme' => 'garland', 'status' => 1, 'weight' => 0, 'region' => 'content', 'pages' => '', 'cache' => -1, ), ... array( 'module' => 'user', 'delta' => 'new', 'theme' => 'seven', 'status' => 1, 'weight' => 0, 'region' => 'dashboard_sidebar', 'pages' => '', 'cache' => -1, ), ); $query = db_insert('block')->fields(array('module', 'delta', 'theme', 'status', 'weight', 'region', 'pages', 'cache')); foreach ($values as $record) { $query->values($record); } $query->execute();
Each block is loaded into the $values
array. Each module defines the name of the module, which defines the block as well as the delta or unique ID of the block within the module. The theme
setting controls which theme the block should be active for and the status
variable controls if the block is enabled (1) or disabled (2). The region
variable controls where the block should be displayed within the page and weight
controls the position within the region. The pages
setting controls which pages the block should be shown on. In the case of the default installation profile, they are shown on all pages. If you want to only show the block on some pages, you should also include the visibility
parameter. The cache
setting controls whether or not the block can be cached to optimize performance. By default, all blocks are set to -1, which means do not cache. You can change this to a variety of values for fine-grained caching control. For a complete list of fields that can be set for a block and their possible values, see:
http://api.drupal.org/api/function/block_schema/7.
The next several lines set up a query to insert the blocks into the database using the new DBTNG layer and then execute the query to save all of the new blocks. We will review the DBTNG layer more in Chapter 6, so don't worry about the actual syntax too much for now.
The next section adds some default node types that editors can use to add content to the site.
// Insert default user-defined node types into the database. For a complete // list of available node type attributes, refer to the node type API // documentation at: http://api.drupal.org/api/HEAD/function/hook_node_info. $types = array( array( 'type' => 'page', 'name' => st('Page'), 'base' => 'node_content', 'description' => st("Use <em>pages</em> for your static content, such as an 'About us' page."), 'custom' => 1, 'modified' => 1, 'locked' => 0, ), array( 'type' => 'article', 'name' => st('Article'), 'base' => 'node_content', 'description' => st('Use <em>articles</em> for time-specific content like news, press releases or blog posts.'), 'custom' => 1, 'modified' => 1, 'locked' => 0, ), ); foreach ($types as $type) { $type = node_type_set_defaults($type); node_type_save($type); }
In this case, two node types are being added—a page
node type and an article
node type. The installation profile defines the type
, name
, and description
for each node type. These are all fairly straightforward. However, note that the st()
function is called to provide translations rather than t()
. This is done because the install
function is called during the install process and the full localization system may not be available yet. The profile also sets the base for the node
type, which tells Drupal which module will control the functionality of the node. By setting custom
to 1, the installation profile instructs Drupal that this node type should be treated as if it were created by a user and that it is not defined by a module. Setting locked
to 0 indicates that the name of the content type can be modified by an administrator.
After basic information has been defined for each node type, the installation profile begins to save each type individually. Before saving the type, it calls node_type_set_defaults
, which builds a type object and adds additional default information to it. The new node type is then saved with a call to node_type_save
.
The installation profile then uses the same technique of defining an array of information and then saving it to build RDF-mapping information for each type as well as taxonomies and fields. Because these substantially use the same techniques as creating blocks and node types, we will omit a line by line discussion of these.
Between setting up the RDF mappings and creating taxonomies, the installation profile sets the values of some variables in the database using the following lines:
// Default page to not be promoted and have comments disabled. variable_set('node_options_page', array('status')); variable_set('comment_page', COMMENT_NODE_HIDDEN); // Don't display date and author information for page nodes by default. variable_set('node_submitted_page', FALSE); // Enable user picture support and set the default to a square thumbnail option. variable_set('user_pictures', '1'); variable_set('user_picture_dimensions', '1024x1024'); variable_set('user_picture_file_size', '800'); variable_set('user_picture_style', 'thumbnail');
All of these lines use the variable_set
function to change the value of the variables. You can get a list of all variables defined within Drupal using the Devel module (http://drupal.org/project/devel).
Skipping down to the end of the file after all of the fields have been created, the installation profile sets some default permissions for the Anonymous and Authenticated roles using a call to user_role_grant_permissions
.
// Enable default permissions for system roles. user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access content', 'use text format 1')); user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'post comments without approval', 'use text format 1'));
If you are creating your own installation profile, which activates additional modules, you may want to activate additional permissions for these users.
The installation profile also creates a new role for the administrator and sets some default permissions:
// Create a default role for site administrators, with all available permissions assigned. $admin_role = new stdClass(); $admin_role->name = 'administrator'; user_role_save($admin_role); user_role_grant_permissions($admin_role->rid, array_keys(module_invoke_all('permission')));
The new role is set up by creating an object to store the role and then saving it with a call to user_role_save
. The permissions are granted by first calling module_invoke_all('permission')
. This loads all available permissions for all modules which have been enabled, thus giving the administrator role all available permissions.
To ensure that the administrator role stays up to date, the installation profile assigns the administrator role as the system admin role by updating the appropriate system variable.
// Set this as the administrator role. variable_set('user_admin_role', $admin_role->rid);
Next the profile rebuilds the menu system to ensure the cache is fresh and that all modules which were installed are correctly updated:
// Update the menu router information. menu_rebuild();
Finally, the installation profile activates the Seven theme and sets it up for use as the administration theme.
// Enable the admin theme. db_update('system') ->fields(array('status' => 1)) ->condition('type', 'theme') ->condition('name', 'seven') ->execute(); variable_set('admin_theme', 'seven'); variable_set('node_admin_theme', '1');
To do this, it again executes a query using the new DBTNG syntax and then sets a couple of variables to finalize the installation. Don't worry about the syntax of the update query too much right now; we will definitely explore this in more detail in Chapter 7.
After the Seven theme has been installed, the installation profile ends and the installation continues. Remember, because the Drupal core has been installed and all of your modules have been activated, when the install
function runs, there is a wide range of actions you can perform during this routine.