Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Apress.Pro.Drupal.7.Development.3rd.Edition.Dec.2010.pdf
Скачиваний:
73
Добавлен:
14.03.2016
Размер:
12.64 Mб
Скачать

C H A P T E R 2 4

■ ■ ■

Installation Profiles

When you installed Drupal 7 for the first time, you were asked to select the installation profile that you wanted to use as the starting point for your new Drupal site. The options presented to you were Standard and Minimal. Each option represents a pre-defined approach for how Drupal is installed, including options such as what modules are enabled, what content types are created, what theme is selected and enabled, and what blocks are enabled and assigned to regions. The Standard installation profile provides you with a relatively complete Drupal site with many of the features that you would likely use on a basic Drupal site. The Minimal installation profile implements just enough Drupal to bring the site up, with a minimal number of features and components.

Creating an installation profile is a relatively easy process; in fact, an installation profile is just a Drupal module. If you can write a module, you can write an install profile, and you can also do everything from install profiles that you can do with modules, including use the full Drupal API and write update functions to move from one version to another. In this chapter, I’ll teach you how to create your own installation profile, resulting in a Drupal site that has just the features and components that you need for your specific requirements.

Creating a New Installation Profile

A good place to start when creating your new installation profile is to examine Drupal 7’s Standard profile. The Standard profile contains most of the features that you’ll want to include for most sites and provides an easy-to-follow framework for adding new features and functionality. As an example, I’ll create a new profile named enhanced and will expand on the features and functionality that are defined in Drupal’s standard profile.

To begin the process of creating my new enhanced installation profile, I’ll first create a directory named enhanced in the /profiles directory, which is located in the base directory of my Drupal installation. Since I’m expanding on the features and functionality of the standard installation profile, I’ll copy the contents of the standard directory to the enhanced directory.

The three files that you will copy are described in Table 24-1.

525

CHAPTER 24 INSTALLATION PROFILES

Table 24-1. The Required Files for an Installation Profile: Replace Profilename with the Actual Name of Your Profile

File Name

Description

 

 

profilename.info

Contains basic information about the installation profile. If you open that file,

 

you’ll see that it is identical in structure and content to a standard Drupal

 

module .info file.

profilename.install

Describes key features and attributes of the new Drupal instance, such as the

 

filters, blocks, content types, taxonomy vocabularies, and other attributes.

profilename.profile

Used to modify the installation profile form to include additional fields

 

required to support the new installation profile.

 

 

Before moving forward with the creation of the new enhanced installation profile, I’ll rename the files to enhanced.info, enhanced.install, and enhanced.profile.

The enhanced.info File

This file contains the basic information needed by Drupal core to identify and define key attributes of the installation profile, including

The name of the installation profile

The version of Drupal core that is supported by this installation profile

A list of the dependencies (modules) required by our profile—I’ve added other modules to the list beyond what are enabled in the standard profile at the bottom of the list.

The name of the installation .profile file for this profile

Since I started with the standard profile, I’ll update the name, description, and files attributes to reflect the enhanced installation profile. I’ll also change the list of dependent modules to address any specific requirements of my new installation profile. The listing here represents the completed .info file for the enhanced module.

name = Enhanced

description = An enhanced profile. core = 7.x

dependencies[] = block dependencies[] = color dependencies[] = comment dependencies[] = contextual dependencies[] = dashboard dependencies[] = help dependencies[] = image

526

CHAPTER 24 INSTALLATION PROFILES

dependencies[] = menu dependencies[] = path dependencies[] = taxonomy dependencies[] = dblog dependencies[] = search dependencies[] = shortcut dependencies[] = toolbar dependencies[] = overlay dependencies[] = field_ui dependencies[] = file dependencies[] = rdf

// additions beyond the standard profile dependencies[] = forum

dependencies[] = blog dependencies[] = poll dependencies[] = book files[] = enhanced.profile

The enhanced.profile File

This file executes hook_form_formname_alter and in the example here sets the site name field on the form to the site name defined by the server. You can start with a blank .profile file and add to it as necessary to support your requirements; however, nothing is required and a blank .profile file is all that is required.

