introduction to drupal 7 installation profiles
26 Jan 2014
Last weekend I worked on a Drupal site and it was not fun =( mostly due to incomplete and inaccurate documentation. My goal was to create a distributable bundle for Spanish Ubuntu local teams. I already had a base theme and didn’t though it could be that hard, however what started as a simple task ended as a very long weekend. On this post I’ll try to document what issues I found and how they were worked out.
For the record, I must say I’m not a web developer, I find all the technologies related quite difficult to understand, I also didn’t have any previous experience with drupal internals.
Since the beginning I though any work should be automatized as much as possible, ideally an administrator would be able to download the bundle, throw it away on the file system, run the web installer and start creating content. The result happily is quite similar:
- Download and place the bundle in a directory read by a web server (eg, apache)
- Go to the server ip
- Select the ‘Ubuntu-mx’ profile
- On a Spanish translated interface, input the database settings
- Configure the administrator credentials
- Create content
The resulting site would be translated to spanish, will enable a bunch of modules (l10n_update, admin_menu, smtp, ckeditor), an Ubuntu theme, search permissions and menu links.
For this to work, I used:
Installation profiles
Installation profiles are special modules who allow you to declare which modules, languages and themes to load by default, they can also be used to modify the installer to add or remove steps.
They must have a .info, .profile and .install files at:
- /profiles/profile_name/
I named my module ‘umx’
.info
This file contains name, description, drupal version and dependencies (modules enabled by default):
declaring only core modules as dependencies
The content of my /profiles/umx/umx.info file was:
name = Ubuntu-mx description = Install Ubuntu-mx modules, language (es) and configuration version = 0.1 core = 7.x dependencies[] = block dependencies[] = color dependencies[] = comment dependencies[] = contextual dependencies[] = dashboard dependencies[] = help dependencies[] = image dependencies[] = list dependencies[] = number dependencies[] = options dependencies[] = path dependencies[] = taxonomy dependencies[] = dblog dependencies[] = shortcut dependencies[] = overlay dependencies[] = field_ui dependencies[] = file dependencies[] = rdf dependencies[] = umx_conf
I found much more comfortable to declare only core modules as dependencies and carry on the rest of the configuration in a separate module (generated by the features module). This way I can keep using the same unmodified profile and alter the resulting site by regenerating the umx_conf module when necessary.
.profile
On the .profile and .install files can be written functions to override/define hooks, I used /profile/umx/umx.profile to configure the default language to spanish (as a result the language dialogue is skipped):
function umx_profile_details() { $details['language'] = "es"; return $details; }
The default language can also be configured in a feature module (on this example, umx_conf) however if doing so, the installation process itself will run in English, and if it’s double declared (here and in a feature module), the installation will return a sql duplication key error.
It’s not optimal, but it’s the best I could do. I located the es.po file at:
- /profiles/umx/translations/es.po
The localize.drupal.org server has po files with a drupal version prefix, if downloaded from there, you should rename them. Eg
drupal-7.26.es.po -> es.po
.install
Here you can override install, update and uninstall functions. Since the feature modules doesn’t support theme settings (something who could be really useful) I declared the default theme on this file (/profile/umx/umx.install):
function umx_install() { db_update('system') ->fields(array('status' => 1)) ->condition('type', 'theme') ->condition('name', 'umxtheme') ->execute(); variable_set('theme_default', 'umxtheme'); }
According to the documentation, theme settings should be declared in profile_themes_enabled() with the theme_enable() function, however I was unable to make to work any of them.
Snippets which did NOT work (drupal 7.26):
function umx_themes_enabled() { //any code; }
function umx_install_finished() { //any code; }
function umx_update_N() { //any code; }
function umx_install() { variable_set('theme_default','umxtheme'); }
function umx_install() { $list_themes = list_themes(TRUE); $major_version = (int)VERSION; $theme_default = isset($list_themes['umxtheme']) ? 'umxtheme' : 'garland'; $admin_theme = isset($list_themes['seven']) ? 'seven' : 'garland'; variable_set('theme_default', $theme_default); theme_enable($theme_default); theme_disable(array('bartik')); if($affect_admin_theme){ variable_set('admin_theme', $admin_theme); } if (module_exists('switchtheme')) { if (empty($_GET['theme']) || $_GET['theme'] !== $theme_default) { $query = array( 'theme' => $theme_default ); if($major_version < 7){ $options = $query; } else{ $options = array('query' => $query); } drupal_goto($_GET['q'], $options); } } }
function umx_install() { $enable = array( 'theme_default' => 'umxtheme', 'admin_theme' => 'seven', ); theme_enable($enable); foreach ($enable as $var => $theme) { if (!is_numeric($var)) { variable_set($var, $theme); } } theme_disable(array('bartik')); }
Drupal themes must be placed at:
- /sites/all/themes
One lesson I learned was that themes should be named clearly, at the beginning I declared the theme as ‘umx’ (for ubuntu-mx theme) and put it in /sites/all/themes/umx-theme/, later on while trying to configure the bundle with a default theme I got confused because the profile installation was named equal and I was not sure which one I was referring to. Name your themes with a unique string, (I finally decided to rename ‘umx’ to ‘umxtheme’).
Ignore the name field written in the .info file, and prefix your hook functions with the selected drupal theme (e,g, umxtheme_footer_text())
- Setting default theme for Drupal
- Setting a different default theme by default in an install profile
- how to write a drupal 7 installation profile
Feature modules
Feature modules are good for bundling configurations, permissions and dependencies on non default modules. I created umx_conf to iterate faster. Using feature modules you can modify drupal settings through a browser and then export the result to code from the feature menu.
Autogenerated features modules can contain:
- .info
- .module
- .feature.submodule.inc
Very few times you would need to modify them directly. In my experience (a weekend) the autogenerated files will sometimes contain mistakes, therefore I modified them slightly to feet my needs:
.info
On this file, dependencies are declared, the generator makes a quite clever job adding recursively all the dependencies your configurations depend on.
name = umx conf description = Common settings for the Ubuntu-mx local portal. core = 7.x package = Features version = 7.x-0.1 project = umx_conf dependencies[] = admin_menu dependencies[] = admin_menu_toolbar dependencies[] = ckeditor dependencies[] = features dependencies[] = l10n_update dependencies[] = locale dependencies[] = menu dependencies[] = search dependencies[] = smtp features[ckeditor_profile][] = Advanced features[ckeditor_profile][] = CKEditor Global Profile features[ckeditor_profile][] = Full features[features_api][] = api:2 features[user_permission][] = search content features[user_permission][] = use advanced search features[menu_custom][] = main-menu features[menu_links][] = main-menu_portada:<front> features[menu_links][] = main-menu_foros:http://google.com features[menu_links][] = main-menu_preguntas:http://ubuntu.shapado.com features[menu_links][] = main-menu_wiki:https://wiki.ubuntu.com/UbuntuMxTeam features[menu_links][] = main-menu_chat:http://google.com features[menu_links][] = main-menu_descargar-ubuntu:http://google.com
.module
On this file, you can override hook functions, I leave it blank
.feature.submodule.inc
On these files per module configurations are saved, in my case, I had to modify /sites/all/modules/umx_conf/umx_conf.features.menu_links.inc because some links weren’t exported.
function umx_conf_menu_default_menu_links() { $menu_links = array(); $menu_links['main-menu_portada:<front>'] = array( 'menu_name' => 'main-menu', 'link_path' => '<front>', 'router_path' => '', 'link_title' => 'Portada', 'options' => array( 'attributes' => array( 'title' => '', ), 'identifier' => 'main-menu_portada:<front>', ), 'module' => 'menu', 'hidden' => 0, 'external' => 1, 'has_children' => 0, 'expanded' => 0, 'weight' => 0, 'customized' => 1, ); ...
I had to adjust mostly the weight parameter and add missing links. Not difficult if you follow the syntax (even if you don’t know php).
Extra
If you had problems with the above description, a probably better and more up-to-date approach to profile Drupal installation is described at:
That’s it, I hope this information can save some time to someone, have fun!