Index: l10n_community/l10n_community.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/l10n_community.module,v
retrieving revision 1.1.2.23.2.66.2.14
diff -u -p -r1.1.2.23.2.66.2.14 l10n_community.module
--- l10n_community/l10n_community.module	31 Mar 2010 13:53:00 -0000	1.1.2.23.2.66.2.14
+++ l10n_community/l10n_community.module	9 Jun 2010 18:27:39 -0000
@@ -703,6 +703,9 @@ function l10n_community_project_uri_by_t
  */
 function l10n_community_theme($existing, $type, $theme, $path) {
   return array(
+    'l10n_community_page' => array(
+      'arguments' => array('page' => NULL),
+    ),
     // pages.inc
     'l10n_community_progress_columns' => array(
       'arguments' => array('sum' => NULL, 'translated' => NULL, 'has_suggestion' => NULL),
@@ -742,6 +745,29 @@ function l10n_community_theme($existing,
 }
 
 /**
+ * Theme an l10n_community summary page with 4 'regions'.
+ */
+function theme_l10n_community_page($page) {
+  $output = '<div id="l10n-community-summary" class="admin clear-block">';
+  foreach (array('top', 'left', 'right', 'bottom') as $container) {
+    if (isset($page['#'. $container])) {
+      $output .= '<div class="'. $container .' clear-block">';
+      uasort($page['#'. $container], 'element_sort');
+      foreach ($page['#'. $container] as $item) {
+        $admin_block = theme('admin_block', $item['#block']);
+        if (isset($item['#classes'])) {
+          $admin_block = str_replace('class="admin-panel"', 'class="admin-panel '. join(' ', $item['#classes']) .'"', $admin_block);
+        }
+        $output .= $admin_block;
+      }
+      $output .= '</div>';
+    }
+  }
+  $output .= '</div>';
+  return $output;
+}
+
+/**
  * Compute language community stats.
  *
  * @param $langcode
Index: l10n_community/pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/pages.inc,v
retrieving revision 1.1.2.20.2.24.2.12
diff -u -p -r1.1.2.20.2.24.2.12 pages.inc
--- l10n_community/pages.inc	26 May 2010 12:15:42 -0000	1.1.2.20.2.24.2.12
+++ l10n_community/pages.inc	9 Jun 2010 18:27:39 -0000
@@ -272,48 +272,64 @@ function l10n_community_overview_project
     return '';
   }
 
-  $output = '<div id="l10n-community-summary" class="admin clear-block"><div class="left clear-block">';
-
   $project = l10n_server_get_projects(array('uri' => $uri));
-  $output .= l10n_community_language_progress_for_project($project, $languages, t('Translations overview'), t('Overall status of translations'));
-
-  $output .= '</div><div class="right clear-block">';
+  $page_structure = module_invoke_all('l10n_community_build_page', 'project', array($project, $languages));
+  drupal_alter('l10n_community_page', $page_structure, 'project', array($project, $languages));
+  return theme('l10n_community_page', $page_structure);
+}
 
-  $block = array(
-    'title' => t('Contribute'),
-    'description' => t('Export, translate, review'),
-    'content' => '<p class="info">'. t('Select a language from the overview to review translations and contribute to the translation efforts. The export tab allows exporting of translation templates, but translations can also be exported on the language pages.') .'</p>'
-  );
-  $output .= str_replace('class="admin-panel"', 'class="admin-panel admin-panel-contribute"', theme('admin_block', $block));
+/**
+ * Implementation of hook_l10n_community_build_page().
+ */
+function l10n_community_l10n_community_build_page($page_key, $params) {
+  if ($page_key == 'project') {
+    list($project, $languages) = $params;
+    $page = array();
+
+    // Stats information on current project status per language.
+    $page['#left'][] = array(
+      '#weight' => 1,
+      '#block' => l10n_community_language_progress_for_project($project, $languages, t('Translations overview'), t('Overall status of translations'))
+    );
 
-  $num_source = l10n_community_get_string_count('project', $project->pid);
+    // Call for contributions.
+    $page['#right'][] = array(
+      '#weight' => 1,
+      '#block' => array(
+        'title' => t('Contribute'),
+        'description' => t('Export, translate, review'),
+        'content' => '<p class="info">'. t('Select a language from the overview to review translations and contribute to the translation efforts. The export tab allows exporting of translation templates, but translations can also be exported on the language pages.') .'</p>'
+      ),
+      '#classes' => array('admin-panel-contribute'),
+    );
 
-  // Get information on releases, and the number of parsed ones.
-  $releases = l10n_server_get_releases($uri, FALSE);
-  $num_parsed = 0;
-  foreach ($releases as $release) {
-    if ($release->last_parsed > 0) {
-      $num_parsed++;
+    // Summary of some interesting data about the project.
+    $num_source = l10n_community_get_string_count('project', $project->pid);
+    $releases = l10n_server_get_releases($project->uri, FALSE);
+    $num_parsed = 0;
+    foreach ($releases as $release) {
+      if ($release->last_parsed > 0) {
+        $num_parsed++;
+      }
     }
-  }
-
-  // Get information on warnings.
-  $num_warnings = db_result(db_query("SELECT COUNT(DISTINCT e.eid) FROM {l10n_server_project} p LEFT JOIN {l10n_server_release} r ON p.pid = r.pid LEFT JOIN {l10n_server_error} e ON r.rid = e.rid WHERE p.uri = '%s'", $uri));
+    $num_warnings = db_result(db_query("SELECT COUNT(DISTINCT e.eid) FROM {l10n_server_project} p LEFT JOIN {l10n_server_release} r ON p.pid = r.pid LEFT JOIN {l10n_server_error} e ON r.rid = e.rid WHERE p.uri = '%s'", $project->uri));
+    $page['#right'][] = array(
+      '#weight' => 2,
+      '#block' => array(
+        'title' => t('@project summary', array('@project' => $project->title)),
+        'description' => t('Some details we know about this project'),
+        'content' => theme('item_list', array(
+          t('Project home') .': '. (!empty($project->home_link) ? ('<a href="'. check_url($project->home_link) .'">'. check_plain($project->home_link) .'</a>') : t('Not available')),
+          format_plural(count($releases), '1 release known', '@count releases known'),
+          format_plural($num_parsed, '1 release parsed', '@count releases parsed'),
+          format_plural($num_source, '1 source string in total', '@count source strings in total'),
+          ($num_warnings == 0 ? t('No source code warnings') : format_plural($num_warnings, '1 source code warning', '@count source code warnings')),
+        ))
+      )
+    );
 
-  $block = array(
-    'title' => t('@project summary', array('@project' => $project->title)),
-    'description' => t('Some details we know about this project'),
-    'content' => theme('item_list', array(
-      t('Project home') .': '. (!empty($project->home_link) ? ('<a href="'. check_url($project->home_link) .'">'. check_plain($project->home_link) .'</a>') : t('Not available')),
-      format_plural(count($releases), '1 release known', '@count releases known'),
-      format_plural($num_parsed, '1 release parsed', '@count releases parsed'),
-      format_plural($num_source, '1 source string in total', '@count source strings in total'),
-      ($num_warnings == 0 ? t('No source code warnings') : format_plural($num_warnings, '1 source code warning', '@count source code warnings')),
-    ))
-  );
-  $output .= theme('admin_block', $block);
-  $output .= '</div></div>';
-  return $output;
+    return $page;
+  }
 }
 
 /**
@@ -356,7 +372,7 @@ function l10n_community_language_progres
     array('class' => 'l10n-community-overview')
   ) .'<div class="clear-block"></div>';
 
-  return theme('admin_block', $block);
+  return $block;
 }
 
 /**
Index: l10n_community/welcome.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/welcome.inc,v
retrieving revision 1.1.2.7.2.17.2.8
diff -u -p -r1.1.2.7.2.17.2.8 welcome.inc
--- l10n_community/welcome.inc	18 May 2010 10:39:43 -0000	1.1.2.7.2.17.2.8
+++ l10n_community/welcome.inc	9 Jun 2010 18:27:39 -0000
@@ -32,7 +32,7 @@ function l10n_community_welcome_page() {
   if ($project = l10n_community_get_highlighted_project()) {
     // Display progress status of the highlighted project.
     include_once drupal_get_path('module', 'l10n_community') .'/pages.inc';
-    $highlight_output = l10n_community_language_progress_for_project($project, l10n_community_get_languages(), t('Translation status for %project', array('%project' => $project->title)), t('Highlighted project'));
+    $highlight_output = theme('admin_block', l10n_community_language_progress_for_project($project, l10n_community_get_languages(), t('Translation status for %project', array('%project' => $project->title)), t('Highlighted project')));
   }
 
   // Build contribution call to action block.
Index: l10n_packager/l10n_packager.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_packager/Attic/l10n_packager.module,v
retrieving revision 1.1.2.4.2.6
diff -u -p -r1.1.2.4.2.6 l10n_packager.module
--- l10n_packager/l10n_packager.module	27 May 2010 08:29:35 -0000	1.1.2.4.2.6
+++ l10n_packager/l10n_packager.module	9 Jun 2010 18:27:40 -0000
@@ -195,7 +195,7 @@ function l10n_packager_create_path($path
 /**
  * Build target filepath from release object based on the set pattern.
  */
-function l10n_packager_get_filepath($release, $language) {
+function l10n_packager_get_filepath($release, $language = NULL, $pattern = NULL) {
    // Get version information from release title
    if ($release->uri == 'drupal') {
      // Core releases are like: 6.1, 6.2, 6.x-dev, 6.x-beta1
@@ -214,7 +214,49 @@ function l10n_packager_get_filepath($rel
     '%core'     => $core,
     '%version'  => $version,
     '%extra'    => !empty($extra) ? '-'. $extra : '',
-    '%language' => $language->language,
+    '%language' => isset($language) ? $language->language : '',
    );
-   return strtr(variable_get('l10n_packager_filepath', L10N_PACKAGER_FILEPATH), $replace);
+   if (!isset($pattern)) {
+     $pattern = variable_get('l10n_packager_filepath', L10N_PACKAGER_FILEPATH);
+   }
+   return strtr($pattern, $replace);
+}
+
+/**
+ * Implementation of hook_l10n_community_build_page().
+ */
+function l10n_packager_l10n_community_build_page($page_key, $params) {
+  if ($page_key == 'project') {
+    list($project, $languages) = $params;
+    $page = array();
+    $releases = l10n_server_get_releases($project->uri, FALSE);
+
+    // Build list of paths by core compatibility for all releases.
+    $paths = array();
+    foreach ($releases as $release) {
+      $release->uri = $project->uri;
+      // @todo: this should not be hard-wired.
+      $paths[l10n_packager_get_filepath($release, NULL, '%core/%project/')] = TRUE;
+    }
+
+    // Generate a list of download links based on that.
+    $url = variable_get('l10n_packager_update_url', file_create_url(l10n_packager_directory()));
+    $list = array();
+    foreach ($paths as $path => $dummy) {
+      list ($core, $name) = explode('/', $path);
+      $list[] = l(t('Translations for @core_version', array('@core_version' => $core)), $url .'/'. $path);
+    }
+
+    // Wrap it in a block.
+    $page['#right'][] = array(
+      '#weight' => -2,
+      '#block' => array(
+        'title' => t('Download translations'),
+        'description' => t('@project translations are available on the following links', array('@project' => $project->title)),
+        'content' => theme('item_list', array($list)),
+      )
+    );
+
+    return $page;
+  }
 }
