Hi,

I am working on a module which will display more info in user's page(user-profile.tpl.php).
(Yes, hook_user_view is another option, but I want to put my HTML code in tpl files)

I have the following in my module:

function mymodule_theme_registry_alter(&$theme_registry) {
  $theme_registry['user_profile']['theme path'] = drupal_get_path('module', 'mymodule').'/theme';
  $theme_registry['user_profile']['path'] = drupal_get_path('module', 'mymodule').'/theme';
  $theme_registry['user_profile']['theme paths'] = array(
    0 => drupal_get_path('module', 'mymodule').'/theme',
  );  
}

The above will override the user's module template, and I can have my own template file in:
mymodule/theme/user-profile.tpl.php

My problem is, I cannot override my module template under the theme folder. The following file is now ignored:
mytheme/user-profile.tpl.php

How can I have my template file in my module and have the options for the others to override in their theme?

Many thx!

Comments

jaypan’s picture

May I suggest a different method, that still allows you to use a template file, and will prevent the issue you are having?

I find it's best not to override system generated themes as much as possible. The reason for this is that when you override the system, you are essentially freezing it in time, because any updates to the code will not be used by the system anymore. This could theoretically introduce security errors, though in this case it's somewhat doubtful.

Anyways, what you can so is still use hook_user_view(), but you just add your own data using your own template. I'm going to show you the D6 way, because I haven't worked with overriding user pages on Drupal 7 yet, so the syntax may have changed a little in D7, but the overall idea is still the same even in D7.

In D7, you will use hook_user_view(), but in D6, we had to use hook_user() with an $op of view:

function mymodule_user($op, &$edit, &$account, $category = NULL)
{
  if($op == 'view') // equivalent to hook_user_view() in D7
  {
    $work_stuff = array // The data to be added to the user page
    (
      'profession' => t('Ninja'), 
      'skills' => t('Hiding'),
    );
    $account->content['mymodule_data'] = array // syntax may be different in D7
    (
      '#value' => theme('mymodule_data', $work_stuff), // Theme the data. This will be done using a template file (see below)
    );
  }
}

In the above code, some data was generated in the variable $work_stuff, and added to the $account->content array after being passed through a theming function. The theming function is registered in hook_theme() (D7 also uses hook_theme()) as follows:

function mymodule_theme()
{
  $path = drupal_get_path('module', 'mymodule') . '/templates';
  return array
  (
    'mymodule_data' => array // mymodule_data is the theme name we used in hook_user()
    (
      'arguments' => array
      (
        'work_stuff' => array(),
      ),
      'path' => $path,
      'template' => 'mymodule-data', // template names use hyphens instead of underscores, and don't include .tpl.php
    )
  )
}

Registering the theme function above means that we can now use the template [MODULE PATH]/templates/mymodule-data.tpl.php to theme the data:

mymodule-data.tpl.php

<h2>Profession</h2>
<p><?php print $work_stuff['profession']; ?></p>
<h2>Skills</h2>
<p><?php print $work_stuff['skills']; ?></p>

This will theme the data added in hook_user() using a template file. In Drupal 7, the process is much the same:

1) Implement hook_user_view(), and generate your data
2) Run your data through a theme function, and add the data to the $account->content array.
3) Register theme function you used in step 2, setting the data to be outputted to a template
4) Create the template file, theming the data how you want.

By doing this, you are not bypassing any of Drupal's APIs (and are in fact using the right ones), which can prevent unexpected issues in the future as you start adding 3rd party modules or updating core etc.

Contact me to contract me for D7 -> D10/11 migrations.

franfran’s picture

Thank you for your detail explanation, appreciated.

I didn't think of #value => theme() in hook_user_view()

I tried your suggestion, it can render successfully, but I cannot override it in the theme folder.
I am using Drupal 7.

function mymodule_user_theme(){
  return array(
    'mymodule_profile' => array (
      'variables' => array('myvar' => NULL),
      'template' => 'user-profile-test',
      'path' => drupal_get_path('module', 'mymodule') . '/theme',
    )
  );
}

function mymodule_user_view($account){
  $account->content['mymodule'] = array(
    '#markup' => theme('mymodule_profile', array('myvar' => 'test')),
  );
}

I have the theme file in mymodule/theme/user-profile-test.tpl.php. And the above works without any problem.
However, if I put another file in mytheme/user-profile-test.tpl.php, clear cache, it couldn't pickup.

Thanks in advance.

jaypan’s picture

Hmm, I don't have an answer for that (though I admit, I'm curious). Anyways, this is a new topic, different from your original, so I would recommend starting a new thread for this problem.

Contact me to contract me for D7 -> D10/11 migrations.

g089h515r806’s picture

I have the same problem in breadcrumb2 module.

Chinese drupal tutorials Think in Drupal

g089h515r806’s picture

I have fixed this issue, http://drupal.org/node/1873856 .Template file provided by hook_theme_registry_alter() could not be override in theme layer.

Chinese drupal tutorials Think in Drupal