/**

*Implements hook_form_alter().

*Allows the profile to alter the site configuration form.

*/

function enhanced_form_install_configure_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'install_configure_form') {

// Set default for site name field. $form['site_information']['site_name']['#default_value'] = $_SERVER['SERVER_NAME'];

}

}

The enhanced.install File

This is the file where all the features, functions, variables, and configuration options are defined and set. In the .install file, I’ll define the following:

The input formats that will be defined and enabled

The blocks that will be enabled and assigned to regions

The content types that will be created and enabled

The fields that will be created and associated with content types

The permissions that will be assigned to the site administrators

527

CHAPTER 24 INSTALLATION PROFILES

The roles that will be created

What theme will be enabled as the active theme

All of the settings are wrapped in a hook install function. In the case of the enhanced installation profile, the function name becomes enhanced_install(), as shown here.

/**

*Implements hook_install().

*Perform actions to set up the site for this profile.

*/

function enhanced_install() {

The first thing I’ll do is set up the text formats that will be used on the site. I’ll use the filtered HTML and full HTML input formats that are standard on most Drupal sites. To define an input format, we give it a name, assign it a weight, set the status to active (1), and define the list of filters that are included in the input format. The following example demonstrates setting up the Filtered HTML input format. This input format applies the URL filter (changes links to URLs), the HTML filter (strips out unwanted tags), the Line break filter (changes carriage returns to <br/> tags), and the HTML corrector filters. Each filter in the list is assigned a weight, which defines the order that the filters are applied to the content.

// Add text formats. $filtered_html_format = array(

'name' => 'Filtered HTML', 'weight' => 0,

'filters' => array(

//URL filter. 'filter_url' => array(

'weight' => 0, 'status' => 1,

),

//HTML filter. 'filter_html' => array(

'weight' => 1, 'status' => 1,

),

//Line break filter. 'filter_autop' => array(

'weight' => 2, 'status' => 1,

),

//HTML corrector filter. 'filter_htmlcorrector' => array(

'weight' => 10, 'status' => 1,

),

),

);

528

CHAPTER 24 INSTALLATION PROFILES

The next step in the .install file is to convert the structure created previously into an object and to save the input format by calling the filter_format_save API.

$filtered_html_format = (object) $filtered_html_format; filter_format_save($filtered_html_format);

The next input format that I’ll define is full HTML. This input format is identical in structure to the filtered HTML input format with the exception of not including the HTML filter, which strips out unwanted HTML tags. I’ll follow the same pattern, defining the name, weight, and the list of filters that will be included in this input format.

$full_html_format = array( 'name' => 'Full HTML', 'weight' => 1, 'filters' => array(

//URL filter. 'filter_url' => array(

'weight' => 0, 'status' => 1,

),

//Line break filter. 'filter_autop' => array(

'weight' => 1, 'status' => 1,

),

//HTML corrector filter. 'filter_htmlcorrector' => array(

'weight' => 10, 'status' => 1,

),

),

);

The next step is to convert the structure just created into an object, followed by saving the input format to the Drupal database by calling the filter_format_save API.

$full_html_format = (object) $full_html_format; filter_format_save($full_html_format);

The next step in the process is to define the blocks that will be enabled and assigned to regions of our theme. The key attributes assigned to each block definition are described in Table 24-2.

529

Download from Wow! eBook <www.wowebook.com>

CHAPTER 24 INSTALLATION PROFILES

Table 24-2. Block Attributes Used to Define Each Block That Will Be Enabled During the Install Process

Attribute

Description

Module

The name of the module where the block is defined

Delta

The name of the block as defined in the module (look for hook_block_info to find the

 

list of blocks defined within a module)

Theme

The name of the theme where the block will be assigned

Status

Whether the block will be enabled (1) or disabled (0)

Region

The region defined in the theme where the block is to be shown

Cache

Whether the block is cached or not (-1)

The following code shows the list of blocks that are automatically enabled and assigned to regions by the enhanced installation profile.

