Building a 'Portal' App in Drupal Open Atrium Intranet

09 Feb 2012

Joris Snoek - Business Dev
+31 (0)20 - 261 14 99

When navigating through your intranet, it would be nice to have your essential websites at hand. So you have one Portal (intranet) to navigate all your essential systems. Here is an example on how to build a 'Portal' feature for Open Atrium, a Drupal based intranet.

Usage example

First, create a new group of type 'External website'

When group is created, you'll see this button: 'add external website'. Hit it.

Fill in the title and address

And voila, the external website loaded in an App (feature). This way you won't have to navigate away from your intranet and, for example, add Features like the case tracker, to create projects and task concerning this external system.

How to create this

Add content type and create initial feature

Add and configure a new content type, in this example 'external website'. In that content type add a link field 'address'. After creating this content type, you can export it to a feature. In the downloaded feature, go to the generated .info file and add this line:

spaces[types][] = "og"

Now this content type will only be available in groups, and not site-wide.
For more info on creating features:
In that tutorial you can also learn, for example, how to create and export a view to your feature.

Install the initial feature

Now the basics of the feature are set. Next step is to install it, so we can work it out to become the Portal feature as exampled above.

Create new group type

So now we have installed the feature, it's time to create a new group type. This can be done with help of the powerful Spaces module. After creating the space, you can also export that to your feature. From there you can tweak code and thus space settings, most important code here:

* Implementation of hook_spaces_presets().
function atrium_portal_spaces_presets() {
  $spaces_presets->space_type = 'og';
  $spaces_presets->value = array(
    'variable' => array(
      'spaces_og_selective' => 0,
      'spaces_og_register' => 0,
      'spaces_og_directory' => 0,
      'spaces_og_private' => 0,
      'spaces_features' => array(
        'atrium_portal' => '1',
      'spaces_setting_home' => 'portal',
      'site_frontpage' => 'portal',
      'designkit_color' => array(
        'background' => '#3399aa',
} ?>

Load the external website direct

When we hit the 'External website' App, we want the external site to load directly as show in example above. Since a view will always generate a list of of fields or nodes, this won't do. So here's a little code I added to the .module file of the feature; this way the added external website will load directly when 'External website' Feature is clicked:

So you may think: ' why is this view needed then?'. Well, it provides the handy text: '...add your first External website to start...', that makes it user friendly. And we can use it in the future to load more external sites for example dived in different tabs.

* Implementation of hook_menu().
function atrium_portal_menu() {
  $items = array();
  $items['portal'] = array(
    'title' => t('External website'),
    'page callback' => '_atrium_portal_show',
    'page arguments' => array(),
    'access callback' => 'spaces_access_feature',
    'access arguments' => array('view', 'atrium_portal'),
    'type' => MENU_NORMAL_ITEM,
    'menu_name' => 'features',
  return $items;

* Page callback for portal feature.
function _atrium_portal_show() {

  global $user;
  //Make sure the first entered external window node opens, when openining the Feature.
  $result = views_get_view_result('Portal', 'page_1');

  if (count($result) == 1) {
    drupal_goto('node/'. $result[0]->nid);
  return views_embed_view('Portal', 'page_1');
} ?>

Load an iframe

Now we need a template file that provides an iframe. Because Open Atrium doesn't support a 'iframe' layout, or something like that. This is what the tpl file looks like:

$frame = '

And we need this template file to load when a 'external website' node type is loaded. Here is the code for that:

* Implementation of hook_preprocess_node()
function atrium_portal_preprocess_node(&$vars) {

  // Make sure no crap is surrounding the external website :)
  // And correct tpl file is loaded
  if ($vars['type'] == 'frame') {
    $node = node_load($vars['node']->nid);
    $address = $node->field_address['0']['url'];
    $vars['content'] = theme('portal', $address);
    $vars['links'] = $vars['node']->title = $vars['title'] = '';
    $vars['submitted'] = '';
} ?>

Load 'wide' layout

By default, Open Atrium will load a layout with a right sidebar. You can override that by adding a context and make sure is loads the 'wide layout'. IN that context, also make sure the breadcrumbs and active menu are handled. Also export this context to your feature. Here is the most important piece of code from that exported context:

 function atrium_portal_context_default_contexts() {
  $context->conditions = array(
    'node' => array(
      'values' => array(
        'frame' => 'frame',
      'options' => array(
        'node_form' => '1',
    'views' => array(
      'values' => array(
        'Portal' => 'Portal',
        'Portal:page_1' => 'Portal:page_1',
  $context->reactions = array(
    'block' => array(
      'blocks' => array(),
      'layout' => 'wide',
    'breadcrumb' => 'portal',
    'menu' => 'portal',
......... ?>

Wrap up

Ok, I hope you can learn something from this and maybe the Portal feature is useful to you. Download it and see for yourself. I can also learn from you, so don't hesitate to hit me in the comments.

Joris Snoek


Nóg meer
kennis nodig?

Check ons ons blog archief >