So far I really like the Nodeprofile module, it fits my needs very well. But there is one small problem: The Drupal default "user page" (the one that displays how long you've been a member) still exists, and is separate from the Nodeprofile page. And wherever the user's name appears, like in the "authored by" line, it links to that user page, not the Nodeprofile page. I'd like to make these two pages one and the same, a single entity, so that the user page IS the Nodeprofile page. Is there any way to accomplish this?

Comments

thomie’s picture

*Either use the Bio module instead of Nodeprofile, which has an option to completely take over the user page. Drawback: it's not possible to integrate with registration procedure.
*Read Michelle's tutorial.

Grantovich’s picture

Thank you for pointing me to the Bio module, I will try it out as soon as I am able. Integration with the registration process is not a major concern, so it should work fine. In the meantime I have a question about it: On my profile pages, the hard-coded field for the name of the node (usually "Title") will be called something like "Real Name". Is there a way I can replace the display of usernames everywhere on the site with the "Real Name" of the corresponding profile page? The Authorship module does something similar, but using fields defined by the built-in Profile module.

thomie’s picture

http://groups.drupal.org/node/4200
If you have the user's realname specified in you cck content type, you should use Fago's comment and change the code a bit. You could also use core Profile module for a user's realname, and then use the code as is.

Grantovich’s picture

The Bio module isn't quite working out for me due to various small things. Let's try a second tack: Assuming I'm okay with having the Nodeprofile page and the user page be two separate things, as long as it's impossible for anonymous users to access the user page (i.e. "authored by" links pointing to the user page should go to the Nodeprofile page instead). The only way to access a user page would be if I explicitly link to it. Can that be done? I'm thinking that would allow me to use the nodeprofile_load thing and get the proper names, too.

Grantovich’s picture

Anyone? I am pretty much clueless here and I don't really know PHP (at least not to the degree I would need to understand this). I couldn't even find any other references to that function.

Also, does anyone know where the code is that cuts off a username after a certain length? I will need to raise that limit if I ever get to the point where I can display real names for the "authored by" links.

thomie’s picture

I thought I had posted this.

If Bio module doesn't work for you, try to go through Michelle's tutorial. The link is in one of my posts above. You can really learn a lot from reading the tutorial and trying to understand the code that comes with it, even though you maybe don't want to use all of it like guestbook/buddylist. There's also a forum there with lot's of questions and answers about these issues.

Something you might need from the tutorial, step 3: Take over the user account view tab. And step 11: Redirect usernode / nodeprofile.

Hope that works, good luck.

Grantovich’s picture

As I said, I'm no longer aiming for taking over Drupal's user page, precisely because it involves so many changes to different areas. At this point I have figured out that simply overriding the theme_username function should give me exactly what I need. Unfortunately I have no idea how to locate the correct profile node to link to, or how to pull the title from that node to use as the link text. Any advice in that direction?

EDIT: Also, re-reading from the link you posted earlier, it looks like the mysterious nodeprofile_load function is key. But I can't find any other references to this function in the whole site, not even the documentation for the Nodeprofile module! Clearly more research is required...

thomie’s picture

..that function does not exist, he probably meant node_load().

Try this: put the following code in your template.php. I'm assuming you're using CCK to make your nodeprofile. In the code, change 'your_profile_type' into the name of the content type you're using. And replace the part after 'field_' in the string 'field_your_profile_field' into the name of the CCK field that you are using for the user's full name. So if that field is called 'fullname', than you would substitute 'field_your_profile_field' by 'field_fullname'.

/**
 * @param $object
 *   The user object to format, usually returned from user_load().
 *   But can also be a node!
 * @return
 *   A string containing an HTML link to the user nodeprofile
 */
function phptemplate_username($object) {
  // *** Replace username of user everywhere with user's full name.
  // Make links to users always to user nodeprofile instead of userpages, 
  // if exists, and supply appropriate link_text.
  // From template.php in usernode.module.
  if (!empty($object->uid)) {
    // Load nodeprofile
    $nodeprofile = node_load(array('type' => 'your_profile_type', 'uid' => $object->uid)));
    if ($nodeprofile) {
      // Get realname of user.
      $name = $nodeprofile->field_your_profile_field[0]['value'];
      $link = 'node/'. $nodeprofile->nid;
      $link_text = 'Go to the nodeprofile of this user.';
    }
    else {
      // Nodeprofile does not exist.
      $name = $object->name;
      $link = 'user/'. $object->uid;
      $link_text = 'Go to the userpage of this user.';
    }
    if (user_access('access content')){
      $output = l($name, $link, array('title' => $link_text));
    }
    else {
      $output = check_plain($name);
    }
  }
  else if (!empty($object->name)) {
    // Sometimes modules display content composed by people who are
    // not registered members of the site (e.g. mailing list or news
    // aggregator modules). This clause enables modules to display
    // the true author of the content.
    if ($object->homepage) {
      $output = l($object->name, $object->homepage);
    }
    else {
      $output = check_plain($object->name);
    }

    $output .= ' ('. t('not verified') .')';
    return $output;
  }
  else {
    $output = variable_get('anonymous', 'Anonymous');
    return $output;
  }
}

