Mixing PHP Variables with ExpressionEngine Template Tags

Jul. 3, 2008

1:22 pm

I'm knee deep in a project at my day job that's turning out to be a perfect example of ExpressionEngine's biggest strengths – fine-grained access control, a speedier build process, and crazy flexibility.

My task is to take a client's current site, change none of the layout or styling on existing pages, and port the whole thing to EE. Because we did the original build, the code is all standards compliant and has managed to stay pretty clean. The site's currently managed by the client with a basic WYSIWYG maintenance tool. It's actually worked quite well for them. But their organization represents 30 or so distinct sub-organizations, and giving those sub-orgs access to their own content is the biggest reason for this move. The hope is that the site will stay more current if opened up to these partners.

ExpressionEngine in the hiz-ouse!

For each of those sub-organization pages, the amount of content varies greatly. Most only have an overview page. But some have additional resources, some have conferences, some have news items – and some have all of those plus more. Each sub-org is represented by a single entry in a "Projects" weblog. Each of those additional content types are corralled in separate EE weblogs (appropriately named "News," "Resources," etc.) and related to the appropriate project by using a related entries field type and pulled into the correct project page with a call to reverse_related_entries.

The project manager I'm working with suggested tabbing these additional pages, and rather than coding the JS ourselves, our colleague suggested we go with DOMTab. Works a charm.

The problem.

Well, DOMTab, like any JS component, is pretty particular about how the code should be laid out. You've got a container div and a ul for the nav where each li represents one of the child divs, which can be named whatever you want. So something like this:

  1. <div class="domtab">
  2.  
  3. <ul class="domtabs">
  4. <li><a href="#resources">Resources</a></li>
  5. <li><a href="#news">News</a></li>
  6. [... and so on ...]
  7. </ul>
  8.  
  9. <div>
  10. <h2><a name="resources"id="resources">Resources</a></h2>
  11. <p>Here's where the resources go.</p>
  12. </div>
  13.  
  14. <div>
  15. <h2><a name="news" id="news">News</a></h2>
  16. <p>Here's where the news goes.</p>
  17. </div>
  18.  
  19. [... and so on ...]
  20.  
  21. </div><!--END DOMTAB-->

Many (or most) of our sub-projects don't have any additional info, and for those cases, we want the entire DOMtab section hidden. If there are any resources, news items, etc., then we want to show the whole thing, a list item in that initial ul, and an associated div in the body.

The solution I wish worked.

We've already hit the problem, even if it's not apparent yet. The simplest, and most elegant thing to do would be to wrap the entire chunk in a conditional call to reverse_related_entries and then nest other reverse_related_entries calls within. It'd look something like this:

  1. {if {reverse_related_entries weblog="resources|news"}}
  2. <div class="domtab">
  3.  
  4. <ul class="domtabs">
  5. {if {reverse_related_entries weblog="resources"}}
  6. <li><a href="#resources">Resources</a></li>
  7. {/if}
  8. {if {reverse_related_entries weblog="news"}}
  9. <li><a href="#news">News</a></li>
  10. {/if}
  11. [..and so on...]
  12. </ul>
  13.  
  14. {if {reverse_related_entries weblog="resources"}}
  15. <div>
  16. <h3><a name="resources" id="resources">Resources</a></h3>
  17. {reverse_related_entries weblog="resources"}
  18. [...print our resources info here...]
  19. {/reverse_related_entries}
  20. </div>
  21. {/if}
  22.  
  23. {if {reverse_related_entries weblog="news"}}
  24. <div>
  25. <h3><a name="news" id="news">News</a></h3>
  26. {reverse_related_entries weblog="news"}
  27. [...print our news info here...]
  28. {/reverse_related_entries}
  29. </div>
  30. {/if}
  31.  
  32. [...and so on...]
  33.  
  34. </div><!--END DOMTAB-->
  35. {/if}

But alas, that won't work. We're already within an initial exp:weblog:entries call, so it'd be asking a lot of EE to let us nest queries this deeply.

Halfway there.

What you could do is pull out all the nesting and wrap each item's opening and closing portions in its own conditional that checks reverse_related_entries. So, just for example's sake, the code for the entire DOMtab section would look like this:

  1. {if reverse_related_entries}
  2. <div class="domtab">
  3. {/if}
  4.  
  5. [...here's where all our content goes...]
  6.  
  7. {if reverse_related_entries}
  8. </div><!--END DOMTAB-->
  9. {/if}

That's fine in theory, but when you start extrapolating out exactly how many conditionals you'll need to get the whole thing to work, stuff starts to look crazy.

What I ended up doing.

To eliminate the clutter inherent in wrapping every single conditional element in its own reverse_related_entries conditional, what I ended up doing was turning on PHP for the template and setting the parsing stage to output. That last part's important because it tells EE to run the template tags before running the PHP. That lets me do this:

  1. {if reverse_related_entries}
  2. <?php TRUE = $has_additional_info; ?>
  3. {/if}

Now whenever I want to check to see if a chunk of code should be printed to the page, I only have to write a PHP conditional that starts with <php if ($has_additional_info) : ?> and I'm good to go. It's much more readable than the alternative, and as a bonus, uses less overhead.

Made it this far?

Wow. Look at the big brain on Brett!

If you're new to ExpressionEngine but like what you see, may I suggest Ryan Irelan's EE Screencast Series? I'm usually skeptical about any screencast that requires me to open my wallet, but I've watched all of these, and they're the nuts.

Look at that. It's the first day of a four day weekend, and I've spent two hours writing a single blog post. Time for me to do some recreatin'.

Happy futzin' everyone!

Whaddya think?