Anthony McLin

Custom User Login Block on Drupal 6 Zen sub-themes

I was trying to override the login block displayed on one of my Drupal sites and I kept running into a lot of trouble. No matter what functions I tried overriding in my template.php, nothing was displaying. All the tutorials I could find online didn't take into consideration the specifics of using a Zen subtheme. Hopefully my guide here will avoid this problem.

This guide was particularly useful, but it didn't account for using a Zen subtheme, and neither did this one.

Add the hook_theme() function

The first step in all the guides is to implement the hook_theme function. This function lets you signal to Drupal what core functions your template will override. If you're using a Zen subtheme, this has already been done for you. In your template.php, look for the following:

/**
 * Implementation of HOOK_theme().
 */
function STARTERKIT_theme(&$existing, $type, $theme, $path) {
  $hooks = zen_theme($existing, $type, $theme, $path);
  // Add your theme hooks like this:
  /*
  $hooks['hook_name_here'] = array( // Details go here );
  */
 // @TODO: Needs detailed comments. Patches welcome!
  return $hooks;
}

If you setup your theme properly, you should have already replaced STARTERKIT above with the safe name of your theme. As written, this function checks for overrides from Zen:

$hooks = zen_theme($existing, $type, $theme, $path);

What we're going to do is add additional function overrides to the list provided by Zen. On the next line, add the following:

$hooks['user_login_block'] = array(
 	'arguments' => array('form' => NULL),
  );

This tells drupal to look for a new function called STARTERKIT_user_login_block(). The full STARTERKIT_theme() function should look like this. Don't forget to replace STARTERKIT with your theme's safe name.

/**
 * Implementation of HOOK_theme().
 */
function STARTERKIT_theme(&$existing, $type, $theme, $path) {
  $hooks = zen_theme($existing, $type, $theme, $path);
  $hooks['user_login_block'] = array(
  	'arguments' => array('form' => NULL),
  );
  // Add your theme hooks like this:
  /*
  $hooks['hook_name_here'] = array( // Details go here );
  */
  // @TODO: Needs detailed comments. Patches welcome!
  return $hooks;
}

Override the form preparation function