Let me know if this works.

Grantovich’s picture

Check here and search for "function nodeprofile_load":
http://cvs.drupal.org/viewcvs/drupal/contributions/modules/nodeprofile/n...

It looks strikingly similar to your line above that starts "$nodeprofile =", but there is some comment about caching, which sounds nice. At any rate, thank you very much for that code, I will certainly try it out and see how it goes. I will need to make a small change though, because I am using the hard-coded Drupal "Title" field as the "real name". I assume there would be some change to the "$name = $nodeprofile->" line but I'm not sure about the function of the things in brackets.

thomie’s picture

you're right, it does exist then. But only in the development version, not in the current version of Nodeprofile yet. Anyway, doesn't really matter, node_load() should also work fine.

(But if you want speed, using the core profile module for a user's realname is another way to go, and nodeprofile for the other stuff like you're doing right now. That way you wouldn't have to load a node every time you need to display a username/realname. The user's realname is then part of the $user object, and this is already loaded most of the time. That's what I did at least, but I don't know if this is really faster, and that caching of nodeprofile might be good also. You'll know what to change if you want to use nodeprofile_load() later.)

About your node title (sorry for not reading correctly), you can use: $name = $nodeprofile->title;

A very handy trick is to put this: print_r($nodeprofile) temporarly in you template.php after the line with node_load(), to see which fields this object holds. You'll see title as one of the fields.

We will get this to work eventually.

Grantovich’s picture

I used this code:

function gmodified_username($object) {
  // Make links to users always use nodeprofile instead of userpages,
  // if exists, and supply appropriate link_text
  if (!empty($object->uid)) {
    // Load nodeprofile
    $nodeprofile = node_load(array('type' => 'profile', 'uid' => $object->uid));
    if ($nodeprofile) {
      // Get title of profile page for "real name"
      $name = $nodeprofile->title;
      $link = 'node/'. $nodeprofile->nid;
      $link_text = 'Go to profile page';
    }
    else {
      // Profile page does not exist
      $name = $object->name;
      $link = 'user/'. $object->uid;
      $link_text = 'Go to user page';
    }
    if (user_access('access content')){
      $output = l($name, $link, array('title' => $link_text));
    }
    else {
      $output = check_plain($name);
    }
  }
  else if (!empty($object->name)) {
    // Sometimes modules display content composed by people who are
    // not registered members of the site (e.g. mailing list or news
    // aggregator modules). This clause enables modules to display
    // the true author of the content.
    if ($object->homepage) {
      $output = l($object->name, $object->homepage);
    }
    else {
      $output = check_plain($object->name);
    }

    $output .= ' ('. t('not verified') .')';
    return $output;
  }
  else {
    $output = variable_get('anonymous', 'Anonymous');
    return $output;
  }
}

The only changes to your original code were the "$name =" line, changing the 'type' to 'profile' to match my content type, and changing the link title attributes (you also had one too many parentheses in the node_load line). When I insert this code in my template.php, all usernames disappear! At least, any usernames that are normally handled by that theme function, which is most of them. There just isn't anything there. I specifically tested it on a page authored by a user who had a profile page, but still nothing.

thomie’s picture

we need to return the $output, so add

  return $output;

before the last bracket.

If it's still not doing what you want it to do, you need to further debug the code. Use for example

drupal_set_message('name = '. $name);

after the $name =$nodeprofile->title; statement, to see if something is pickup up. I always put these drupal_set_messages everywhere to see what happens, and act accordingly.

Grantovich’s picture

Shows you how long I've been dealing with PHP. Anyway, it works brilliantly now, thank you very much! And the "node" link is automagically converted to its associated URL alias! (I'm really happy that took care of itself) I even managed to add an extra feature so if you're logged in as user #1, you will see the real username next to the profile name in brackets, and you can click it to go to the old Drupal user page. Here's the final code:

