I'm trying to override template_preprocess_user_profile(&$variables) in template.php.
But i always get an empty profile. I copied the user-profile.tpl.php to the theme directory.
It runs through my overridden function phptemplate_preprocess_user_profile(&$variables) but $variables['user_profile'] comes out empty.
I've traced the problem to drupal_render($variables['account']->content[$key]);
it seams drupal_render just doesn't render the content. ($variables['account']->content[$key] data is correct).

And I've noticed both functions get called template_preprocess_user_profile(&$variables) from user.pages.inc and phptemplate_preprocess_user_profile(&$variables) from template.php. The first generates some content but then the second gets executed and turns out empty.

Maybe because the both get called?

I have content profile, badges, user points and bookmarks installed.

Comments

moshe weitzman’s picture

Status: Active » Closed (works as designed)

Once drupal_render renders something, it marks it as #printed = TRUE and any future calls to drupal_render() will not do anything.

DizzyC’s picture

i thought so...
but then why does template_preprocess_user_profile(&$variables) run when i have it overriden in template.php?

Craftsman’s picture

Status: Active » Closed (works as designed)

I have the same problem. $variables['profile'] contains only titles of categories. I’ve just copied template_preprocess_user_profile() body (from here http://api.drupal.org/api/function/template_preprocess_user_profile/6 ) in mytheme_ preprocess_user_profile() and I didn’t change anything.

I want to change content of category (add some new variables and so on), what I’m doing wrong?

Craftsman’s picture

Status: Closed (works as designed) » Active
manuel.adan’s picture

Status: Closed (works as designed) » Active

Hi,

As far I can see, drupal 6 theme engine call each preprocess function defined for a hook. theme() function in includes/theme.inc responsible code is:

652    if (isset($info['preprocess functions']) && is_array($info['preprocess functions'])) {
653      // This construct ensures that we can keep a reference through
654      // call_user_func_array.
655      $args = array(&$variables, $hook);
656      foreach ($info['preprocess functions'] as $preprocess_function) {
657        if (function_exists($preprocess_function)) {
658          call_user_func_array($preprocess_function, $args);
659        }
660      }
661    }

Documentation about overriding themable output suggest that only one preprocess function is called, and it should be so, in order of better performance and easy developing. I'm not an expert in drupal, so I'm not sure if it may be a bug in theme() function.

In the meantime, a way to solve it is unset '#printed' and call drupal_render again in the own theme preprocess function, something like this:

  foreach (element_children($variables['account']->content) as $key) {
    
    $c = $variables['account']->content[$key];
    if ($c['#printed']) {
      unset($c['#printed']);
    }
    
    $variables['profile'][$key] = drupal_render($c);
  }
matt v.’s picture

I ran into the same problem. I started to use adan's workaround from comment #5, which seemed to be working; but ultimately I decided to implement the changes I needed in a custom module instead.

Dropper’s picture

I had the same problem and your solution works perfectly. Thanks a lot!

netsensei’s picture

Same issue. Adan's solution works.

tbartels’s picture

The documentation actually clearly states that the registered preprocessors are "run in order": http://drupal.org/node/223430, also at the bottom of the list describing the preprocess order there is a note about a similar issue:

There is an unfortunate design flaw/bug in the theme system when a theme is part of a base theme/sub-theme hierarchy. Any preprocess functions prefixed with engineName_preprocess will be run multiple times (once for each theme in the hierarchy) instead of just once. Not only is this wasting resources, it can also cause difficult-to-debug errors.

The bug for this particular preprocessor is actually the timing of drupal_render, there isn't any good way that I know of to reverse the full effect of a drupal_render. e.g. If you want to modify/edit child elements you will be SOL without unsetting the #children element recursively since drupal_render will use #children before trying to build new rendered HTML.

Presently, I do not have a satisfactory fix.

I think the thing to understand is that preprocessors are not overrides like those you might be used to from drupal 5.

mdupont’s picture

Category: Bug report » Support request
Issue summary: View changes
Status: Active » Closed (works as designed)

Template files are overriding each other (so the most specific works) but preprocess functions are run in order (from the most generic to the most specific), so you should not copy / paste code from one another, you should only do changes on the already preprocessed data. If you re-run drupal_render() in your preprocess and it has already be run before you will encounter issues such as the one you are describing. However the theme system works as designed. Closing this old issue.