We now have everything in place to tell Drupal to look for our custom overrides for the User Login Block. The next step is to add the overrides using a theme_user_login_block() function. At the end of your template.php file, add the following function (again, remember to swap STARTKERKIT with your theme's name):

/**
 * Override the return of the User Login Block form
 * @param $form
 *   An array representing the form
 */
function STARTERKIT_user_login_block(&$form) {
	// Modify the text of the submit button
	$form['submit']['#value'] = t('Login Now!');
	return (drupal_render($form));
}

Now all you need to do is save your file, rebuild your theme registry and flush any theme caches (the admin_menu module makes this easy), and you should be displaying the modified form!

Advanced theming

But what if I want to do more than just change the text or values of some of the form elements? What if I need to modify the HTML output to display the user login form block the way I want? This is relatively easy. Since we already used theme_hook() to indicate to Drupal that we are overriding the form preparation function, we can also tell Drupal to look for a template file instead of displaying its normal output. In your theme_hook() function, find the line we created that starts with 'arguments' and add this line after it:

    // Template file, ex: user-login-block.tpl.php
    'template' => 'user-login-block',

This tells Drupal that not only are we overriding the form preparation function, but we're also providing a template file that should be used called user-login-block.tpl.php. Your full theme_hook() function should now look like this:

/**
 * Implementation of HOOK_theme().
 */
function STARTERKIT_theme(&$existing, $type, $theme, $path) {
  $hooks = zen_theme($existing, $type, $theme, $path);
  $hooks['user_login_block'] = array(
        'arguments' => array('form' => NULL),
        // Template file, ex: user-login-block.tpl.php
        'template' => 'user-login-block',
  );
  // Add your theme hooks like this:
  /*
  $hooks['hook_name_here'] = array( // Details go here );
  */
  // @TODO: Needs detailed comments. Patches welcome!
  return $hooks;
}

Since we'll be providing our own template file, the theme_user_login_block() function we previously created will no longer work correctly. Instead, we'll need to create a theme_preprocess_user_login_block() function so that our changes to the $form structure will be inserted before the template file is processed. Find your theme_user_login_block() function at the bottom of your template.php file and replace it with this:

/**
 * Override the form pre-processing to include our changes
 * @param $vars
 *   An array of variables to pass to the theme template.
 */
function STARTERKIT_preprocess_user_login_block(&$vars) {
	// Modify the text of the submit button
	$vars['form']['submit']['#value'] = t('Login Now!');

	$vars['form_markup'] = drupal_render($vars['form']);
}

Now, in your template folder, add a new file, user-login-block.tpl.php Whatever you put in this file will be used to output the form, just like any of your other template php files. Again, simply clear your caches and theme registry, and you should see this file working. Here's an example of my user-login-block.tpl.php file:

Categories: 

Comments

This article rules! Thank you for being so thorough!

this is the clearest explanation of this topic that I've found. Thanks so much.

perfect tutorial, thank you

- bill_baroud (not verified)

I have followed your instructions to a T but cannot get anything to display, no matter what. Every time I add the new function command I get a syntax error which I also cannot figure out. If you have any ideas it would be much appreciated! Thanks.

- nick (not verified)

nick wrote:
I have followed your instructions to a T but cannot get anything to display, no matter what. Every time I add the new function command I get a syntax error which I also cannot figure out. If you have any ideas it would be much appreciated! Thanks.

Without seeing your exact error, there's not much I can recommend other than to double-check everything, make sure you don't have any missing parenthesis or semi-colons. A syntax error generally means a coding typo.

- Anthony McLin

Hi there! Thank for the great tut!

One note- in Zen 7.0 there was no STARTERKIT_preprocess_user_login_block() and no user-login-block.tpl.php, but yours worked!

And,

Anthony, it appears that some of your code did not come through properly, in particularly, a couple ampersands are showing up as "&-amp;" html codes. That may be why nick was experiencing syntax errors. I copy & pasted part of your code, and I was getting a syntax error because of the "encoded" ampersand.

Thanks for the great tutorial! I've been searching high and low, and this solved my problem for me.

- Tim Mackey (not verified)

Tim Mackey wrote:
in particularly, a couple ampersands are showing up as "&-amp;" html codes. That may be why nick was experiencing syntax errors. I copy & pasted part of your code, and I was getting a syntax error because of the "encoded" ampersand.

Thanks for the clarification Tim. Chalk this one up to Joomla + TinyMCE's lousy code cleanup. I've gone back and edited the original article to fix the encoded HTML entities and TinyMCE inserted code, as well as changed my site styling a little bit to better prevent this problem in the future. Good catch!

valk wrote:
in Zen 7.0 there was no STARTERKIT_preprocess_user_login_block() and no user-login-block.tpl.php, but yours worked!

I haven't yet looked into Drupal and Zen 7. This is specific to Drupal 6. I'm sure much has changed between versions now that Drupal 7 is out.

nicely clarified thanks

- kannetkeifer (not verified)

Hi Anthony. Thanks for the tutorial. Everything makes sense to me, and should work, but I get this returned after reloading my site.

# warning: include(./sites/all/themes/zen_fedlabs/user-login-block.tpl.php) [function.include]: failed to open stream: No such file or directory in /home/fedlabs/public_html/includes/theme.inc on line 1066.

# warning: include() [function.include]: Failed opening './sites/all/themes/zen_fedlabs/user-login-block.tpl.php' for inclusion (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/fedlabs/public_html/includes/theme.inc on line 1066.

I'm still in the process of learning how drupal works.

I have not changed my template.php file from the default STARTERKIT code (save the renaming of STARTERKIT to my sub-theme name), except for the two areas you called attention to above.

Any insight you can give would be much appreciated.

- jason (not verified)

Hope you don't mind me spamming a link, but I've just written an article on a similar subject for Drupal 7 login blocks (using the Bartik theme, it's mostly about making the registration link more prominent, but covers general theming a little).

The article is: Get more sign-ups from Drupal 7: make ‘Create new account’ eye catching.

Cheers!

- Liam McDermott (not verified)

Hi, when stuck in my mind and ask google and found this article, very detail and nice tough, anyway i want to theming the drupal register block (made by formblock module) so in this article using "user_login_block", where you know the variable to put in the hooks ?

thanks

Nice tutorial, thanks! Just one thing - I had to make a small amendment to store the template in the templates/ subdirectory:

'template' => 'templates/user-login-block',

Greetings from Indiana.

It turned out that the method you used for the separation of each form element is exactly what I needed. The build_id was something I kept trying to figure out how to extract from the back-end, but your code made it a pretty simple feat--that is, once I found your code!

Thanks again.

Wonderful tutorial! I have this worked on my drupal 6

- htcbug (not verified)

There's an extra closing curly brace in the full version of the theme_hook() function under "Advanced Theming" that completely blanks the site.

- Daniel (not verified)

Good catch Daniel. I've removed the extraneous }

- Anthony McLin

Add new comment