function gmodified_username($object) {
  // Make links to users always use nodeprofile instead of userpages,
  // if exists, and supply appropriate link_text
  if (!empty($object->uid)) {
    // Load nodeprofile
    $nodeprofile = node_load(array('type' => 'profile', 'uid' => $object->uid));
    if ($nodeprofile) {
      // Get title of profile page for "real name"
      $name = $nodeprofile->title;
      $link = 'node/'. $nodeprofile->nid;
      $link_text = 'Go to profile page';
    }
    else {
      // Profile page does not exist
      $name = $object->name;
      $link = 'user/'. $object->uid;
      $link_text = 'Go to user page';
    }
    if (user_access('access content')){
      $output = l($name, $link, array('title' => $link_text));
      if ($nodeprofile && $GLOBALS['user']->uid == 1) {
        $output .= ' ' . l('['.$object->name.']', 'user/'.$object->uid, array('title' => 'Go to user page'));
      }
    }
    else {
      $output = check_plain($name);
    }
    return $output;
  }
  else if (!empty($object->name)) {
    // Sometimes modules display content composed by people who are
    // not registered members of the site (e.g. mailing list or news
    // aggregator modules). This clause enables modules to display
    // the true author of the content.
    if ($object->homepage) {
      $output = l($object->name, $object->homepage);
    }
    else {
      $output = check_plain($object->name);
    }

    $output .= ' ('. t('not verified') .')';
    return $output;
  }
  else {
    $output = variable_get('anonymous', 'Anonymous');
    return $output;
  }
}
thomie’s picture

Glad I could help.

Next thing you probably want is user picture links being links to nodeprofile nodes also. You need the theme_user_picture() function from user.module for that, with basically the same modifications. So copy it and put it in your template.php, rename it to gmodified_user_picture() or something, and replace "user/$account->uid" by "node/$nodeprofile->nid" (hey, I didn't know you could concatenate 2 strings like that), after first loading the nodeprofile again. Optionally also change the username into realname in $alt like before.

Anyway, good luck, you'll probably be able to figure it out.

Grantovich’s picture

The current site design does not require user pictures, so I'm all set there. Now I have a completely different problem to deal with, which unfortunately is extremely tricky (though I hope it's possible because it's a super-critical feature that's preventing my site from going live). If you have any knowledge to contribute there, it would be greatly appreciated.

lias’s picture