// Enable some standard blocks. $values = array(

array(

'module' => 'system', 'delta' => 'main', 'theme' => 'garland', 'status' => 1, 'weight' => 0, 'region' => 'content', 'pages' => '', 'cache' => -1,

),

array(

'module' => 'search', 'delta' => 'form', 'theme' => 'garland', 'status' => 1, 'weight' => -1,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

530

CHAPTER 24 INSTALLATION PROFILES

array(

'module' => 'node', 'delta' => 'recent', 'theme' => 'seven', 'status' => 1, 'weight' => 10,

'region' => 'dashboard_main', 'pages' => '',

'cache' => -1,

),

array(

'module' => 'user', 'delta' => 'login', 'theme' => 'garland', 'status' => 1, 'weight' => 0,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

array(

'module' => 'system', 'delta' => 'navigation', 'theme' => 'garland', 'status' => 1,

'weight' => 0,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

array(

'module' => 'system', 'delta' => 'management', 'theme' => 'garland', 'status' => 1,

'weight' => 1,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

array(

'module' => 'system', 'delta' => 'powered-by', 'theme' => 'garland', 'status' => 1,

'weight' => 10, 'region' => 'footer', 'pages' => '', 'cache' => -1,

),

531

CHAPTER 24 INSTALLATION PROFILES

array(

'module' => 'system', 'delta' => 'help', 'theme' => 'garland', 'status' => 1, 'weight' => 0, 'region' => 'help', 'pages' => '', 'cache' => -1,

),

array(

'module' => 'system', 'delta' => 'main', 'theme' => 'seven', 'status' => 1, 'weight' => 0, 'region' => 'content', 'pages' => '', 'cache' => -1,

),

array(

'module' => 'system', 'delta' => 'help', 'theme' => 'seven', 'status' => 1, 'weight' => 0, 'region' => 'help', 'pages' => '', 'cache' => -1,

),

array(

'module' => 'user', 'delta' => 'login', 'theme' => 'seven', 'status' => 1, 'weight' => 10, 'region' => 'content', 'pages' => '', 'cache' => -1,

),

array(

'module' => 'user', 'delta' => 'new', 'theme' => 'seven', 'status' => 1, 'weight' => 0,

'region' => 'dashboard_sidebar', 'pages' => '',

'cache' => -1,

),

532

CHAPTER 24 INSTALLATION PROFILES

array(

'module' => 'search', 'delta' => 'form', 'theme' => 'seven', 'status' => 1, 'weight' => -10,

'region' => 'dashboard_sidebar', 'pages' => '',

'cache' => -1,

),

// Additional blocks beyond those defined in the standard profile array(

'module' => 'blog', 'delta' => 'recent', 'theme' => 'garland', 'status' => 1, 'weight' => 5,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

array(

'module' => 'forum', 'delta' => 'active', 'theme' => 'garland', 'status' => 1, 'weight' => 10,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

array(

'module' => 'forum', 'delta' => 'new', 'theme' => 'garland', 'status' => 1, 'weight' => 10,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

array(

'module' => 'poll', 'delta' => 'recent', 'theme' => 'garland', 'status' => 1, 'weight' => 15,

'region' => 'sidebar_first', 'pages' => '',

'cache' => -1,

),

);

533

CHAPTER 24 INSTALLATION PROFILES

The next step in the process is to save the block configuration information in the block table in the Drupal database. The following code inserts each of the blocks just defined into the table.

$query = db_insert('block')->fields(array('module', 'delta', 'theme', 'status', 'weight', 'region', 'pages', 'cache'));

foreach ($values as $record) { $query->values($record);

}

$query->execute();

The next step in the installation process is to define the content types that will be created and enabled during the installation process. The key attributes associated with a content type are shown in Table 24-3.

Table 24-3. Content Type Attributes

Attribute

Description

 

 

Type

The internal name of the content type

Name

The name of the content type that appears on the administration pages

Base

The foundational content type that is used to build the new content type

Description

The description of the content type that appears on the administration pages

Custom

Defines whether the content type is a custom content type (1)

Modified

Defines whether the content type was modified; since we’re just creating the

 

content type, the value is set to 1 (yes).

Locked

Defines whether the content type can be modified (0) or not (1)

 

 

For the enhanced installation profile, I’ll use the Basic page and Article content types that are defined in the standard installation profile, and I’ll create a new content type that will be used just for news-related content.

$types = array( array(

'type' => 'page',

'name' => st('Basic page'), 'base' => 'node_content',

'description' => st("Use <em>basic pages</em> for your static content, such as an 'About us' page."),

'custom' => 1, 'modified' => 1, 'locked' => 0,

),

534

CHAPTER 24 INSTALLATION PROFILES

array(

'type' => 'article', 'name' => st('Article'), 'base' => 'node_content',

'description' => st('Use <em>articles</em> for content that requires an image and tags.'),

'custom' => 1, 'modified' => 1, 'locked' => 0,

),

//New content type added for the enhanced installation profile array(

'type' => 'news', 'name' => st('News'),

'base' => 'node_content',

'description' => st('Use <em>news</em> for news related content.'),

'custom' => 1, 'modified' => 1, 'locked' => 0,

),

);

The next step in the process is to save the content types by calling the node_type_set_defaults, node_type_save, and node_add_body_field APIs for each of the content types defined previously.

foreach ($types as $type) {

$type = node_type_set_defaults($type); node_type_save($type); node_add_body_field($type);

}

After creating the content types, the next step is to set up RDF mappings for each of the content types defined in the previous step. The standard installation profile defined the mappings for the page and article content types. I’ve added a mapping to include the news content type in the mapping.

$rdf_mappings = array( array(

'type' => 'node', 'bundle' => 'page', 'mapping' => array(

'rdftype' => array('foaf:Document'),

),

),

array(

'type' => 'node', 'bundle' => 'article', 'mapping' => array(

'rdftype' => array('sioc:Item', 'foaf:Document'),

535

CHAPTER 24 INSTALLATION PROFILES

'field_image' => array(

'predicates' => array('rdfs:seeAlso'), 'type' => 'rel',

),

'field_tags' => array(

'predicates' => array('dc:subject'), 'type' => 'rel',

),

),

),

//the following was added for the enhanced installation profile array(

'type' => 'node', 'bundle' => 'news', 'mapping' => array(

'rdftype' => array('foaf:Document'),

),

),

);

After we define the RDF mappings, the next step is to save the mappings to the database, which is performed by calling the rdf_mapping_save API for each of the mappings.

foreach ($rdf_mappings as $rdf_mapping) { rdf_mapping_save($rdf_mapping);

}

With the content types defined, the next step is to set a few content type attributes. The standard installation profile sets the Basic page attributes so that by default they are not promoted to the front page and comments are disabled. For our news content type, we do want them promoted to the front page, and we also want the ability for visitors to post comments, so we will leave the attributes set to their default values.

variable_set('node_options_page', array('status')); // don’t promote basic pages to the homepage

variable_set('comment_page', COMMENT_NODE_HIDDEN); // don’t allow commenting on basic pages

The next attribute that the standard installation profile sets is whether the author and submitted date and time are displayed when the node is rendered on a page. Since we don’t want that information to appear on the Basic page content types, we’ll set the attribute that determines whether to print the author and date to false.

variable_set('node_submitted_page', FALSE);

The next set of options determines whether users can upload a picture to their profile and have those pictures displayed with their posts and comments. The following configuration options set whether pictures are allowed and the attributes that define how those pictures are displayed on the site.

536

CHAPTER 24 INSTALLATION PROFILES

variable_set('user_pictures', '1'); // set the attribute so that users pictures are allowed (1)

variable_set('user_picture_dimensions', '1024x1024'); // set the maximum dimensions of the picture

variable_set('user_picture_file_size', '800'); // set the maximum file size for the picture

variable_set('user_picture_style', 'thumbnail'); // set the default size that will be rendered on the page

Next we’ll define how user account creation is handled. There are three possible values that we can use to determine how user accounts are handled in the system, as described in Table 24-4.

Table 24-4. User Account Creation Options

Value

Description

 

 

USER_REGISTER_ADMINISTRATORS_ONLY

Only administrators can create accounts

 

on the site.

USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL

Visitors can create an account but that

 

account will not be active until an

 

administrator approves and enables the

 

account.

USER_REGISTER_VISITORS

Visitors can create an account and the

 

account is automatically approved and

 

enabled.

 

 

I’ll use the approach where users can register for an account but an administrator must approve and enable the account.

variable_set('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL);

The next step in the installation process is to set up taxonomy. I’ll create a vocabulary called Tags that will allow authors to free tag content. First I’ll define the description and help text associated with the vocabulary, and then I’ll create a vocabulary object.

$description = st('Use tags to group articles on similar topics into categories.'); $help = st('Enter a comma-separated list of words to describe your content.');

$vocabulary = (object) array(

'name' => 'Tags', // the name of the vocabulary 'description' => $description,

'machine_name' => 'tags', 'help' => $help,

);

537

CHAPTER 24 INSTALLATION PROFILES

After defining the vocabulary object, I’ll save it to the Drupal database using the taxonomy_vocabulary_save API.

taxonomy_vocabulary_save($vocabulary);

I’ll next create a field using the Tags vocabulary, and I’ll assign the field to the article content type.

$field = array(

// create the field name using the machine name of the vocabulary that was just created 'field_name' => 'field_' . $vocabulary->machine_name,

// define the field type as a taxonomy term reference 'type' => 'taxonomy_term_reference',

//Set cardinality to unlimited for tagging. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,

//set the list of allowed values to the list of terms in the vocabulary 'settings' => array(

'allowed_values' => array( array(

'vid' => $vocabulary->vid, 'parent' => 0,

),

),

),

);

// create the field using the field_create_field API field_create_field($field);

With the field created, I can now assign it to the article content type.

$instance = array(

// use the field that was just crated

'field_name' => 'field_' . $vocabulary->machine_name,

//assign the field to a node 'entity_type' => 'node',

//create the label for the field using the vocabulary name 'label' => $vocabulary->name,

//assign the field to the article content type

'bundle' => 'article',

// use the vocabulary’s help text as the description 'description' => $vocabulary->help,

//use the taxonomy autocomplete widget 'widget' => array(

'type' => 'taxonomy_autocomplete', 'weight' => 4,

),

538

CHAPTER 24 INSTALLATION PROFILES

//define how the terms will be displayed in full node and teaser mode 'display' => array(

'default' => array(

'type' => 'taxonomy_term_reference_link', 'weight' => 10,

),

'teaser' => array(

'type' => 'taxonomy_term_reference_link', 'weight' => 10,

),

),

);

// assign the field to the article content type using the field_create_instance API field_create_instance($instance);

Another requirement for the enhanced installation profile is that the article and news content types should both have an image field for uploading pictures. First I’ll create the field using the following code.

$field = array(

//define the name of the field 'field_name' => 'field_image',

//set the type to image 'type' => 'image',

//allow one image per node 'cardinality' => 1, 'translatable' => TRUE, 'locked' => FALSE,

//set the file ID as the index

'indexes' => array('fid' => array('fid')), 'settings' => array(

'uri_scheme' => 'public', 'default_image' => FALSE,

),

// define how the field is stored 'storage' => array(

'type' => 'field_sql_storage', 'settings' => array(),

),

);

