Hi.

In my content type I have a text field and audio field, both fields are set to have unlimited values, so I can add more in the node if I need them. Some nodes will have 3 of these fields, some will have 5 etc, they will all be different. In my node.tpl.php I need to theme these fields depending on how many are in the node, so this is what I have which currently works:

  <div class="track-data">
    <?php print render($content['field_track_title'][0]); ?>
    <?php print render($content['field_track_preview'][0]); ?>
  </div>
  <div class="track-data">
    <?php print render($content['field_track_title'][1]); ?>
    <?php print render($content['field_track_preview'][1]); ?>
  </div>
  <div class="track-data">
    <?php print render($content['field_track_title'][2]); ?>
    <?php print render($content['field_track_preview'][2]); ?>
  </div>
  <div class="track-data">
    <?php print render($content['field_track_title'][3]); ?>
    <?php print render($content['field_track_preview'][3]); ?>
  </div>
  <div class="track-data">
    <?php print render($content['field_track_title'][4]); ?>
    <?php print render($content['field_track_preview'][4]); ?>
  </div>

The problem is that even though it works, it is still incorrect, if a node only has 2 of these fields it's still going to try print/echo the ones that it doesn't have and print the empty divs etc, plus it's code heavy because the maximum a node has so far is 10 values.

I'm not too hot with PHP yet, but I think the correct way would be to use a 'foreach' and loop through the array, can anyone help with that?

Thank You.

Comments

_

Should be something like (untested):

<?php for ($i = 0; $i < count($content['field_track_title']); $i++): ?>
  <div class="track-data">
    <?php print render($content['field_track_title'][$i]); ?>
    <?php print render($content['field_track_preview'][$i]); ?>
  </div>
<?php endfor; ?>

_
Don't be a Help Vampire - read and abide the forum guidelines.
If you find my assistance useful, please pay it forward to your fellow drupalers.

Thanks, on the right track.

Thanks, on the right track. First problem was syntax error on the endfor:

<?php endfor; ?>

I took it out, then nothing rendered on the page, so I changed the less than operator '<' to greater than '>' and it is rendering only the first value in the array. I also tried greater than or equal to but no difference.

If I echo $i it is always 0, that's why it only renders the first value, so the $i++ doesn't seem to do what it should.

*Update I noticed I had a semi-colon instead of a colon at the end of the first line, that changes everything and it seems the endfor is actually valid now. Still not rendering the fields though.

I will keep playing around... Thx.

_

endfor is required to close the for loop-- so don't remove it. You can see some examples of this construct in http://drupalcode.org/project/calendar.git/blob/refs/heads/7.x-3.x:/them....

The operator needs to be less than because the array is 0 based-- using <=, >, or >= will be out of bounds on the array.

My guess is the field syntax isn't quite right but I never remember the correct field syntax for d7. use dpm(get_defined_vars()); (or print_r() if not using the devel module) to see what variables are available and their exact array format.

_
Don't be a Help Vampire - read and abide the forum guidelines.
If you find my assistance useful, please pay it forward to your fellow drupalers.

Okay, another hour of testing

Okay, another hour of testing with the exact code above: Basically what happens is when I refresh the page I get a blank page, no HTML is rendered at all, but no PHP errors. So I put in a die() on each line, and it renders the correct HTML up until the endfor, so that's really strange. Also, it only renders the first value of those fields.

The best result I can get is with this syntax: (Changing the colon to a semi colon and the oprator)

  <?php for ($i = 0; $i > count($content['field_track_title']); $i++); ?>
  <div class="track-data">
    <?php print render($content['field_track_title'][$i]); ?>
    <?php print render($content['field_track_preview'][$i]); ?>
  </div>

But again, only renders the first value of both fields. Hmmm.
Thanks again for the help, I'll keep going.

Conditions on for loops

Hey,

Just curious; did you put:

<?php
endfor;
?>

back into the code?