Hi there,
I came across your post and was bummed because you didn't post the code for pointing the user pictures to their nodeprofiles rather than to the core profile. I'm hoping you can help me out as I took your advice and used the following (changed "user/$account->uid" to "node/?nodeprofile->nid" but when I click on the link it isn't correct and points instead to just "domain.com/node/"

function isky_user_picture($account) {
  if (variable_get('user_pictures', 0)) {
    if ($account->picture && file_exists($account->picture)) {
      $picture = file_create_url($account->picture);
    }
    else if (variable_get('user_picture_default', '')) {
      $picture = variable_get('user_picture_default', '');
    }

    if (isset($picture)) {
      $alt = t("@user's picture", array('@user' => $account->name ? $account->name : variable_get('anonymous', t('Anonymous'))));
      $picture = theme('image', $picture, $alt, $alt, '', FALSE);
      if (!empty($account->uid) && user_access('access user profiles')) {
        $picture = l($picture, "node/$nodeprofile->nid", array('title' => t('View user profile.')), NULL, NULL, FALSE, TRUE);
      }

      return "<div class=\"picture\">$picture</div>";
    }
  }
}

I didn't use the username code in my template.php file and maybe I need that for this code to work? I also didn't understand what you meant by "loading the nodeprofile again?"
Thanks.

edited:
nevermind, I changed the url to point to member/$account->name and that worked (possibly because I have pathauto enabled?)

jmlavarenne’s picture

In case this is useful, this is what I did to solve this.

I use all the nodefamily modules to manipulate user info. My user_profile.tpl.php contains only the following code :

<?php
	
	// Get usernode nid
	$nid = usernode_get_node_id($user->uid);
	$nodeView = node_load($nid);
	print node_view($nodeView);

?>

So when a user clics on "my account" in the menu, or whenever "?q=user/some_uid" is queried, the usernode associated with his uid is displayed. All theming happens in the node-usernode.tpl.php file.

liliplanet’s picture

subscribe

lias’s picture

Hi Blackguard, I'm not using usernode but do use nodeprofile. How would I make your code work for nodeprofile nodes? Do I replace usernode with nodeprofile or the name of the content type I'm using for nodeprofile for users?

<?php
   
    // Get nodeprofile nid
    $nid = nodeprofile_get_node_id($user->uid);
    $nodeView = node_load($nid);
    print node_view($nodeView);

?>

Thanks.

jmlavarenne’s picture

No I don't think there is such a function as nodeprofile_get_node_id().

My post is about how to make the user/ page display the content of the nodeprofile.

And by the way I just found out it is better to use node_prepare() instead of node_load() - node_prepare passes the data throught filters.

pacome’s picture

I'm actualy trying to insert some user nodeprofile fields (cck) at the top of user's blog page : author name field, wich can be different than user name, and a file field wich link to a .pdf cv/portfolio. Then, the blog will follow....

I have the feeling that I can re-use some code from this topic, but I don't know which part.

Do you have any suggestion ?
I've also posted a topic about that here : http://drupal.org/node/222126

[edit] I finaly found something easier, not yet completely functional, but on a good way (link above)

jmlavarenne’s picture

use


echo "<pre>";
print_r ($node);
echo "</pre>";

in your node-blog.tpl.php file. This will let you see all your fields and how they can be accessed.

It will often be something like $node->fieldname[array_index][array_key].

pacome’s picture

Thanks !

A friend found another solution, I first made a node-blog.tpl.php with the following code in it :

$output = nodeprofile_show_profiles($uid);
     echo drupal_render($output);

But finaly the nodeprofile was printed on every post (I guess node.blog.tpl.php set what's happen for every blog/post because they are nodes). The solution was to put it in a page-blog.tpl.php file...

Here is the code we finaly use :

 if (arg(0) == 'blog') {
                $o = array();
                $o[$type] = array(
		                  '#type' => 'nodeprofile_display_full',
			          '#title' => '', 
			          '#tabs' => '', 
			          '#uid' => arg(1),
			          '#content_type' => 'your-content-type-name',
			          '#weight' => 0,
			          '#suffix' => '',
			   );
		print drupal_render($o);
				
              }
       

And it works : we have the nodeprofile at the top of the blog page, with only the cck fields, and without the generic title..