Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Minisites in Open Atrium

Parent Feed: 

A single Open Atrium installation to serve minisites from different domains with a common backend

You can use a single Open Atrium installation to create minisites, i.e., minimal websites with a simple structure, served at different domains, but sharing a centralized backend. Each minisite can be public or private and can have a specific theme and specific features. An anonymous visitor will only see a small, self-contained site, while site editors will be able to manage content on all minisites from the same backend.

This is an ideal situation, for example, when an Open Atrium installation is used as a private Intranet but you want to build small auxiliary sites for conferences or events, and possibly take advantage of the fact that editors and registered users are the same as the main Intranet.

And, best of all, this can be done with a minimal amount of coding and respecting the Open Atrium architecture.

Creating and Customizing a Minisite

Our aim is to build a feature that will allow us to create and customize a minisite in just a few minutes. We want to start from the ordinary "Create Group" page:

minisite-create.jpg

And this is what we get immediately upon form submission:

minisite-new-1.png

The minisite ships with default content (pages linked from the left side menu) and the editor can just click and add content.

We can also hook our minisite to the built-in look-and-feel customization that Open Atrium provides for its groups and give the possibility to the editor to choose background and foreground colors:

minisite-color.png

After a quick content editing, the editor can achieve something like this:

minisite-custom-1.png

Screenshots are taken from Alfa Puentes, an international project funded by the EU that will focus on exchanging best practices between Europe and Latin America about higher education and that will include several events and conferences, each with a dedicated minisite.

Let's now see how to build this feature in Open Atrium.

Creating a minisite group type (spaces preset)

To start, we simply define a new spaces preset type, named "minisite": this can be done through hook_spaces_presets() using the existing definitions for public and private spaces from atrium_groups.spaces.inc as a basis.

