Hiya guys,

Have gone through the php template handbook and I understand the principles of what it does, but, I'm stumped on implementation.

What I would like to do is override the layout of the user profile pages (I think thats what they are called..it's when someone views a user profile - the layout of where the user picture, name etc. goes)

I'm not clear on how to do this...do I simply create a profile.tpl.php file with my new layout + php snippets to call up the fields?

how do I invoke my new profile.tpl.php layout override?

Do I simply upload it to my themes directory?

This is what the handbook says:

If you want to override a theme function not included in the basic list (block, box, comment, node, page), you need to tell PHPTemplate about it.

To do this, you need to create a template.php file in your theme's directory. This file should contain the required tags, along with stubs for the theme overrides. These stubs instruct the engine what template file to use and which variables to pass to it.

A template.php file already exists in my themes engine directory...but I can't decipher how to tell where to put these "stubs" or what stubs are or how to "tell php template" about my new override.

Bamboozled, baffled & braindead!

Any help or guidance appreciated..

Jason

Comments

Steven’s picture

It is explained on the rest of that page:
http://drupal.org/node/11811

Each stub is the piece of code which tells phptemplate about your override.

Dublin Drupaller’s picture

Hi Steven/guys...

Need help with the following if anyone can help...

I'd like to change the layout of the user profiles pages (When you view a users account details).

But I'm not sure where to start.

At the moment, for examplek the layout is two columns. on the left is a list of details like this:

------------------------------------------------------
NAME:
Joe Drupal

[Send private message]

[Add to buddylist]

Occupation:
Drupallier

Company:
Drupal R US

Address1:
22 main street

Address2:
Drupalville

Postcode:
drpl 1C00l

Telephone:
+44 1234567899

Fax:
+14235464474747

Country:
UK

Website:
www.drupal.org

-------------------------------------------------------

And in the right hand column is the persons picture.

It all looks okay, but, I'd like to change the layout to be more compact. I.e.

---------------------------------------
Joe Drupal
Drupalier

Drupal R US
22 Main street
Drupalville
drpl 1C00l
UK

tel +44 1234567899
fax. +14235464474747
www.drupal.org

[Send private message]
[add to buddylist]

---------------------------------------------------

With the picture on the right hand side...

So it's very simple stuff..but i haven't got a clue where to start.

Anyone know whether I am better of tackling this

a) via the stylesheet?
b) via php template and creating an override (I'm using php template)?
c) Via hacking the profile/user module?

This may appear to be a stupid question. probably is.

I'm a newbie to this stuff and am so thick I make jessica simpson look street wise and savvy...

I'm just finding my feet on where to do stuff with drupal and am stumped on how I approach the user profiles thing...

Thanks for taking the time out to read this and any suggestions are welcome..

Jason

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

Dublin Drupaller’s picture

see above

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

The profile module contains the following theme_ function:

function theme_profile_profile($user, $fields = array()) {
     
  $output  = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $user);
  $output .= ' <div class="name">'. format_name($user) ."</div>\n";
      
  foreach ($fields as $field) {
    if ($value = profile_view_field($user, $field)) {
      $output .= " <div class=\"field\">$value</div>\n";
    }
  }
  
  $output .= "</div>\n";
   
  return $output;
}

As mentioned on the page that Steven referenced, you'll want to override that theme in your template.php file. It would look something like this:

/**
* Catch the theme_profile_profile function, and redirect through the template api
*/
function phptemplate_profile_profile($user, $fields = array()) {
  // Pass to phptemplate, including translating the parameters to an associative array. The element names are the names that the variables
  // will be assigned within your template.

  /* potential need for other code to extract field info */

  return _phptemplate_callback('profile_profile', array('user' => $user, 'fields' => $fields));
}

Now you can create that magic profile_profile.tpl.php file and design the layout. You have the $user and $fields variables to work with. You will likely need to do some logic on the fields array to get the ordering you want.

So, the key learning here is to look at the functions in the target module that begin with "theme_" -- these are the ones that can be overriden, and in general always control the output of the module.

Dublin Drupaller’s picture

Boris,

Thank you so much for the tip..the penny has dropped....I understand how to do it now..

mega thanks..

J

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

Dublin Drupaller’s picture

Hi Boris/anyone...

Thanks again for the tip re: overriding the profile theme...am having difficulty in going to the next stage, i.e. playing with the profile array to re-order them in a more manageable way.

i.e. you said:

Now you can create that magic profile_profile.tpl.php file and design the layout. You have the $user and $fields variables to work with. You will likely need to do some logic on the fields array to get the ordering you want.

I'm having trouble in working this out. I'm not a php expert which is obviously a weakness when trying to do something like this, but, if someone could point me in the right direction on how to manipulate the profile field array in a new profile_profile.tpl.php, it would be appreciated.

Cheers anyone who has any guidance/tips..

Jason

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

I haven't looked at the $fields array in detail, but if you look at the foreach loop, you have the $field variable (which is the label/id of the field) and it's $value.

So, instead of just blindly looping through all the fields, figure out which field names correspond to which bits of information, and then append them to the output in the order you want them.

e.g.

$output .= "<div>Company ".$fields["company"]."</div>";)

Repeat for all fields you want values for. Try doing a print_r on the fields array to see what the labels are for the different fields. I *believe* they map to the field label (e.g. often profile_company) in the user -> profile configuration pages.

Dublin Drupaller’s picture

HI Boris,

I managed to work out how the whole thing works. Appreciate you're help. Took me a while as I had to learn a bit how php operators work with html...and once I got that sussed it was a matter of CSS tweaking.

To override just the layout of the User Profile pag..I created a template.php file with this in it:

>
/**
* Catch the theme_user_profile function, and redirect through the template api
*/
function phptemplate_user_profile($user, $fields = array()) {
  // Pass to phptemplate, including translating the parameters to an associative array. The element names are the names that the variables
  // will be assigned within your template.
  /* potential need for other code to extract field info */
  return _phptemplate_callback('user_profile', array('user' => $user, 'fields' => $fields));
</php 

I uploaded that into my active theme directory and then created and uploaded, to the same directory, the override layout file which is called user_profile.tpl.php.

A very simple/shortened example of how my user_profile.tpl.php works maybe illustrated as follows....(e.g. I have setup custom extended user profile fields called profile_city, profile_country, profile_postcode)....

<div class="custom_profiles">
<div class="fields">City: <?php print $user->profile_city ?></div>
<div class="fields">Country: <?php print $user->profile_country ?></div>
<div class="fields">POstcode: <?php print $user->profile_postcode ?></div>
</div>

While I'm at it...(am chuffed I actually got this far with your help)...just thought I would paste a more detailed example of what you can do on here as well....the following puts a link in a users profile page to an Aerial (sattelite) picture of their house/office automatically....if the user is from the UK.

It's very simple and the map/aerial camera knows which longtitude and lattitude to pick up via the postcode.


<?php print $user->profile_background ?></div><br>



// The following line checks if the person is from the UK

<?php if (($user->profile_country) == "UK" : ?>

// If the answer is YES, a link is automatically placed in the profile page that displays an aerial/sattelite picture of their street using their postcode

<div class="fields">

<a href="http://www.multimap.com/map/browse.cgi?cat=h&amp;scale=5000&amp;pc=<?php print $user->profile_postcode ?>" target="_blank">Street Map/Aerial Camera/Directions to <?php print $user->profile_name ?>.</a>

</div>

<?php endif; ?>

Hope thats of help to others...who are as thick as me and as new to php as I am and are trying to override themes using phptemplate.

Dublin Drupaller..

_________________________________________________
A drupal user by luck and a dubliner by the grace of god.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

Very cool! Want to point us to a live instance of this so we can see for ourselves?

Dublin Drupaller’s picture

Am using it on a test project at the moment. It's not yet completed, but, when it is I'll post a link.

The Multimap/satellite camera thing is nothing to do with me...it's done by another company..to see an example and you know someone from England.. replace the postcode at the end of the following url and click on the link:

http://www.multimap.com/map/browse.cgi?cat=h&scale=5000&pc=[insert postcode here]

here's a link to the street map & satellite shot of my office in Manchester:

http://www.multimap.com/map/browse.cgi?cat=h&scale=5000&pc=OL161NR

(click on the Aerial camera icon for the satellite photo of the street)

It's amazing when you think they have satellite shots of (almost) every street in the UK...a little scary..

Cheers

Dublin Drupaller
_____________________________________________________
A drupal user by luck and a dubliner by the grace of god.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

Dublin Drupaller’s picture

As an after thought...i notice they have maps for the USA as well...and the rest of europe..not sure how much they have covered with satellite pictures...

Dublin Drupaller..

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

I've used MultiMap before. Was more interested in the final result, and to show people I'm not crazy, you CAN theme profile pages :P

Dublin Drupaller’s picture

okay..sorry..thought you meant a final example of the multimap link (I've just discovered it by the way)..

I'm using it for a test site at the moment..which is a members only thing..so it's not easy to link across to..I'll look to see if I can post a screenshot up here though..

cheers

Dublin Drupaller

A drupal user by luck and a dubliner by the grace of god.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

Dublin Drupaller’s picture

Quick one..

Just noticed that when I apply the user_profile.tpl.php override, it not only overrides the layout..it overrides the user_access settings.

Have you come across that before Boris?

Cheers

Dub

___________________________________________________
A drupal user by luck and a dubliner by the grace of god.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

Dublin Drupaller’s picture

Boris,

I don't know how to upload images with a post...but here are a BEFORE and AFTER screenshots from a testsite I'm working on at the moment...it's login members only and unfinished so I can't simply link to the site yet..

BEFORE
This is how the out-of-the-box user profile looks like, with extra profile fields, such as City, Country, Postcode, Position etc. added in. (please note that i couldn't fit teh whole page into the one screenshot..there is an extra "background/more info." field that doesn't show in the BEFORE screen shot.

click to view the BEFORE screenshot in a new window

AFTER
This is how the exact same user profile looks after overriding the theme and applying a simple user_profile.tlp.php file in my theme directory.

click to view the AFTER screenshot in a new window

I hope that is of use Boris...bottom line is that it is extremely simple to over-ride the drupal pages and tweak the layout of pages. So designers, don't be put off by what you see in the DRUPAL SITES list...I can't understate how new I am to php and sql...but even I was able to achieve the above...If I can do that ANYONE can...believe me. And once you have that override...it is completely skinnable using CSS..so the php stuff is minimal, the real work is in the CSS and style sheet layout stuff...i.e. colours, spacing, alignment etc.

by the way...how do I include those screenshots within my post?

I'm tempted to create a BOOK PAGE in the theme override section of the handbook. and explain in simple 1,2,3 steps how I achieved the above. It would make more sense to include before and after pics in a book page like that instead of clicking across to an external link..

Do you know how to do that?

Cheers

Dublin Drupaller..

--------------------------------------------------------
A drupal user by luck and a dubliner by the grace of god.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

Looks great!

Creating a book would be very helpful. Just go to create content > book page and create your page. You won't have permission to make it go live immediately, but I'll watch for it and improve it.

One note: while theming basic profile information is very easy, including data from OTHER modules (e.g. buddylist, private messages, image gallery, etc. etc.) is pretty much impossible today without some major contortions. I'm going to start some developer discussions about this, and hopefully we'll have something like user_profile_buddylist.tpl.php (and corresponding $buddylist value accessible via user_profile.tpl.php).

Kudos to you for sticking through the whole process. Do you have a homepage/weblog I can point to when I write this up? And contact me if you want to talk about mass-hosting of specialized label/band websites :P

Dublin Drupaller’s picture

Hi Boris,

It's funny you should mention the buddylist, private message and other stuff..I'm at that stage now..i.e. integrating the override to work with other and subsequent modules.

I think I'll wait until I have the above sussed..i.e. the user_profile override also includes other modules and stuff..before creating the book page..as the stage I'm at is only STAGE 1 of 3..

STAGE 1: Overriding the layout of extended profile fields in the User Profile Page.

Stage 2: Creating and listing the strings and functions from other existing modules that would affect the user_profile pages....like view image gallery...does this user have private messages?..how long a member, contact lists, address boooks etc. etc.

Stage 3: Create a book page reference of php operators and simple instructions on how to tap into or pull relevant data from the other modules in a template override override.tpl.php file.

It will be a while before I get to stage 3....but..will follow through when I get the time.

you're not crazy by the way....the php template override thing works amazingly brilliantly simply....it just took me freakin ages to get my head around it. Which is more to do with my inexperience with php than anything else. Once the proverbial penny drops...it is incredibly simple to start moving stuff around the page.

A designers dream...!

Hopefully more people will start to use phptemplate with overrides and drupal sites won't all end up looking the same. Which is already beginning to happen...I was looking at Xoops and other CMS systems and what put me off was the fact that every Xoops /phpnuke/mambo site looks the bloody same!

There is nothing wrong with that..but, it doesn't take that much time to put a bit of thought into innovative navigation or cleverer use of the DIV tags.

The php Template theme and engine opens up that door...I can't gush enough about it's potential and simplicity. Perhaps there should be a designers corner on here - seperate from the theme developers forum - that would push out the envelope a little in terms of drupal designs.

I'm going to setup a drupal help corner or weblog on my site for artists/bands/labels....I have spent the last few months evaluating cms software and drupal comes out way on tops for artist/band/label site community development.

Also, one of our team has been looking at plugging flash into drupal...i.e. using flash as the front end or "skin" to a drupal site. It's very early stages, but we know it works and opens up the doors to very high impact and skinnable drupal sites using flash talking to Drupals database.

Just to clarify that..its using Flash purely as a "skin" or the interface..how people move around a drupal driven site..allowing people to move away from "kitchen sink" style sites where every link to every where is on the screen.

It will all be free open source stuff.....and very specific to artists/bands/label applications ...will send you a link when we have it up.

Cheers.

Dub

___________________________________________________
A drupal user by luck and a dubliner by the grace of god.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

tag-1’s picture

If you haven't already, you'll definitely want to check out:

http://www.terminus1525.ca/

The guy who put it together is around this site often. Can't remember his name. The site is amazingly well-done.

dumell’s picture

With the advice on this page, I managed to put together a custom user profile page. But I too wanted to add the "add to buddylist". This is my solution. It allows you to add. Either figure out how to remove or how to get along :)

  if ($user->uid != $GLOBALS["user"]->uid && user_access('maintain buddy list')) {
    echo "<a href=\"/buddylist/".$GLOBALS["user"]->uid."/add/".$user->uid."\">add to buddylist</a>";
  }
scarer’s picture

Hi,

I tried to add this to my custom user profile in drupal 5.1 and it doesn't seem to work. It cannot find the path. I commented out the if statement so it would display the link.

  if ($user->uid != $GLOBALS["user"]->uid && user_access('maintain buddy list')) {
    echo "<a href=\"/buddylist/".$GLOBALS["user"]->uid."/add/".$user->uid."\">add to buddylist</a>";
  }

Any help on getting this working would be great.

Cheers,

Sarah

Dublin Drupaller’s picture

Just thouht I'd flag this here in case any1 else is trying to do the same....when you override the theme functions you also override the user access.

i.e. if you have a drupal site that has logged-in-user only information...it may not be a good idea to use phptemplate overrides...I haven't found a workaround yet for my user_profile.tpl.php override...will post it up here if I get lucky.

Any drupal php experts out there willing to give the phptemplate engine a once over to see if there are any other crucial and basic elements missing? Assume if the user_access thing has slipped through..it's likely that there are other issues overlooked.

thanks in advance for any help..

Dub
___________________________________________________
A drupal user by luck and a dubliner by the grace of god.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

When you pull PHP code directly, it's straight code -- it doesn't pass through any user access layer. This is "by design" -- it is thought that if you can handle pulling info directly, you also know how to manually do user_access checks to check for permissions.

With great power, comes great responsibilty :P

Dublin Drupaller’s picture

Cheers Boris,

I understand the flexibility side of phptemplate. it is truly great.

Haven't looked at the user_access issues in detail...but am I right in thinking that i can include an IF statement at the top of the override.tpl.php file to see if the user is autrhorised or not?

Or is it more involved than that?

Dub

___________________________________________________
A drupal user by luck and a dubliner by the grace of god.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

In profile, you might have half private, half public fields. Basically, you need to check if the field is private (viewable only by user whose profile it is) or public then compare to the current user.

Same for permissions of viewing other items, like buddylist -- check the appropriate permission and see if the current user has that permission.

I've actually flagged this as an area that needs some work. No idea when we'll see improvements, but I'm going to bring it up at the conference.

Dublin Drupaller’s picture

Hi Boris,

Just thought I'd mention I have sorted the protected content & overrides thing. i.e. check if the user is logged in BEFORE invoking the override in the template.php file.

Not sure if it is of use to you...but it maybe useful for other PHP newbies or designers who want to unleash the power of drupal using PHPTEMPLATE overrides and implement sophisticated designs.

http://drupal.org/node/16821

On the subject of half private & half public fields..I understand what you mean and I'll be playing with that later on to see what I can do. Especially with arrays. Wll post back up here if I have any success.

Dub
___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

JohnG-1’s picture

Dub,

is that link a joke or has something gone wrong :?

I get an access denied page (and yes I am logged in:)

Ian Ward’s picture

Hi all,

I've used a combination of the examples outlined on this page on www.nextbillion.net. I also made a few changes to what appears on nextbillion.net/profile. what do you think? A partial inspiration are the profile pages over here at http://www.digitaldivide.net/profile/francisraven which is based on zope/plone, for example. In Drupal, I like the way you can tab over to the 'track' tab to see latest posts, and then identify the type of post and awaiting comments in the table view of the tracker module. Check it out here: http://www.nextbillion.net/user/17. With 'track' data in a tab (default display in 4.5), it keeps the main profile page nice and tidy as compared to the digitaldivide.net example.

You can also see how we called up the private messenger and add-to-buddylist in www.nextbillion.net/profile if you are signed into the page. Also, we added the titles for the profile_fields which are now visible on /profile, which helps out a lot. We need to do some things like add a tab to when you are viewing a listing of someone's buddies or 'buddies of' which will take you back to the user's profile, like at http://www.nextbillion.net/buddylist/17/buddiesof you can see you are kinda stuck on that page if you get to it from the user's profile page.

venkat-rk’s picture

I like the way you give anonymous users access to the user profile at http://www.nextbillion.net/user/17

But, how did you remove the Home>>user account breadcrumbs? When I followed your example to give anonymous users access, it also gives them access to the user account itself and also to the admin:
http://www.ciosa.org.in/beta2/profile/meeven

Ian Ward’s picture

Hey all,
I've got another idea, which relates to how to display profile information, but also how to display flexinode fields - using tabs. I explain how it would work w/ flexinode over here http://drupal.org/node/21763 and imagine something similar could work w/ profiles. I am going to try a few things now...I just want to look at right now if I could get this display simply by overriding the theme to display the fields of one flexinode type on multiple sub pages and using tabs to go back and forth...
Ian

amanda’s picture

I got all excited about this, but realized that I am relying heavily on the "member list pages" that show all users who share the same value (say ... "waiting for a plot" in our garden, or "available to open the garden" on a particular day of the week.)

I have sniffed around but I can't figure out how to retain the links to member lists when I customize the profile display.

Any suggestions?

Thanks!
Amanda

Dublin Drupaller’s picture

Hi Amanda..

Not sure if I can help...but which module produces the links for you?

You might be able to lift the php loop that generates those links and insert it in your user_profile.tpl.php file...

Hope that helps..

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

amanda’s picture

The links are created by the profile module itself. I've sniffed through the module but I can't figure out where the loop that generates the links is.

Ian Ward’s picture

It should be the function theme_profile_profile

This should work on the comma separated lists for the user profiles like it is here: http://www.mobileactive.org/profile when you click on someones Fields of Interest.

skenliv’s picture

I just tried to test this, but the result is no changes.
The page looks like it did before...

How should the CSS look?

Maybe you could zip up the theme u are using, so that i could look thru the
changes myself?... That would really help!!

Dublin Drupaller’s picture

Hiya Sven,

Tried using your contact form to email you, but it's not working. That would really help!

The CSS isn't what controls the override, it's a combination of the
template.php & user_profile.tpl.php.

Here's a quick checklist:

(a) you must be using a phptemplate based theme.

(b) unless you are using drupal 4.6 I think you need to "refresh" the theme by going to ADMIN -->> THEMES -->> CONFIGURE and saving the configurations. As discussed here: http://drupal.org/node/11819

The PHPTemplate package contains example template files for all of these. Simply copy them into your theme/mytheme directory and edit them. Note that you will need to visit administer > themes for PHPTemplate to refresh its cache and recognize any new .tpl.php files.

(c) If the above doesn't work.. switch on your CONTACT FORM so I can email you the user_profile override that I have created.

Hope that helps

Dub

DUBLIN DRUPALLER
___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

skenliv’s picture

.. so id be more than happy if you could send over the
override files that you have created.

There just seems to happen nothing, and ive really tried everything.

And yes, im using PHPTemplate as the engine. With the Persian Theme.

ron collins’s picture

note: there are a few errors in DD's example above. follow here for the corrected code and filenames.

thanks for this work dd. phptemplates really rock. the more i learn about them, the more i love them.

lluvia’s picture

Ups! Fixed!

freyquency’s picture

Another thing to consider is optional fields - for example:

<?php if($user->profile_bio !=""): ?>
<div class="user_bio"><?php print $user->profile_bio ?></div>
<? endif ?>

would only show the field if it were filled in.

I'm having trouble getting this to work with the 'freeform lists' when they are left blank.

<?php if($user->profile_employer !=""): ?>
<div class="user_employer"><?php print $user->profile_employer ?></div>
<? endif ?>

produces

array

when left blank. it works with it filled in though. can anyone offer any tips for this?

... ps - it's also good code form I guess because phptemplate is coded with if / endif statements.

[]+][+][+[]
erik mallinson
http://coacalina.org

boris mann’s picture

It looks like the freeform lists are actually kept in an array, so testing against the empty string won't work. Try just doing if (! $user->profile_empoyer).

freyquency’s picture

That's what I was originally going for, but it didn't work either. Here's exactly what I wrote in case I'm missing a typo:

<?php if(! $user->profile_employer): ?>
<div class="user_employer"><?php print $user->profile_employer ?></div>
<?php endif ?>

[]+][+][+[]
erik mallinson
http://coacalina.org

boris mann’s picture

You're going to make me actually try this on live code, aren't you? :P

If it *always* displays as an array when it's actually empty, then try doing ! is_array($user->profile_employer) (go look up if that is the correct function -- I know there is one, just don't recall what it's called exactly).

freyquency’s picture

didn't work for me, guess i'll just give up on drupal.

...just kidding, gotta go to work. ;D

i'll have a little more time to spend on it later...

Dublin Drupaller’s picture

Hi Erik,

Was following your post. Am just wondering if the following will work for you.

<?php if($user->profile_employer): ?>
<div class="user_employer">
<a href="/profile/profile_employer/<?php print $user->profile_employer ?>"><?php print $user->profile_employer ?></a>
<?php endif; ?>

Basically it creates the freeform link for you....

Dub
___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

freyquency’s picture

i think there should be be something like a foreach / endforeach in there, wrapped around the link tag... but only had time to tinker for a moment.

ultraBoy’s picture

This should work

<?php if(count($user->profile_employer)): ?>
<div class="user_employer"><?php print $user->profile_employer ?></div>
<?php endif ?>
freyquency’s picture

Okay, first of all I made a mistake in what was printing array. It was actually printing 'array' when I was trying to print a 'birthdate' line, using the same formatting as the previous lines. I didn't think it was that because directly afterwards I had 'astrological sign' - which when I looked at it was similar enough to 'birthdate' that my brain didn't filter the problem. :) So the date field isn't printing basically.

The two different methods of calling the array for the freeform list seem to work the same, which is cool:

			<?php if (! is_array($user->profile_employer)): ?>
			<div class="user_employer"><?php print $user->profile_employer ?></div>
			<?php endif ?>

and this one:

			<?php if ($user->profile_employer !=""): ?>
			<div class="user_employer"><?php print $user->profile_employer ?></div>
			<?php endif ?>

Now onto the problem of printing each line or CSV of the freeform list. I can't seem to get foreach to output anything. for example:

			<?php if ($user->profile_profession !=""):?>
			<div class="user_profession">
				<? print $user->profile_profession ?>
				<ul>
				<?php foreach ($user->profile_profession as $profession_link):?>
				<li><a href="/profile/profile_profession/<? print $profession_link ?>" title="title here"><? print $profession_link ?></a></li>
				<?php endforeach ?>
				</ul>
			</div>
			<?php endif ?>

You'll notice on the third line I have it just print the contents of the freeform list, that's for testing purposes, to make sure it prints. But anything within the foreach it will not print.

I also noticed that I was getting error messages in the log for this problem,

warning: Invalid argument supplied for foreach() in /"my account path"/public_html/themes/griffin_phptemplate/user_profile.tpl.php on line 22.

Line 22 being the beginning of the foreach statement. I've looked over the foreach documentation quite a bit and haven't noticed anything that would tell me that I'm doing something wrong. The only thing I could think of is that it's not being stored as an array. If I just wrap the print $user->profile_profession it links to the whole thing as a link. But drupal is obviously got it right, so what am I missing?

[]+][+][+[]
erik mallinson
http://coacalina.org

Dublin Drupaller’s picture

Hi Erik,

As a mini disclaimer - I'm not a PHP expert...but I have been following your post and thought I would offer a suggestion for an alternative way of accessing the array...i.e. counting the contents of the array and running a FOR loop based on that..i.e.

$count_total = count($user->profile_profession);
  for ($counter=0; $counter<$count_total; $counter++)
  {
   $line = each ($user->profile_profession);
  <li><a href="/profile/profile_profession/<? print $line ?>"     title="title here"><? print $line ?></a></li>";
  }

i.e. the count_total is the number of items in the $user->profession array.

Hope that works for you....

Dub..

___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

freyquency’s picture

DD,

nope i modified it a little to get the html for the list item either in a print command or inside a for /endfor statement (i tried both), but it didn't work.

I got this in the error log

warning: Variable passed to each() is not an array or object in /"my path"/public_html/themes/griffin_phptemplate/user_profile.tpl.php on line 22.

so i'm thinking that any call to a user->*freeform list* isn't an array, or that it has to be more specific? perhaps i should create a new forum post around the specific issue and report back here, since it's a question of what freeform list is. then we can figure out how to customize the display...

[]+][+][+[]
erik mallinson
http://coacalina.org

Dublin Drupaller’s picture

I think you're right.they are not stored as an array but are just one field where each link is sperated by a comma or line break....

I looked at the profile.module to see how it does it and here's the code:

 $values = split("[,\n\r]", $value);
        $fields = array();
        foreach ($values as $value) {
          if ($value = trim($value)) {
            $fields[] = $browse ? l(drupal_specialchars($value), "profile/$field->name/". check_url($value)) : drupal_specialchars($value);
          }

I'm obviously guessing...(I'm not a php expert), but it looks like the profile module loads the freeform list value into an array based on comma(,) or line breaks (/n).

In which case you could try:


$temp_array = explode(",",$user->profile_profession);
$count_total = count($temp_array);
for ($counter=0; $counter<$count_total; $counter++)
{
$line = each ($temp_array);
<li><a href="/profile/profile_profession/<? print $line[value] ?>" title="title here"><? print $line[value] ?></a></li>";
}

Hope that makes sense and works.... the explode thing will put the contents into a temp_array for you, iusing the comma (,) as the seperator.

Dub

___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

freyquency’s picture

...it's ... well it didn't work, it's tough to say exactly what's doing what as i worked on this for about 8 hours total today. let's just say that the code above got me somewhere... I've tried explode and also split, in combination with for or foreach and had mixed results... I've gotten "array" to spit out multiple times, and i've had the whole list as one list item as well... but i'll provide more feedback as to what is doing what when I get a chance.

I took a break from this issue for a while to work on the general look of things, and ran into another roadblock, this one may be much easier. Displaying the user picture (avatar). DD what did you call for what you have in the screenshot? I can use user->picture to spit out a URL, which displays the relative path of the pic from the main directory, but I think the problem may lie in that I use 'private' file mode, with a path inside my root directory, ie- not inside 'public_html'... so I cannot get the path to work. Also in a different template it's pulled up /system/files?file=pictures/picture-1 so i cannot just work around a file path. Also, it may be my permissions that are an issue, as I discovered that even with my hosting username and password I am not allowed into the pictures folder. It's owned by drupal. ?

[]+][+][+[]
erik mallinson
http://coacalina.org

Dublin Drupaller’s picture

Hi Erik,

Will be interesting to see what was happening with the array code. don't forget to post up here if you get it working.

To answer your question...the code that produces the output for showing a user picture is as follows:

(please note: it checks to see if a user has one...if the user has one..it displays it...if a user doesn't have one, it displays a default "no picture" type image to give the page a balance.)

<?php if($user->picture): ?>
<div class="picture">
<img src="/<?php print $user->picture ?>">
</div>
<?php endif; ?>
 
<?php if(($user->picture) == ""): ?>
<div class="picture">
<img src="/files/pictures/blank1.jpg">
</div>
<?php endif; ?>

I hope that is of use.

By the way, Erik, have you worked out how to check user access when implementing an override?

The overrides work very well, but, I discovered that it also overrides the user access settings...i.e. anyone can view a user profile...even though user access is not enabled for anonymous users.

Cheers

Dub

___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

adrian’s picture

Wherever permission checking happens inside a theme_* function (and you know.. practically, I think it is bad form), you will need to do the same in the template.

You can check the solution at the bottom of the page (http://drupal.org/node/14466#comment-27786)

--
The future is so Bryght, I have to wear shades.

Dublin Drupaller’s picture

nice one...

thanks for the contribution....and ace job on phptemplate by the way...am just getting to grips with it.

2 Quick questions while you are here...

Q1. I'm playing around with overriding the user profile page....and while I have worked out how to extract and position extended profile fields..am wondering how I go about pulling in the other fiekds...such as "add to buddy list"..."view image gallery"..."send private message" etc.. Can you point me in the right direction on that front or am I better off hard-coding in the extra user profile fields myself?

Q2. Once I have the Q1 thing nailed, I'm going to have a bash at overriding the EDIT forms for the user profile to make them a bit more user friendly. Can I use PHP Template for that? or do I need to play with the forms.module?

(Apologies in advance if the above are stupid questions...am a newbie to php and the rest, appreciate any guidance or pointers..)

CHeers

Dub

Dublin Drupaller
___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

freyquency’s picture

Adrian, thank you, especially since you've been out of commission a few days, it's much appreciated, and hope you're doing better.

I've not been able to get the path to picture correct with my setup. I've got 'private' permissions enabled and the directory where files upload is below 'public_html', aka file and public_html are in the same folder. I'm not sure if that's the cause of the trouble. I've been able to access files there for the e-commerce module, so I know the directory will work, and that ../../ sort of stuff will work with the relative path. Honestly though i'm a bit bewildered with this problem and quick to be frustrated by it; so i may be missing something.

as for the original problem, displaying freeform lists, i'm stuck there as well, and i haven't been able to work on picture galleries or anything as such.

[]+][+][+[]
erik mallinson
http://coacalina.org

wtrenker’s picture

Adrian, I picked up on your advice here:

Wherever permission checking happens inside a theme_* function (and you know.. practically, I think it is bad form)

I would appreciate your thoughts on what constitutes good form in this instance. What is the Drupal-intended way of handling rendered content as a function of permissions?

Thanks,
Bill

robertdouglass’s picture

Drupal uses theme_* functions throughout its code base. What Adrian was saying is that all user access calls should be taken care of before they get called. This is the module coder's responsibility, not the themer's. For example, in the profile.module, one finds this function:

function theme_profile_listing($user, $fields = array()) {

  $output  = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $user);
  $output .= ' <div class="name">'. format_name($user) ."</div>\n";

  foreach ($fields as $field) {
    if ($value = profile_view_field($user, $field)) {
      $output .= " <div class=\"field\">$value</div>\n";
    }
  }

  $output .= "</div>\n";

  return $output;
}

Note the call to profile_view_field($user, $field)? Let's look inside that function. The first three lines tell the whole story:

function profile_view_field($user, $field) {
  // Only allow browsing of private fields for admins
  $browse = user_access('administer users') || $field->visibility != PROFILE_PRIVATE;

What the module's author should have done is make the theme function like this:

function theme_profile_listing($user, $fields = array(), $value = null) {

  $output  = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $user);
  $output .= ' <div class="name">'. format_name($user) ."</div>\n";

  foreach ($fields as $field) {
    if ($value) {
      $output .= " <div class=\"field\">$value</div>\n";
    }
  }

  $output .= "</div>\n";

  return $output;
}

and build $value before calling the theme function at all.

- Robert Douglass

-----
If this helped you, please take the time to rate the value of this post: http://rate.affero.net/robertDouglass/

www.hornroller.com, www.robshouse.net

robertdouglass’s picture

There is a patch to fix this. I'm hoping it will find its way into 4.7

http://drupal.org/node/27949

- Robert Douglass

-----
Rate the value of this post: http://rate.affero.net/robertDouglass/
I recommend CivicSpace: www.civicspacelabs.org
My sites: www.hornroller.com, www.robshouse.net

freyquency’s picture

Sorry for the delay... I created a lot of confusion for myself by jumping around to different issues (customizing freeform lists and pictures for example) instead of focusing on one at a time. I've actually figured out what I was doing wrong. In the code you had posted you used "," in cohoots with explode() where my list was line by line. Once I realized that your example totally worked... But as it would make a mess if one person used commas and another used lines it would need to be coded as such. Here's what I've got so far:

	<?php if($user->profile_profession != ""): ?>
	<ul>
	<?php
	$temp_array_line = explode("\n", $user->profile_profession);
	$temp_array_comma = explode(",", $user->profile_profession);
	$temp_array = array_merge($temp_array_line, $temp_array_comma);
	$count_total = count($temp_array);
	for($counter=0; $counter<$count_total; $counter++):?>
	<?php $link = each($temp_array) ?>
	<li><a href="/profile/profile_profession/<?php print $link[value] ?>" title="People who share this profession"><?php print $link[value] ?></a></li>
	<?php endfor ?>
	</ul>
	<?php endif ?>

Either /n or , work as explode separators, but I haven't been able to combine them into one explode argument successfully. By creating two arrays and merging them it doens't really work either. It sucessfully merges everything but for example this happens:

    *  visual artist,musician,hacker
    * web designer
    * visual artist
    * musician
    * hacker web designer

Any thoughts on how to combine the two methods of posting a freeform list into one array? I'd rather that as the code is smaller, but an array merge that checked against the other would work too. I'd love to spend more time on it right now, but alas, my paying job beckons.

... another thing would be removing spaces from the values- so that %20 doesn't appear in the url.

[]+][+][+[]
erik mallinson
http://coacalina.org

freyquency’s picture

I had to use split, not explode for pulling the information from the array created by using a freeform list field. The reason being that split can take multiple criteria to make a new value; we want both commas and new lines to be separators of content - I suppose that's why it's used in the original code that we are overwriting.

It's important that there be no space between /n and comma, else the space is also considered a separator. For example, if the comma were there it would consider "web designer" to be (in my example) "web" and "designer". For those whom haven't been following this thread, the $profile_profession is a freeform list I created, so it's name is dependent on what is given to the freeform list (profile_ is the recommended name prefix).

	<?php if($user->profile_profession != ""): ?>
	<ul>
	<?php
	$temp_array = split("[\n,]", $user->profile_profession);
	$count_total = count($temp_array);
	for($counter=0; $counter<$count_total; $counter++):?>
	<?php $link = each($temp_array) ?>
	<li><a href="/profile/profile_profession/<?php print $link[value] ?>" title="People who share this profession"><?php print $link[value] ?></a></li>
	<?php endfor ?>
	</ul>
	<?php endif ?>

woot!

[]+][+][+[]
erik mallinson
http://coacalina.org

Dublin Drupaller’s picture

fair play to you Erik...nice one..

Have you worked out how to pull out the other profile links?

like the send private message/image gallery/budylist...basically the links other modules create for the profile page?

Just curious.

Cheers

Dub

DUBLIN DRUPALLER
___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

freyquency’s picture

Not yet. I'd like to get recent posts (the module, the name escapes me at the moment), image gallery, and the date field working personally. Except recent posts I have pretty much what I need to relaunch the site using the same theme, but based on phptemplate. After that i'm going to look into making new themes that incorporate more rewriting of userpage and customizing other drupal 'parts'.

On another note I noticed that the code from the profile.module that you posted also has \r as a split, so it's probably a good idea to mimic that as well...
Thanks so much for your help with the freeform lists.

[]+][+][+[]
erik mallinson
http://coacalina.org

freyquency’s picture

In the example \n is correct, not /n as I wrote above it.

[]+][+][+[]
erik mallinson
http://coacalina.org

zirafa’s picture

Great little piece of code, thanks chromatic. Just wanted to add my 2 cents. It helps to put the link[value] in the href inside of a trim() function to make sure there is no white space, otherwise it will generate a link that ends up being /profile/profile_profession/%20pilot, which is undesirable. Also, you need to convert the spaces in the href link into +'s so that you get:
/profile/profile/profession/professional+airline+pilot
for instance. I used preg_replace to do that.

 <?php if($user->profile_profession != ""): ?>
<ul>
<?php
$temp_array = split("[\n,]", $user->profile_profession);
$count_total = count($temp_array);
for($counter=0; $counter<$count_total; $counter++):?>
<?php $link = each($temp_array) ?>
<li><a href="/profile/profile_profession/<?php print preg_replace('[\s]', '+', trim($link[value])) ?>" title="People who share this profession"><?php print $link[value] ?></a></li>
<?php endfor ?>
</ul>
<?php endif ?>

Thanks again for posting this!

adrian’s picture

I am the designer of phptemplate, and I have looked at your problem.. here is the theme you are overriding :

function theme_profile_profile($user, $fields = array()) {

  $output  = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $user);
  $output .= ' <div class="name">'. format_name($user) ."</div>\n";

  foreach ($fields as $field) {
    if ($value = profile_view_field($user, $field)) {
      $output .= " <div class=\"field\">$value</div>\n";
    }
  }

  $output .= "</div>\n";

  return $output;
}

Now!. the permissions trick here are the lines :

    if ($value = profile_view_field($user, $field)) {
      $output .= " <div class=\"field\">$value</div>\n";
    }

If you furthermore look at the profile_view_field() function :
[?
function profile_view_field($user, $field) {
// Only allow browsing of private fields for admins
$browse = user_access('administer users') || $field->visibility != PROFILE_PRIVATE;

?]

This means to get the permissions working as they are presently, you need to check if the profile_view_field function returns anything. You can completely avoid the output if that's what you require (although it might be practical to use it for everything other than the specifically overridden fields).

--
The future is so Bryght, I have to wear shades.

Mangaforce’s picture

Hi Bryght

I understand i can use the template.php aswell as user_profile.tpl.php but i still have to use this within the boundaries of the Theme ive chosen for the whole site.. IS there anyway i can override the WHOLE theme, and start with a complete blank page on the profiles only?

regards

newy

nautis’s picture

Jason -

Could you post your final profile.module solution for the benefit of the group? Like you were in December, I'm coming at this "bamboozled, baffled & braindead."

- matthew | nautis.com

Dublin Drupaller’s picture

http://drupal.org/node/14466#comment-26027

Dub

DUBLIN DRUPALLER
___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

nautis’s picture

I tried that and nothing happened. I'm using the interlaced.theme. Maybe that's the problem? Is interlaced using phptemplate?

- matthew | nautis.com

Dublin Drupaller’s picture

Sorry mathew,

I have no idea whether the interlaced theme uses phptemplate.....a few quick questions:

(a) have you installed phptemplate?
(b) did you upload the template.php & tpl.php files as outlined in my example?

I remember there was an extra step when I was doing this...it mentions it in the handbook the following

Note that you will need to visit admininster > themes for PHPTemplate to refresh its cache and recognize the new file.

PhpTemplate documentation is here for more info:

http://drupal.org/node/11810

Hope that helps

Dub.

DUBLIN DRUPALLER
___________________________________________________
A drupal user by chance and a dubliner by sheer luck.
Using Drupal to help build Artist & Band web communities.

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

boris mann’s picture

Interlaced is a pure PHP theme. You would have to complete duplicate the code of the user profile theme function in order to change the layout.

If you are going to be doing theme modifications, I would suggest sticking with PHPTemplate.

nautis’s picture

Doh! I should have guessed. Time to redesign. I see there's a thread already started on xtemplate v. phptemplate. Should the template engine be standardized (only one engine) to avoid fubars like this ... or is this openness part of the appeal - the extensibility?

- matthew | nautis.com

boris mann’s picture

Different people will have different needs, so there will never be only one template engine.

Drupal.org uses PHPTemplate. I'll let you fill in the blanks of which theme engine I think you should choose :P

robertdouglass’s picture

As of Sept. 6, the problem where overriding the profile.module's theme functions led to user access violations is fixed. You can now use the $fields variable however you want without having to perform additional checks.

- Robert Douglass

-----
Rate the value of this post: http://rate.affero.net/robertDouglass/
I recommend CivicSpace: www.civicspacelabs.org
My sites: www.hornroller.com, www.robshouse.net

PeterLucas’s picture

I uploaded the template.php and user_profile.tlp.php files to my themes folder. When I go to my website I get this on a blank page:

Parse error: parse error, unexpected '>' in /home/mywebsite.com/public_html/drpl/themes/mytheme/template.php on line 2

I have no idea what went wrong or where to start to fix it.

There's so much stuff going on in this thread it's very hard to follow.

Can someone please post a clear step by step solution somewhere how to customize the profile page?

Edit: I think I found the problem. The template.php posted earlier has wrong tags. It should be:

<?php
/**
* Catch the theme_item_list function, and redirect through the template api
*/
function phptemplate_user_profile($user, $fields = array()) {
// Pass to phptemplate, including translating the parameters to an associative array. The element names are the names that the variables
// will be assigned within your template.
return _phptemplate_callback('user_profile', array('user' => $user, 'fields' => $fields));
}
?>

Am I the only one who had a problem with this?

Now my profile pages are empty, but that's a problem for next time...

Dublin Drupaller’s picture

just in case any other users are reading this...there was a typo in PeterLucas' filename..it should be called user_profile.tpl.php...*not* user_profile.tlp.php as was previously mentioned.

A book page is here: http://drupal.org/node/16011

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

yngens’s picture

subscribe

JonGirard-1’s picture

Hey Guys,

I'm having a big problem.

I'm using the profile override statement as many of you are

<?php
/**
* Catch the theme_user_profile function, and redirect through the template api
*/
function phptemplate_user_profile($user, $fields = array()) {
  // Pass to phptemplate, including translating the parameters to an associative array. The element names are the names that the variables
  // will be assigned within your template.
  /* potential need for other code to extract field info */
return _phptemplate_callback('user_profile', array('user' => $user, 'fields' => $fields));
  }
?>

and now when I try to click on another persons profile listing to go to their profile, it goes to their URL but all the content is still my own even though they have created content. EX: Even though the url says "localhost:8888/user/addie-black" it's administrator's content, because I'm logged in as administrator. If I were logged in as addie black, all users profiles that addie navigated to would be her own profile content (picture, bio, links.. everything.)

How can I fix this so that users can view other peoples profiles?

Perhaps it's something in my actual profile layout> http://pastie.textmate.org/225770

Thanks.

Jon.

JonGirard-1’s picture

Figured out the problem-

http://drupal.org/node/277414

Jon.

summit’s picture

Subscribing, greetings, Martijn