Let's write a browser inside the browser, in Javascript!
making profile.module appear in places it doesn't want to
Out of all the modules in Drupal Core, Profile has always seemed me to be the most half-assed. It's clear that something needs to happen to it — using CCK field types at the least, maybe removing profile data from the user object, and, if I had my way, permanently node-ifying users. I haven't poked around Drupal 6 as thoroughly as I ought to, but based upon what I've heard from Phil's writeup and the Lullabot podcast, I may have to wait a bit longer to see meaningful change come to Profile.
So others may find themselves in the situation I did yesterday for a bit longer: trying to embed a profile form somewhere that Profile.module doesn't think it ought to go — for instance, yesterday I needed to let users edit their name and address on their user_profile page, rather than expecting them to mess around with a bunch of tabs and only-vaguely-different categories.
You'd think there'd be a way to call drupal_get_form() to collect your users' addresses and names whereever you might care to. But you'd be wrong, so far as I can tell — profile.module acts as a user.module parasite, accomplishing what it does through hook_user() and the abuse of arg().
But it's very easy to re-wrap Profile's form-generating functions in your own module and then call drupal_get_form() against it. Here's the example that I came up with:
/*
WRAPPER FUNCTIONS FOR PROFILE.MODULE FORM
The profile form is usually only available on the user editing form.
Some wrapper functions are necessary to make it work elsewhere.
*/
function mymodule_profile_form($user,$category)
{
if(module_exists('profile'))
{
$user = user_load(array('uid' => $user->uid));
$edit = array();
foreach($user as $key => $value)
if(preg_match('/^profile_/',$key))
$edit[$key] = $value;
$form = profile_form_profile($edit, $user, $category);
// now let's pretend we're in hook_form_alter
// add a submit button
$form['op'] = array
(
'#type' => 'submit',
'#value' => t('Submit'),
);
// pass along the $category parameter as a hidden value
$form['category'] = array
(
'#type' => 'hidden',
'#value' => $category,
);
return $form;
}
}
function mymodule_profile_form_validate($form_id,$form_values)
{
if(module_exists('profile'))
{
/* do any necessary custom validation here */
return profile_validate_profile($form_values, $form_values['category']);
}
}
function mymodule_profile_form_submit($form_id,$form_values)
{
global $user;
if(module_exists('profile'))
{
$r = profile_save_profile($form_values, $user, $form_values['category']);
// reload the user with the newly-saved info
$user = user_load(array('uid' => $user->uid));
return $r;
}
}
You can call all of this with a simple drupal_get_form('mymodule_profile_form','Personal Information') — if "Personal Information" is the profile category that you wish to get a form for.
Of course, what'd be really nice is for profile.module to provide wrapper functions like this natively. Maybe there's another way to skin this cat, but at the moment I think this is the option that users are facing.






Comments
thanks for this!..can tell me how to implement this? make a new module called mymodule.module?
thanks!
r
having some trouble getting this to work..made a module called mymodule, enabled it and made the call:
?php print drupal_get_form('mymodule_profile_form','About Me')?>
all i get is a submit button!
any help would be greatly appreciated.
thanks
r