// create the field using the field_create_field API field_create_field($field);

With the field defined, I can now assign the field to both the article and news content types.

$instance = array(

//use the field image that was just created 'field_name' => 'field_image',

//assign it to a node

'entity_type' => 'node', 'label' => 'Image',

539

Download from Wow! eBook <www.wowebook.com>

CHAPTER 24 INSTALLATION PROFILES

// assign the field to the article content ype 'bundle' => 'article',

'description' => 'Upload an image to go with this article.', 'required' => FALSE,

// define the settings associated with the image to be uploaded 'settings' => array(

'file_directory' => 'field/image', 'file_extensions' => 'png gif jpg jpeg', 'max_filesize' => '',

'max_resolution' => '', 'min_resolution' => '', 'alt_field' => TRUE, 'title_field' => '',

),

// define the type of widget to be used 'widget' => array(

'type' => 'image_image', 'settings' => array(

'progress_indicator' => 'throbber', 'preview_image_style' => 'thumbnail',

),

'weight' => -1,

),

// define how images are displayed for full node and teaser views 'display' => array(

'default' => array( 'label' => 'hidden', 'type' => 'image__large', 'weight' => -1,

),

'teaser' => array( 'label' => 'hidden',

'type' => 'image_link_content__medium', 'weight' => -1,

),

),

);