<?phpfunction atrium_minisite_spaces_presets() {
 
$export = array(); $spaces_presets = new stdClass;
 
$spaces_presets->disabled = FALSE;
 
$spaces_presets->api_version = 3;
 
$spaces_presets->name = 'minisite';
 
$spaces_presets->title = 'Minisite';
 
$spaces_presets->description = 'Minisite space preset.';
 
$spaces_presets->space_type = 'og';
   ...
?>

The new space preset can be exported into a feature and creating a minisite becomes as easy as creating a new group.

minisite-create.jpg

Assigning features to a minisite

Just like a standard Open Atrium group has some features available by default, we will want our minisites to use a certain set of features by default. In our case, we built two features for Pages and News and we enable them for our minisites, that will thus have static pages and news available.

<?php ... (follows from above) ...
 
$spaces_presets->value = array(
   
'variable' => array(
     
'spaces_features' => array(
       
'atrium_blog' => 1,
       
'atrium_book' => 0,
       
'atrium_calendar' => 1,
       
'atrium_casetracker' => 0,
       
'atrium_members' => 1,
       
'atrium_pages' => 1,
       
'atrium_shoutbox' => 0,
       
'spaces_dashboard' => 1,
       
'atrium_news' => 1,
      ),
  ... (continue
along the lines of atrium_groups.spaces.inc) ...
?>

Making minisites self-contained: menus and blocks

We want our minisites to be self-contained as much as possible. In order to achieve that, with some standard Drupal hooks, we create a new menu for each minisite, that takes care of updating it as soon as the respective minisite group changes. Here is one of the implemented hooks:

<?php
function atrium_minisite_nodeapi(&$node, $op, $arg = 0) {
 
  if (isset(
$node->spaces_preset_og) &&
     
atrium_minisite_is_minisite_preset($node->spaces_preset_og)) {
    if (
in_array($op, array('insert', 'update', 'delete'))) {
     
$menu = array();
     
$menu['title'] = $node->title;
     
$menu['menu_name'] = atrium_minisite_get_menu_name($node);
     
$menu['description'] = $node->og_description;
     
atrium_minisite_menu_api($op, $menu);
     
      if (
$op == 'insert') {
       
module_invoke_all('atrium_minisite_default_content', $node, $menu);
      }
    }
  } 
}
?>

As you can notice, our minisite feature exposes an atrium_minisite_default_content() hook which allows other modules to provide default content once a new minisite is created (e.g. "About" and "Contact" pages, etc...). Shipping each new minisite with default content allows the editor to start filling up the site straight away without the need to recreate again and again the same content structure.

To make our minisite menu group-aware, we implement hook_block() in atrium_minisites.module. The implementation below relies on a couple of helper functions defined elsewhere.

<?php
function atrium_minisite_block($op = 'list', $delta = NULL, $edit = NULL) {
 
 
$blocks = array();
  if (
$op == 'list') {
   
$blocks['primary-navigation']['info'] = t('Minisite: Primary navigation');
   
$blocks['primary-navigation']['cache'] = BLOCK_NO_CACHE; $blocks['secondary-navigation']['info'] = t('Minisite: Secondary navigation');
   
$blocks['secondary-navigation']['cache'] = BLOCK_NO_CACHE; $blocks['full-navigation']['info'] = t('Minisite: Full navigation');
   
$blocks['full-navigation']['cache'] = BLOCK_NO_CACHE;
  }
  if (
$op == 'view') {
    if (
atrium_minisite_is_minisite_space()) {
     
$config = atrium_minisite_get_menu_block_config($delta);
      if (
$delta == 'secondary-navigation' || $delta == 'full-navigation') {
       
$config['level'] = 2;       
       
$config['expanded'] = 1;
       
$config['depth'] = 0;
      }
      if (
$delta == 'full-navigation') {
       
$config['level'] = 1;       
      }
     
$blocks = menu_tree_build($config);
      unset(
$blocks['subject']);
    }
  }
  return
$blocks;
}
?>

This block is then specified as a context reaction, so that site visitors will see a self-contained navigation when browsing the minisite.

Making minisites themeable

Each minisite can be assigned a different theme. To do so from a convenient interface, we implement hook_form_alter() in atrium_minisite.module to give the possibility to select a theme for the given minisite. Again, we omit some helper functions for brevity.

<?php
/**
* Implementation of hook_form_alter()
*/
function atrium_minisite_form_alter(&$form, &$form_state, $form_id) {
 
  if (isset(
$form['#node']) && $form_id == $form['#node']->type .'_node_form') {
   
$node = $form['#node'];   
   
    if (
og_is_group_type($node->type)) {
     
module_load_include('inc', 'system', 'system.admin');     
     
atrium_minisite_theme_form($form);
    }
   
    if (
atrium_minisite_is_minisite_space()) {
      if (
$node->type == 'page') {
       
$space = spaces_get_space();
       
$conf['menu_default_node_menu'] = atrium_minisite_get_menu_name($space->group);
       
$menu_name = atrium_minisite_get_menu_name($space->group);
       
$menu = array($menu_name => $space->group->title);
       
$form['menu']['parent']['#options'] = menu_parent_options($menu, $item);
      }
    }
  }
}
?>

We can now choose the best theme for our minisite directly on the creation page:

minisite-theme.jpg

Serving minisites on different domains

Each Open Atrium group gets its own URL path component; in our case the minisite will be reachable at something like http://alfapuentes.org/conference/. With a quick Persistent URL customization we can actually set the URL rewriting to be per domain, allowing our minisite to have its own domain. This can be achieved by:

  1. Enabling the "Domain" URL modification type from admin/settings/purl/types;
  2. Assigning to "Group space" the new modifier type on admin/settings/purl;
  3. Adding a custom URL each time we are going to create a minisite group

By taking advantage of the Persistent URL domain rewriting we can really make the new minisite look completely independent from the underlying Open Atrium platform:

minisite-url.png

The techniques shown here are covered in detail in our trainings; if interested, contact us for more information.

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web