[development] core user_login customization -- getting breakout theming AND custom validator working at the same time?

Lee Rowlands leerowlands at rowlands-bcs.com
Thu May 20 22:23:55 UTC 2010


Hi Ben
I think this is overcomplicating it, from what I gather, you've got
everything except the Theming/output/appearance working.
To add new elements to your form, just add them using hook_form_alter, the
$form variable is passed by reference.
In your theme function (#theme), stitch the fields together in the order you
want using drupal_render and make a final call to drupal_render($form)
before returning the output, that way all of the remaining elements
(including form_id, form_build_id etc get rendered).
A good example of Theming a form the way you like it is the user list. E.g.
this function http://api.lullabot.com/user_admin_account builds the form
which is just a huge long list of fields then this function
http://api.lullabot.com/theme_user_admin_account stitches the output
together as a table using selective calls to drupal_render followed by a
final call on the $form element to output the supplementary stuff
Lee

-----Original Message-----
From: development-bounces at drupal.org [mailto:development-bounces at drupal.org]
On Behalf Of Ben DJ
Sent: Friday, 21 May 2010 2:02 AM
To: development at drupal.org
Subject: Re: [development] core user_login customization -- getting breakout
theming AND custom validator working at the same time?

Made progress ... mainly an exercise in what NOT to include from the
various examples out there :-/

hook_alter-ing the user_login form from inside my module
(custom.module), I can correctly replace the local login validation
handler with my own custom handler.

I have validated the switch (simply with, <?php print
print_r($form['#validate']); ?>), and can add my own validation
criteria.

Captcha module integration/use works in display & submission using
standard validator;  I haven't yet figured out how to _move_ the
Captcha validation "into" my custom validator -- that's next ...


In the process of switching to a/my "module-based" implementation,
what gets 'referenced' and what gets  'printed' changes a bit.  i'm
looking for a bit of clarification on the changes ...

in the module-based implementation, instead of

	@ template.php
		--------------------------------------------------
		...
		function get_user_login_form() {
			$form_id = 'user_login';
			$form = array();
			$form['name'] = array(
				'#type' => 'textfield',
				'#maxlength' => USERNAME_MAX_LENGTH,
				'#required' => TRUE,
				'#attributes' => array('tabindex' => '1'),
			...
			$form_state = array();
			drupal_prepare_form($form_id, $form, $form_state);
			drupal_process_form($form_id, $form, $form_state);
			$out = new stdClass;
			$out->form_start =
				sprintf("<form method='post'
accept-charset='UTF-8' action='%s'>",
				url('user/login'));
			$out->form_end = "</form>";
			$out->name = drupal_render($form['name']);
			$out->pass = drupal_render($form['pass']);
			$out->submit =
				drupal_render($form['form_id']) .
				drupal_render($form['form_build_id']) .
				drupal_render($form['submit']);
			return $out;
		}
		...
		--------------------------------------------------

and,

	@ user-login.tpl.php
		--------------------------------------------------
		...
		<?php
			$login_form = get_custom_user_login_form();
				print $login_form->form_start;
					print $login_form->name . '<br />';'
					print $login_form->pass . '<br />';
					print $login_form->submit;
				$login_form->form_end;
		?>
		...
		--------------------------------------------------


I've,

	@ custom.module
		--------------------------------------------------
		...
		function custom_form_alter(&$form, $form_state, $form_id) {
			switch ($form_id) {
			...
				case 'user_login':
				case 'user_login_block':
					$form['name'] = array(
					'#type' => 'textfield',
					'#maxlength' => USERNAME_MAX_LENGTH,
					'#required' => TRUE,
					'#attributes' => array('tabindex' =>
'1'),
					);
					...
					$form['#build_id'] =
sprintf('form-%s', md5(uniqid(mt_rand(), TRUE)));
					$form_state = array();
				break;
			}
		}
		...
		--------------------------------------------------

and,

	@ user-login.tpl.php
		--------------------------------------------------
		...
		<?php
			print drupal_render($form['name']) .'<br />';
			print drupal_render($form['pass']) .'<br />';
			// print drupal_render($form['form_id']) .
			// print drupal_render($form['form_build_id']) .
			print drupal_render($form['submit']);
		?>
		...
		--------------------------------------------------


As a result of NOT declaring a new $login_form object, wherein I've defined

	$out = new stdClass;
	...

and, instead, 'using' the altered, existing user_login form, I've

(1) 'lost' the convenience of object notation,

	...
	print $login_form->name . '<br />';'
	print $login_form->pass . '<br />';
	...

and,

(2) seemingly made unnecessary use of

	x		$out->form_start =
	x			sprintf("<form method='post'
accept-charset='UTF-8' action='%s'>",
	x			url('user/login'));
	x		$out->form_end = "</form>";
			$out->submit =
	x			drupal_render($form['form_id']) .
	x			drupal_render($form['form_build_id']) .
				drupal_render($form['submit']);


Questions:

(A)	How/where would I declare, and use, object notation in the
module-case?

	Simply referencing

			$form->name

	in user-login.tpl.php is clearly not correct/sufficient.

(B)	I'm a bit confused by being able to do without the $form
start/end/form_id/form_build_id, but gather that the Drupal engine,
via use of the native user_login form, is handling that ...

Am I causing any problems by NOT referencing those in my 'new'
module-based approach?

Ben
Internal Virus Database is out of date.
Checked by AVG - www.avg.com 
Version: 8.5.406 / Virus Database: 271.1.1/2686 - Release Date: 02/13/10
19:35:00



More information about the development mailing list