// attach the image to the article content type using the field_create_instance API field_create_instance($instance);

$instance = array(

//use the field image that was just created 'field_name' => 'field_image',

//assign it to a node

'entity_type' => 'node', 'label' => 'Image',

// assign the field to the news content ype 'bundle' => ‘news’,

'description' => 'Upload an image to go with this news item.', 'required' => FALSE,

540

CHAPTER 24 INSTALLATION PROFILES

// define the settings associated with the image to be uploaded 'settings' => array(

'file_directory' => 'field/image', 'file_extensions' => 'png gif jpg jpeg', 'max_filesize' => '',

'max_resolution' => '', 'min_resolution' => '', 'alt_field' => TRUE, 'title_field' => '',

),

// define the type of widget to be used 'widget' => array(

'type' => 'image_image', 'settings' => array(

'progress_indicator' => 'throbber', 'preview_image_style' => 'thumbnail',

),

'weight' => -1,

),

// define how images are displayed for full node and teaser views 'display' => array(

'default' => array( 'label' => 'hidden', 'type' => 'image__large', 'weight' => -1,

),

'teaser' => array( 'label' => 'hidden',

'type' => 'image_link_content__medium', 'weight' => -1,

),

),

);

// attach the image to the news content type using the field_create_instance API field_create_instance($instance);

