Probably every Drupal developer has come across with ready-to-use site packages on Drupal where after installation you get a ready site with the set of necessary modules, personal theme and so on. There are many such packages, among which Open Atrium, Drupal Commons and others. I’m sure the question appeared: “How was it realized?” or “How can it be done?” The answer to this question is Drupal Install Profile. So, how can a personal install profile be created? Generally, install profiles are created on the basis of the existed site.
Step 1. Preparation of files.
Create “modules” folder, “contrib” folder in it into which all the modules necessary for work are copied.
“themes” folder is created into which a folder with our themes is put, for example, acquia_prosper, and .tpl.php sets and .js and .css files created in the process of custom Drupal development. To include several special elements of site into a package, such as views, content type, menu, roles, access rights and others, Features module is used. Created features are put into “features” folder and added to “modules” folder.
Note: At the moment Features module doesn’t transfer taxonomy dictionaries and terms into them, maybe it will be done in the following versions of module, that’s why it should be done manually. It’ll be described further.
We’ll get the following structure:
myprofile
- modules
- contrib
- features
- themes
Step 2. Creation of .profile file
This file is the “brain” of our profile; it manages the site installation process.
Note: At this stage of site work, function t() doesn’t function, that’s why its equivalent st () is used.
2.1. myprofile.profile is created.
2.2._profile_modules().
Function myprofile_profile_modules () is formed. In this function, the modules are described which should be turned on after installation.
// $Id$ // indicate dictionary taxonomy id define('MYPROFILE_NEWS_VOCAB_ID', 1); // indicate topic title define('MYPROFILE_ACQUIA_THEME', 'acquia_prosper'); define('MYPROFILE_FUSION_CORE', 'fusion_core'); /** * Returns array of modules which will be turned on after profile installation */ function myprofile_profile_modules() { $modules = array( // Default Drupal modules. 'color', 'comment', 'dblog', 'help', 'menu', 'path', 'taxonomy', //ADMINISTRATION 'admin', 'admin_menu', //CCK 'content', 'text', 'ctools', 'content_permissions', 'fieldgroup', 'filefield', 'optionwidgets', 'nodereference', 'userreference', //FILEFIELD PATHS 'filefield_paths', //IMAGECACHE 'imageapi', 'imageapi_gd', 'imagecache', 'imagecache_ui', 'imagecache_customactions', //TOKEN 'token', //VIEWS 'views', 'views_bulk_operations', 'viewscarousel', 'views_export', 'views_or', 'views_slideshow', 'views_ui', //META TAGS 'nodewords', 'nodewords_basic', 'nodewords_extra', 'nodewords_verification_tags', //USER INTERFACE 'imce', 'wysiwyg', 'jquery_ui', 'jquery_update', 'dialog','vertical_tabs', 'imce_wysiwyg', //SKINR 'skinr', 'skinr_ui', //OTHER 'better_formats', 'globalredirect', 'no_anon', 'pathauto', 'url_alter', 'subpath_alias', 'token_actions', 'transliteration', 'vertical_tabs', //UBERCART 'ca', 'uc_order', 'uc_store', 'uc_product', 'uc_cart', 'uc_payment', 'uc_reports', 'uc_shipping', 'uc_product_power_tools', 'uc_stock', //XML SITEMAP 'xmlsitemap', 'xmlsitemap_engines', 'xmlsitemap_menu', 'xmlsitemap_node' ); return $modules; }
Note: Modules which “depend on” other ones should be indicated after those that they depend on. There are also problems when url_alter module is turned on. The decision can be found here.
2.3. _profile_details().
Profile description which will be shown on profile installation screen.
/** @return * array with keys "name" and "description", describing the given profile, * and additional "language", to redefine language for a profile */ function myprofile_profile_details() { $description = st('Select this profile to install the My custom profile.'); return array( 'name' => 'My profile', 'description' => $description, ); }
Note: Modules which “depend on” other ones should be indicated after those that they depend on. There are also problems when url_alter module is turned on. The decision can be found here.
2.4. _profile_task_list()
List of tasks that will be done during profile installation.
function myprofile_profile_task_list() { $tasks = array(); $tasks['configure-myprofile'] = st('Configure My profile'); $tasks['install-myprofile'] = st('Install My profile'); return $tasks; }
2.5. _profile_tasks(&$task, $url)
This function is responsible for this stage of profile installation.
/**
* .
*/It executes the final tasks of profile installation.
function myprofile_profile_tasks(&$task, $url) {
// skipping the standard installation stage.
if ($task == 'profile') {
$task = 'install-myprofile';
}
// It returns features form
if ($task == 'configure-myprofile') {
$output = drupal_get_form('myprofile_features_form', $url);
}
// installation batch process
if ($task == 'install-myprofile') {
$operations = array();
// pre-installation operations
$operations[] = array('myprofile_config_taxonomy', array());
// creating taxonomy dictionary
// “features” installation
$features = variable_get('myprofile_selected_features', array());
foreach ($features as $feature) {
$operations[] = array('features_install_modules', array(array($feature)));
}
// post-installation operations
$operations[] = array('myprofile_config_theme', array()); //
turning on the personal theme
$operations['finished'] = 'myprofile_configure_batch_finished';
// building batch process
$batch = array(
'operations' => $operations,
'title' => st('Configuring My profile'),
'error_message' => st('An error occurred. Please try reinstalling again.'),
'finished' => 'myprofile_cleanup',
);
// building batch process
variable_set('install_task', 'install-myprofile-batch');
batch_set($batch);
batch_process($url, $url);
}
// It shows batch execution page
if ($task == 'install-myprofile-batch') {
include_once 'includes/batch.inc';
$output = _batch_page();
}
return $output;
}
2.6. _features_form()
“Choose from available features” form to transfer their functional on the site.
function myprofile_features_form($form_state, $url) { $form = array(); drupal_set_title(st('Choose from available features')); // Ancillary message $form['message'] = array( '#type' => 'item', '#value' => st('The selected features will be enabled after the installation has completed. At any time, you can turn the available features on or off.'), ); $form['content'] = array( '#type' => 'checkbox', '#title' => st('Content types'), '#default_value' => 1, '#description' => st('Some test content types'), );l $form['menu_links'] = array( '#type' => 'checkbox', '#title' => st('Menu'), '#default_value' => 1, '#description' => st('Some test menu'), ); $form['views_default'] = array( '#type' => 'checkbox', '#title' => st('View'), '#default_value' => 1, '#description' => st('Some test view'), ); // Returns to installation without its abort. $form['url'] = array( '#type' => 'value', '#value' => $url, ); $form['submit'] = array( '#type' => 'submit', '#value' => st('Continue'), ); return $form; }
2.7. _features_form_submit()
This function forms the array of chosen features.
function myprofile_features_form_submit(&$form, &$form_state) {
// chosen features batch
$features = array();
foreach ($form_state['values'] as $key => $value) {
$features[] = $key;
}
// forming temporary variable with chosen features.
variable_set('myprofile_selected_features', $features);
// initiating the next step of installation
variable_set('install_task', 'install-myprofile');
// returning to the installation page
drupal_goto($form_state['values']['url']);
}
2.8._config_taxonomy()
Creating taxonomy dictionary.
function myprofile_config_taxonomy() { $vocab = array( 'name' => st('Test'), 'description' => st('Test vocabulary'), 'multiple' => '1', 'required' => '1', 'hierarchy' => '1', 'relations' => '1', 'tags' => '0', 'module' => 'taxonomy', ); taxonomy_save_vocabulary($vocab); db_query("UPDATE {vocabulary} SET vid = %d WHERE name = '%s", MYPROFILE_NEWS_VOCAB_ID, st('Test')); }
2.9._config_theme()
Turning on the personal theme, i.e. it will become active after installation.
function myprofile_config_theme() { // turning off garland theme db_query("UPDATE {system} SET status = 0 WHERE type = 'theme' and name = '%s'", 'garland'); // turning on fusion and acquia_prosper themes db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' and name = '%s ", MYPROFILE_ACQUIA_THEME); db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' and name = '%s ", MYPROFILE_FUSION_CORE); // setting acquia_prosper theme by default variable_set('theme_default', MYPROFILE_ACQUIA_THEME); // rebuilding registry list_themes(TRUE); drupal_rebuild_theme_registry(); }
2.10._cleanup()
Cleaning up after we are done :) .
function myprofile_cleanup() { // rebuilding types of content node_types_rebuild(); // filtering cache $core = array('cache', 'cache_block', 'cache_filter', 'cache_page'); $cache_tables = array_merge(module_invoke_all('flush_caches'), $core); foreach ($cache_tables as $table) { cache_clear_all('*', $table, TRUE); } // clearing JC and CSS caches drupal_clear_css_cache(); drupal_clear_js_cache(); // features should be returned $revert = array( 'myprofile_features' => array('content', 'menu_links', 'views_default') ); features_revert($revert); // completing installation variable_set('install_task', 'profile-finished'); }
Created myprofile.profile should be put into "myprofile" folder.
The final structure of files is:
myprofile
- modules
- contrib
- features
- themes
- myprofile.profile
The last thing that is needed is to transfer a folder with our profile "myprofile" into Drupal distributive using the way drupal-6.х -> profiles.
Note: This example was made on the basis of Drupal Commons, it can serve as an example of install profile realization.
Conclusion.
In order to create our install profile, we need to create a “package” with necessary modules, features and theme and also to create .profile file.
If you need help with creating install profile, contact our Drupal development agency.