8

I am using Drupal Paragraphs module that lets you create "bundles" of fields inside other fields. (It does this using entities). Each bundle has it's own tpl.php file.

In addition, you can nest "sub-bundles" inside the "main-bundles" for complex layouts.

I have created a "main-bundle" called field_panels_content.

Inside this is another "subbundle" which holds a field_body_text. The "main-bundle" can hold an unlimited number of "sub-bundles".

In my theme, I need to access the all field_body_text fields from the multiple "subbundle" from the tpl.php file that is for the "main-bundle".

I have used devel_themer and found I can get to the field_body_text fields like this:

<?php print render($content['field_panels_content'][0]['entity']['paragraphs_item'][9]['field_body_text']); ?>
<?php print render($content['field_panels_content'][2]['entity']['paragraphs_item'][10]['field_body_text']); ?>
<?php print render($content['field_panels_content'][2]['entity']['paragraphs_item'][12]['field_body_text']); ?>

As you can see this does not make for efficient theming as I would need to know the second array value in order to print it out (e.g. [9][10][12]).

Is there away I can use a loop or some other PHP function to get to the second array value automatically without knowing it?

This second array value changes with each new piece of content (e.g. If I add a new subbundle it will have a value of [13]. The reason the numbers jump from [10] to [12] is because I deleted the subbundle that was [11].



Update

Here are some more steps I have tried (from this page):

Here is an example loop:

<?php
foreach ( $content['field_panels_content'] as $wrapper) {
  foreach ( $wrapper['entity']['paragraphs_item'] as $item ) {
    if ( !empty($item['field_body_text']) ) {
      print render($item['field_body_text']);
    }
  }
}
?>

It produces the following results: Cannot use object of type ParagraphsItemEntity as array in foreach ( $wrapper['entity']['paragraphs_item'] as $item ) {

Here is a reworked version:

<?php
foreach ( $content['field_panels_content'] as $wrapper) {
  foreach ( $wrapper['entity'].paragraphs_item as $item ) {
    if ( !empty($item.field_body_text) ) {
      print render($item.field_body_text);
    }
  }
}
?>

Error message: Fatal error: Cannot use object of type ParagraphsItemEntity as array in line "foreach ( $wrapper['entity'].paragraphs_item as $item ) {"

Editing the code so only field_body_text is in square brackets (e.g. $item['field_body_text']), produces this error message: Fatal error: Cannot use object of type ParagraphsItemEntity as array

Editing the code so only paragraphs_item is in square brackets (e.g. $wrapper['entity']['paragraphs_item']), produces this error message: Fatal error: Only variables can be passed by reference in line print render($item.field_body_text);

If I use print instead of render, I get this error message: Fatal error: Cannot use object of type ParagraphsItemEntity as array



Other Notes

The following code works perfectly:

<?php print render($content['field_panels_content'][0]['entity']['paragraphs_item'][9]['field_body_text']); ?>
<?php print render($content['field_panels_content'][1]['entity']['paragraphs_item'][10]['field_body_text']); ?>

So surely it should be a simple case to refactor the code into a loop to get the desired result.


Please note

I don't want to use other modules.

I will be printing out all the field_body_text separately at the top of the tpl file. I'll then display the whole paragraph (with the field_body_text still in it) in the normal way.

2 Answers 2

4
+200

I think the issue here is that each of those paragraph groupings contain various elements that are array keys. For example, if you dpm up to $content['field_paragraph'], you may see values that look like this:

enter image description here

I think the issue is, due to your loops, your trying to render/loop through things that aren't objects. To get around this, you might want to try checkin if the key is numeric before proceeding on.

Something along the lines like this:

<?php
    foreach($content['field_paragraph'] as $key=>$array){
  if (is_int($key)) {
    foreach ( $array['entity']['paragraphs_item'] as $key2=>$item ) {
    if ( is_int($key2) ) {
      print render($item['field_body']);
    }
  }
  }
}

?>

Note the is_int($key), that's what you need to get the errors to go away. Note my code has my own field names in it, so you'll just need to switch yours in.

1
  • I started an answer then re-read this. This is exactly correct.
    – Darvanen
    Commented Apr 15, 2015 at 0:55
2

Instead of overriding and creating templates, manage all of the display of the entity through the UI and create field formatters for field types when core doesn't cover your display requirements.

This is a much cleaner way of defining displays, templates get messy fast especially when diving into references.

1
  • in my case I need to output a list of all the titles stored in the "main bundle". I can know I can embed a View a to do this, but I would just like to have a list of titles as it would make it simpler. Also I need to output the title in different ways on a single page, so a template is cleaner than having lots of different formatters (and the UI only lets you use one formatter per a display)
    – big_smile
    Commented Apr 10, 2015 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.