The next step is to enable the default permissions that should be associated for systems roles (anonymous and authenticated users are the default systems roles). First I’ll create a variable that I can use to assign the default input format that I want to assign to anonymous and authenticated users. For my purposes, I want to use filtered HTML for both roles.

$filtered_html_permission = filter_permission_name($filtered_html_format);

Next I’ll assign the basic permission of being able to access content and use the filtered HTML input filter to the anonymous user role.

user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access content', $filtered_html_permission));

541

CHAPTER 24 INSTALLATION PROFILES

I’ll be more generous with the authenticated user role. I’ll assign access content, access comments, post comments, post comments without approval, and the filtered HTML input filter.

user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'post comments without approval', $filtered_html_permission));

The next step in the process is to set up the default role for site administrators and grant all permissions to that role.

$admin_role = new stdClass(); $admin_role->name = 'administrator'; $admin_role->weight = 2;

//save the role to the Drupal database user_role_save($admin_role);

//grant all permissions to the admin role user_role_grant_permissions($admin_role->rid, array_keys(module_invoke_all('permission')));

//Set this as the administrator role.

variable_set('user_admin_role', $admin_role->rid);

With the admin role created, the next step is to assign the admin role to the user with a UID of 1. We do that by simply inserting a row in the user roles table using the UID of the admin user (1) and the admin role ID that was created in the previous step.

db_insert('users_roles')

->fields(array('uid' => 1, 'rid' => $admin_role->rid)) ->execute();

With all the changes that have been made, we need to rebuild the menus by calling the menu_rebuild function.

menu_rebuild();

The last step in the process is to set and enable the seven theme as the admin theme and close out the install function.

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');

// close the install function.

}

The enhanced installation profile is now complete and ready to be used to install Drupal. I could have continued to expand on the installation profile by adding additional blocks, creating additional content types and fields, and assigning those fields to content types, creating taxonomy vocabularies, and user roles.

542

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]