Also, in case it helps, the second part of the "for" expression is a condition that is evaluated during every loop. If it is true, the loop continues; if it is false, the loop stops and the script continues. So, the way you have it, let's say you have 3 elements in the field_track_title array. In the first loop:

$i=0 and count($content['field_track_title']) = 3

At this point, $i is not greater than count, because 0 is not > 3. Thus, the loop ends. I'm wondering if it's still displaying the initial elements because without

<?php
endfor;
?>
it is not seeing it properly as a loop.

Yeah I did, and I got a PHP

Yeah I did, and I got a PHP error, so nothing worked. I understand and you're definitely right, that's why it only renders the first value in my adjusted code, so I guess I'll look into a different way of writing the loop.

Syntax error?

This might be the syntax error:

<?php
for ($i = 0; $i > count($content['field_track_title']); $i++);
?>

I think it should be:

<?php
for ($i = 0; $i > count($content['field_track_title']); $i++):
?>

Does that work?

Tried both ways and every possible combination...

Basically, if the code is like this (the way it should be):

<?php for ($i = 0; $i < count($content['field_track_title']); $i++): ?>
  <div class="track-data">
    <?php print render($content['field_track_title'][$i]); ?>
    <?php print render($content['field_track_preview'][$i]); ?>
  </div>
  <?php endfor; ?>

No HTML at all renders, I have a blank page and no source code whatsoever and no PHP errors either, something goes wrong in the loop because if I put in a die(); before the endfor the rendering stops and it renders the first value in the loop.

Weird

What does the rest of the code in your file look like? I'm wondering if the error is because of code outside of this snippet.

Thought crossed my mind...

I thought about that but it should all be ok, as it's always worked before with no problems, check it out here, I made a text file from the dev node file and put it on my server

http://media.stereofx.net/test/node--album.txt

The code without the loop (when I'm printing the hard coded array like in my first post) renders these album pages, all working:

http://stereofx.net/music/house-electro/dreamcatcher

(Current Code)

http://media.stereofx.net/test/node--album-current.txt

Also another thing that I didn't mention but shouldn't make a difference is in my node type settings these 2 fields are grouped in a fieldset.

_

When I examine the contents of $content for a field, I see:

field_fieldname (Array, 16 elements)
    #theme (String, 5 characters ) field
    #weight (String, 1 characters ) 0
    #title (String, 14 characters ) Project Number
    #access (Boolean) TRUE
    #label_display (String, 5 characters ) above
    #view_mode (String, 4 characters ) full
    #language (String, 3 characters ) und
    #field_name (String, 20 characters ) field_project_number
    #field_type (String, 4 characters ) text
    #field_translatable (String, 1 characters ) 0
    #entity_type (String, 4 characters ) node
    #bundle (String, 8 characters ) solution
    #object (Object) stdClass
    #items (Array, 1 element)
    #formatter (String, 12 characters ) text_default
    0 (Array, 1 element)
        #markup (String, 7 characters ) 3457623

So i dont think looping on $content['field_track_title'][$i] will work-- there's a lot of meta data in that array so at the very least count() will be wrong. I don't have time to play with it now, but my guess is you should be accessing the field directly rather than using $content, but again you'll need to examine the array to see how to do it.

_
Don't be a Help Vampire - read and abide the forum guidelines.
If you find my assistance useful, please pay it forward to your fellow drupalers.

Thanks!

Awesome, that's exactly what I need to keep going. Everything makes sense and that's actually quite and easy thing to do.

Update:

Just want to update this post with the working code, thanks to some help I got:

<?php foreach ($content['field_track_title'] as $key => $value): ?>
  <?php if (is_numeric($key)):  ?>
    <div class="track-data">
      <?php print render($content['field_track_title'][$key]); ?>
      <?php print render($content['field_track_preview'][$key]); ?>
    </div>
  <?php endif; ?>
<?php endforeach; ?>
nobody click here