Today I noticed the following comment in project_release.module:

/**
 * Returns the appropriate release download table for a project node.
 * TODO: this should be themeable.
 */
function project_release_project_download_table($node) {

I happened to be working on making it possible to easily show all releases of a project in the download table on both the projects overview page and the individual projects pages.

The attached patch adds this functionality. It changes project_release_project_download_table() to theme_project_release_project_download_table() in project_release.module, allowing that function to be themed.

The patch also creates a new function theme_project_release_table_overview(), which essentially acts as a themeable wrapper that calls project_release_table(). This makes it possible to theme the download table shown on the overview page in a different way than those shown on individual project pages. For example, the overview page might be set to display all release nodes by overriding theme_project_release_table_overview(), and the individual project pages set to show all official releases but only the default versions of development snapshots by overriding theme_project_release_project_download_table().

The patch also changes the calls in project.module and project.inc to the new themed versions.

Comments

drewish’s picture

StatusFileSize
new3.01 KB

here's a re-roll with less of the whitespace changes.

dww’s picture

Status: Needs review » Needs work

This seems wrong in project.inc:

-    if (function_exists('project_release_project_download_table')) {
+    $project_table_output = theme('project_release_project_download_table', $node);
+    if (!empty($project_table_output)) {

That used to effectively test if project_release.module was enabled. Now, it's not really testing anything. I guess I don't know what theme() does if you ask it for something that there's no implementation of. But, this at least needs some clarification (ideally, via a comment in the code), if not actual correction.

Also, this comment isn't true:

+ * Theme function that calls theme_project_release_table 

Otherwise, I'm a little uneasy about the basic approach of this change. I still get nervous about making "theme" functions out of insanely logic-heavy functions. Seems to cloud the "logic vs. presentation" barrier. My naive view of theme functions is that they should be handed a bunch of data that represents all the logic, and they just convert that blob of data into the appropriate output. Here, we're basically punting all the logic and presentation directly to the themer, which just seems wrong.

Of course, I've never tried to write my own theme, or do any more than the most basic theme modifications to any of my sites, so I'm definitely not an authority on these issues. But from my high-level, conceptual understanding of the theme layer, this seems a little dirty. ;)

Comments from those who know more about this than I do are most welcome...

aclight’s picture

Status: Needs work » Needs review
StatusFileSize
new2.73 KB

That used to effectively test if project_release.module was enabled. Now, it's not really testing anything. I guess I don't know what theme() does if you ask it for something that there's no implementation of. But, this at least needs some clarification (ideally, via a comment in the code), if not actual correction.

If a theme function isn't implemented, nothing bad happens--the function call just returns nothing. So in this case, no release table is printed but there are no error messages either on the page or in the logs. I added a comment to the code to reflect this.

Also, this comment isn't true:
+ * Theme function that calls theme_project_release_table

This is now fixed

Otherwise, I'm a little uneasy about the basic approach of this change. I still get nervous about making "theme" functions out of insanely logic-heavy functions. Seems to cloud the "logic vs. presentation" barrier. My naive view of theme functions is that they should be handed a bunch of data that represents all the logic, and they just convert that blob of data into the appropriate output. Here, we're basically punting all the logic and presentation directly to the themer, which just seems wrong.

I don't think that the theme functions themselves are actually that logic heavy. Of course, they call a logic heavy function (project_release_table()) but I don't see any other reasonable way to do it.

For example, on my site, I have this override:

/**
 * * Causes the project_download_table on the individual project pages
 *   to include ALL official releases and the DEFAULT versions of development releases
 *
 * * Displays a note on the project page if there are no releases for the project
 * * Adds a repository URL link if the project uses subversion
 *
 */
function phptemplate_project_release_project_download_table($node) {
  if (!$node->releases) {
    return;
  }

  $output = '<h3>' . t('Releases') . '</h3>';
  $official_release_table = project_release_table($node, 'all', 'official', t('Official releases'));
  $snapshot_release_table = project_release_table($node, 'default', 'snapshot', t('Development snapshots'));

  if (empty($official_release_table) && empty($snapshot_release_table)) {
    $output .= '<h3><strong>There are currently no releases for this project.</strong></h3>';
  }
  else {
    $output .= $official_release_table;
    if ($node->snapshot_table) {
      $output .= $snapshot_release_table;
    }
  }
  if (project_use_cvs($node)) {
    if ($node->cvs_repository == 2) {   // standard svn.example.com repository
      $repository_link = 'svn://svn.example.com'.$node->cvs_directory; 
    }    
    if ($repository_link) {
      $output .= '<div class="SVN_repository_link"><h3>Subversion Repository:</h3>  &lt;a href=&quot;&#039;. $repository_link .&#039;&quot;&gt;&#039;. $repository_link .&#039;&lt;/a&gt;</div>';
    }
  }
  
  $links = array();
  $links[] = l(t('View all releases'), 'node/'. $node->nid .'/release');
  if (project_check_admin_access($node->nid)) {
    $links[] = l(t('Add new release'), 'node/add/project_release/'. $node->nid);
  }
  $output .= theme('item_list', $links);
  return $output;
}

It wouldn't be possible to do this without modifying the module itself unless a theme function is added.

aclight’s picture

StatusFileSize
new3.01 KB

sorry---#3 was the wrong version of patch

dww’s picture

Ok, I guess that's all reasonable. Patch visually looks clean. I'll give this a little testing and get it in later today if all goes well. ;)

dww’s picture

Status: Needs review » Fixed

Cleaned up some of the phpdoc comments and 1 tiny whitespace change -- I usually don't like the extra whitespace to make things line up in FAPI array definitions:

-        '#value' => project_release_project_download_table($node),
+        '#value'  => $project_table_output,
         '#weight' => 1,

That's totally subjective, but personally, I don't tend to prefer it. ;)

Anyway, tested, and committed to HEAD. Again, don't think I'll backport this to DRUPAL-4-7--2.

Thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)