ExpressionEngine: Embed an Embed within Itself?

At work this week, there was discussion on how to accomplish something in ExpressionEngine. We wanted to pull in entries that were in one category, but if there were no entries, then pull in from other categories and display that instead. We were kind of stumped as to how to do that.

I’m not sure if we were missing some easy way to do that, but we couldn’t think of a nice way to accomplish it.

Let’s Backup

I guess it will be helpful to give you some more context. We had created a Channel (our term for Weblog) for events. You could categorize the events, and they would publish in different places.

In this instance, the homepage, we wanted to pull an event from one category, but if there were none, then just display an event from another category.

The Initial Code

This code was separated out in an embed so that we could use it in various places on the site:

{assign_variable:channel_name="{embed:channel}"}
{assign_variable
:category_id="{embed:category}"}

{exp
:weblog:entries weblog="{channel_name}" category="{category_id}" show_future_entries="yes" show_expired="no" limit="1" disable=“category_fields|custom_fields|member_data|pagination|trackbacks”}

 
<h2>{title}</h2>
 
{if events_feature_image}
  
<class="rightSide"><a href="{url_title_path="{embed:template_path}"}"><img src="{events_feature_image}" alt="" /></a></p>
 
{/if}
 {if events_summary}
  {events_summary}
 {
/if}

 
<p><a href="{url_title_path="{embed:template_path}"}" class="more">Read more &raquo;</a></p>
{/exp:weblog:entries} 

The code doesn’t really need to be explained; it’s not the important part of this post. So on the homepage, we had code that looked like this to pull in the event:

{embed="site/.events" channel="events" category="7" template_path="news-events/events"

Now, what we really wanted to be able to do was to modify the exp:weblog:entries code to pull from a different category if there were no results. Something like this:

{exp:weblog:entries weblog="{channel_name}" category="{category_id}" show_future_entries="yes" show_expired="no" limit="1" disable=“category_fields|custom_fields|member_data|pagination|trackbacks”}
&hellip;
 
{if no_results}
  Code  to pull from a different category
 {
/if}
&hellip;
{/exp:weblog:entries} 

But the problem was, there really was no code that we could put in there that would pull from another category since you can’t nest exp:weblog:entries tags. So that’s when I remembered that you could stick an embed file in there that could have the exp:weblog:entries tag inside of it.

Then we realized that the code we wanted to write would be exactly like the code in the embed file we were already working with.

So we did a little investigation and found out that according to the documentation (see notes section), you cannot embed an embed within itself.

That makes sense, because you could create an infinite loop. But what if we knew that it would not return an infinite loop?

Modified Code

So we determined that what we could do is not pass in the category on the embed statement, and that would pull back any events.

{exp:weblog:entries weblog="{channel_name}" category="{category_id}" show_future_entries="yes" show_expired="no" limit="1" disable=“category_fields|custom_fields|member_data|pagination|trackbacks”}
&hellip;
 
{if no_results}
  {embed
="site/.events" channel="events" template_path="news-events/events"}
 {
/if}
&hellip;
{/exp:weblog:entries} 

See how there is no category parameter this time? Here is the full modified code:

{assign_variable:channel_name="{embed:channel}"}
{assign_variable
:category_id="{embed:category}"}

{exp
:weblog:entries weblog="{channel_name}" category="{category_id}" show_future_entries="yes" show_expired="no" limit="1" disable=“category_fields|custom_fields|member_data|pagination|trackbacks”}

 
<h2>{title}</h2>
 
{if events_feature_image}
  
<class="rightSide"><a href="{url_title_path="{embed:template_path}"}"><img src="{events_feature_image}" alt="" /></a></p>
 
{/if}
 {if events_summary}
  {events_summary}
 {
/if}

 
<p><a href="{url_title_path="{embed:template_path}"}" class="more">Read more &raquo;</a></p>

 <
strong>{if no_results}
  {embed
="site/.events" channel="events" template_path="news-events/events"}
 {
/if}</strong>
{/exp:weblog:entries} 

And that worked!

Houston, we still have a problem…

But, we then realized that the same problem would occur if there were no future events in any categories. So, we still needed to go back and solve that problem by similarly passing the value for the show_expired parameter in the embed statement as well. I left that to my colleague, so I didn’t test this code, but this is my guess of how to solve that problem:

{assign_variable:channel_name="{embed:channel}"}
{assign_variable
:category_id="{embed:category}"}
<strong>{assign_variable:show_expired="{embed:show_expired}"}</strong>

{exp:weblog:entries weblog="{channel_name}" category="{category_id}" show_future_entries="yes" <strong>show_expired="{show_expired}"</stronglimit="1" disable=“category_fields|custom_fields|member_data|pagination|trackbacks”}

 
<h2>{title}</h2>
 
{if events_feature_image}
  
<class="rightSide"><a href="{url_title_path="{embed:template_path}"}"><img src="{events_feature_image}" alt="" /></a></p>
 
{/if}
 {if events_summary}
  {events_summary}
 {
/if}

 
<p><a href="{url_title_path="{embed:template_path}"}" class="more">Read more &raquo;</a></p>

 
{if no_results}
  {embed
="site/.events" channel="events" <strong>show_expired="yes"</strongtemplate_path="news-events/events"}
 {
/if}
{
/exp:weblog:entries} 

Conclusion

Was there some really easy way to do this that we completely blanked on? It seemed a little hacky, but the solution worked.

3 Comments

Doug Avery

10.23.2009

Interesting! I actually didn’t realize you could use embeds to do simple weblog nesting that way.

This looks like a great way to do it, especially with complex parameters like show_expired to deal with. I’d be curious to see how many queries this results in, but I’m guessing that if it didn’t infinite-loop out, it’s probably okay. Thanks for the tip!

Mark @ Alchemy United

01.16.2010

Hey Trevor

Did you solve this? Couldn’t you just add a (PHP?) flag that gets set within the No Results? And then when you come out of that main loop just evaluate that flag and see if you need to run another loop for the other categories?

Another similar option might be to set up some sort of array of the categoires in the order you want to check for them. Then have an outer foreach loopwith the EE loop within it that uses category=“Cat[foreach_array] and just keep working down the array as the No Result comes back = True.  Kinda recursive but not really.

Btw, while I’m here - you know anything about putting the Flickr share code into an EE weblog? Maybe my head just isn’t on straight but it doesn’t seem to be as simple as just pasting it in EE. That doesn’t seem to want to render right. Or is it just me?

Trevor

01.16.2010

@Mark @ Alchemy United-
Solve what problem? I don’t know of any issues of putting Flickr code into EE, but I guess it would depend on the code.
——-

Too late, comments are closed!

Don’t worry, you can email me or contact me on Twitter.