Support

Home Forums Event Espresso Premium Event Espresso Markup Being Injected into Random WP_Query

Event Espresso Markup Being Injected into Random WP_Query

Posted: September 24, 2018 at 10:59 am


Grant

September 24, 2018 at 10:59 am

On the event registration template, the following code is being injected into a WP_Query for a custom post type in the footer of the page:


<a id="checkout" style="float: left; margin-left: -999em;"></a>
<div id="espresso-notices" style="position: fixed; top: 876px; left: 186px; margin: 0px;">...</div>
<div id="espresso-ajax-loading" style="display:none;">...</div>
<div id="espresso-ajax-notices">...</div>

This code breaks the footer as it is being injected directly into a unordered list. If the query is not present, the code is not added to the page. The WP_Query is a basic query that is supplied arguments for order, post_type, and posts_per_page.

Please advise as to why this code is being added here and how it can be removed.


Josh

  • Support Staff

September 24, 2018 at 12:07 pm

Hi,

I would need to be able to see the custom code in its context to be able to answer your questions. Is that something you can post into a pastebin or a GitHub gist, then link here?


Grant

September 25, 2018 at 7:42 am

Code for the loop can be viewed here: https://pastebin.com/TVCwpjQB

The Event Espresso markup is being injected once at the top of the unordered list.


Josh

  • Support Staff

September 25, 2018 at 11:24 am

That’s very context actually. You could try adding the following just before you start the loop:

add_filter('FHEE__EE_Front_Controller__display_errors', '__return_false');

If the above does not work, we’ll need more context to have an idea about what’s happening there.


Grant

October 1, 2018 at 9:11 am

The filter removes the div elements however the anchor tag remains so the issue is the same.

Also, I noticed that the same issue is happening in a similar loop on the homepage of the website. In this instance, it is only the three div elements that are added and not the anchor tag. Since there is no anchor tag present, the filter fixes this section of the website.


Josh

  • Support Staff

October 1, 2018 at 9:35 am

We’ll need more context (in other words, more of the theme code to look at) in order to troubleshoot further.


Grant

October 1, 2018 at 10:54 am

Is there something specifically you would like to see? Below are the relevant templates:

This seems like a pretty standard template setup to me? The registration template has been assigned to the plugin pages and the loop is contained within the footer template which is being included via a standard footer include.


Josh

  • Support Staff

October 1, 2018 at 11:38 am

That does not look like standard to me because what you have between those templates is a loop within a loop. In other words the main loop doesn’t end until after the second loop starts and ends.

Do you see how the loop starts on line 5 of the registration template, then the loop ends at the very bottom (after the get_footer() call)? That means the main loop has started, but more loops are running while the main loop is still iterating.

Here’s an example of a standard loop:

https://github.com/WordPress/twentyseventeen/blob/master/page.php

Do you see how the loop starts after the call to get_header()? Then see how the loop ends before the call to get_footer()? If your registration template were to be adjusted to follow that pattern, your main loop will end before the secondary loop begins.


Grant

October 1, 2018 at 12:55 pm

There’s nothing wrong with nesting a WP_Query within the main loop and the post data is being reset after the WP_Query as it should be.

Moving the footer include outside of the loop does not fix the issue.


Josh

  • Support Staff

October 1, 2018 at 1:28 pm

It’s not standard though, and if you temporarily switched to a theme that follows WP coding guidelines, like twentyseventy, loops will start and end as expected and you would not see an issue with the EE markup getting injected twice and within the last loop.


Grant

October 1, 2018 at 3:58 pm

There are no official “WP coding guidelines” that I have ever seen that say you should not nest queries. The WordPress Codex entry for “The Loop” even has a specific section called “Nested Loops” that says they are useful.

As I’ve already said, moving the query so that it is not nested within the main loop does not fix the issue with the plugin injecting markup into the query. I have already tried this suggestion and do not want to continue debating whether or not this practice is “standard” because it does not fix my issues either way.

Please let me know if you have another suggestion.


Josh

  • Support Staff

October 1, 2018 at 4:14 pm

Are you still starting the loop before calling get_header()?

Nesting queries isn’t so much the issue here. The problem is you’re starting the loop too early, and ending it too late. So unexpected things are going to happen.


Grant

October 2, 2018 at 7:44 am

No, moving both the header and footer includes outside of the loop does not fix the issue.


Josh

  • Support Staff

October 2, 2018 at 8:04 am

Quite likely there is some other convoluted code happening to prevent multiple headers and footers from being printed every time a post is returned. So we’ll need to see more context in order to advise further.


Grant

October 2, 2018 at 9:01 am

There isn’t. WordPress ignores multiple calls to include the header and footer by default and even if it didn’t, The Loop does not iterate on pages or single entries so there would be no reason to expect this code to be executed multiple times.

Can you please answer the following questions for me:

  • What is the purpose of the markup that is being injected?
  • Where is the markup supposed to be injected?
  • Why is there sometimes an anchor tag and sometimes not?


Josh

  • Support Staff

October 2, 2018 at 9:57 am

The purpose of the markup is a placeholder that’s used to show notices on screen. For example, let’s say someone puts the ticket selector shortcode on a post or page. If the user visiting the page does not select a quantity of tickets and submits the ticket selector form, they’ll see a notice that looks like this:

https://slack-files.com/T02SY781D-FD5B2RS1J-f004963f2f

If you activate the twentyseventeen theme, then view the source of the event page, you’ll see an example of where the markup is supposed to be injected. See also this screenshot:

https://slack-files.com/T02SY781D-FD4QET4BS-76ed541b1b

The anchor tag is added if there’s a checkout session. For details, here’s a link to the source that shows the context of how & where that gets added:
https://github.com/eventespresso/event-espresso-core/blob/master/modules/single_page_checkout/EED_Single_Page_Checkout.module.php#L490


Grant

October 2, 2018 at 1:24 pm

Thank you. I’m still not clear on where the markup is supposed to be injected. That looks like it is somewhere after the header but how does the plugin determine the appropriate place on the page?


Josh

  • Support Staff

October 2, 2018 at 1:34 pm

The markup is usually placed between the end of the header and the beginning of the main post content.

The plugin has a display_errors method that hooks to loop_start. Generally loop_start will fire right after the header (but not with you’re particular template, because you’ve started the loop before the header). Here’s a link to the source that shows all the conditional checks it uses to ensure the markup is injected where expected:

https://github.com/eventespresso/event-espresso-core/blob/master/core/EE_Front_Controller.core.php#L87

https://github.com/eventespresso/event-espresso-core/blob/master/core/EE_Front_Controller.core.php#L396


Grant

October 2, 2018 at 2:27 pm

Can you please have your developers confirm the following issues:

  1. The plugin does not function correctly on templates using nested loops and will output markup at the start of both the initial loop and the first nested loop.
  2. The plugin does not function correctly on templates with multiple loops (regardless of nesting) where there is also a checkout session and will output markup at the start of all loops.


Josh

  • Support Staff

October 2, 2018 at 2:32 pm

Both of those statements are false because in most cases the markup will output one time (please note the ! $shown_already check in EE_Front_Controller.core.php’s display_errors method).


Grant

October 2, 2018 at 3:02 pm

I understand that you have functionality in place that will prevent this from happening in most cases. I am not interested in most cases, I am interested in the two specific cases that I have mentioned where I am seeing that functionality fail. This is why I have asked your support team to investigate them.

If you replied within 5 minutes of me asking you to look into this, then you have not bothered to check whether either of those statements is actually false. You have also not provided any alternative suggestions or information that would help me proceed with solving my issue. Should I dig around your source code and figure it out for myself? As someone who has purchased your plugin and is seeking support, this is incredibly frustrating. If you do not have the time or resources to investigate this issue further, then please say so.


Josh

  • Support Staff

October 2, 2018 at 3:16 pm

Hi,

I’ve been looking into this matter off and on throughout the day, we’ve helped others resolved similar issues, and this statement:

The plugin does not function correctly on templates using nested loops and will output markup at the start of both the initial loop and the first nested loop.

is false, and it’s not really asking for support.

Your template isn’t exactly a nested loop. At least, if you use the definition of nested loop from the WordPress codex, what you have going on isn’t a nested loop.

I cannot begin to guess what other other code from your theme is causing unexpected results. So here’s what I can do:

I can comb through your custom theme and point you in the direction of how to make sure the loop_start action hook will fire in the general vicinity of where we’d all expect the first instance of a loop_start hook to fire. I’ve asked for more context, and it seems you’re hesitant to give that further context. If you can upload the theme somewhere, post a private reply with a link to download the theme, we can investigate further.


Brent Christensen

  • Support Staff

October 2, 2018 at 4:05 pm

Hi Grant,

I’m Event Espresso’s lead developer and the one who wrote the code that injects our notices container into the loop.

As Josh has explained, we are hooking into the 'loop_start' action at priority 2, as you can see here:

https://github.com/eventespresso/event-espresso-core/blob/master/core/EE_Front_Controller.core.php#L87

the display_errors callback that is called can be seen here:

https://github.com/eventespresso/event-espresso-core/blob/master/core/EE_Front_Controller.core.php#L396

I’ll walk you through what’s going on in that method:

– first, we set a static variable called $shown_already that is used for ensuring our notices container only displays once. Because it is static, it doesn’t matter how many times this method gets called, it will retain its value, which is initially set to false.
– next we have a custom action that fires before anything else happens. This gives devs a guaranteed spot to inject some code that will run prior to our notices container being generated.
– then we hit a multi stepped conditional that has been in place for 5 maybe 6 years without much issue and has probably not seen any changes at all in the last 3 years or so (although I’m guessing). Considering that Event Espresso has run on thousands of sites with all sorts of various templates, I am pretty confident that this code operates reasonably well. I’ll break down what is happening in it line by line. Please note that these conditionals are joined using && (AND) meaning that each of these conditionals must evaluate to true in order to advance to the next line, and ALL of them must evaluate to true in order for the inner code to run. Code execution will stop as soon as one of these conditionals evaluates to false, meaning the inner code will not run.


! $shown_already

this checks the value of our static variable set at the top o f the method. Since it is initially set to false, this becomes a double negative, so ! false evaluates to true and we advance to the next conditional


apply_filters('FHEE__EE_Front_Controller__display_errors', true)

this is a custom filter that gives devs an opportunity to exit out of this conditional in case they want to remove our notices container in order to position it somewhere else.


is_main_query()

this verifies that the current query is the WordPress main query for the request and not one of the many other queries that run on a page, such as the one that retrieves menu items for the site navigation.


! is_feed()

this prevents our notices container from displaying on RSS feeds because those do not allow for any user interaction (such as registering for an event) and therefore do not require notifications to be displayed to the user


in_the_loop()

this was added to handle an edge case where some themes are running a custom main query in addition to the WordPress main query but are not tagging it as being in the loop.


did_action('wp_head')

another bit added to accommodate themes that run their main query prior to calling get_header(). This prevents our notices container from being output prior to the WordPress header. This is the conditional that is not operating as expected because of your custom theme. I’ll come back to this line in a minute.


$this->Request_Handler->is_espresso_page()

this final conditional examines the current request and performs a bunch of poking and prodding on the current global post to determine if the current request is for an Event Espresso page that needs our notices container injected into the DOM.

So again, if any of those conditions does not evaluate to true then the inner code which injects our notices container will not run.

Now, your Registration template can be summed up as follows:


if ( have_posts() ) : while ( have_posts() ) : the_post();

    get_header();

    // template HTML

    get_footer();

endwhile; endif;

As explained above, our notices container hooks into the loop_start action that fires immediately after calling the_post() but only upon the first iteration of the loop. The reason that you are not seeing our notices container getting injected into the correct place in the DOM is because of the did_action('wp_head') conditional I listed earlier. That action is typically fired from within a theme’s header.php file. For example, here what happens in the official WordPress Twenty Seventeen theme header.php file:


<!DOCTYPE html>
<html <?php language_attributes(); ?> class="no-js no-svg">
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="http://gmpg.org/xfn/11">

<?php wp_head(); ?>
</head>

The problem with your Registration template code is that it is calling get_header() from within the the loop. This means that the_post() is being called before the header.php file is being loaded. Therefore the_post() is being called before wp_head() is firing. So when EE_Front_Controller::display_errors() hooks into loop_start that is called by the_post(), our notices container do not get injected because the did_action('wp_head') conditional returns false, because your theme is not loading its header until after it has begun looping through post results for the main query.

The reason that our notices container is getting injected later on in your footer code is because you are running an additional query within that template, and by that time all of the conditions for our conditional that control its appearance have now been met.

I cannot stress enough that it is completely unconventional and unexpected for a theme to call get_header() from within the the loop. I’m not a gambling man but I would bet that you would have to look through thousands and thousands and thousands of WordPress themes before you could find one that is doing what your theme is doing, that is if you could even find another theme doing it at all.

Why?

Because calling get_header() from within the the loop is a pretty guaranteed way to shoot yourself in the foot.

Is there even any reason why your theme is calling get_header() and get_footer() from within the the loop? I can see absolutely no benefit for doing so.

The standard most basic expected structure for a top level theme template is:

Header
The loop and everything else
Footer

I have no doubts that any of the archive templates for your theme do not do the exact same thing as your Registration template, because if they did, you would have a header and footer being printed out for every post returned by your query.

The comment that you made earlier:

WordPress ignores multiple calls to include the header and footer by default

is not correct in any way. Here is the entirety of the WordPress get_header() function:


function get_header( $name = null ) {
	/**
	 * Fires before the header template file is loaded.
	 *
	 * @since 2.1.0
	 * @since 2.8.0 $name parameter added.
	 *
	 * @param string|null $name Name of the specific header file to use. null for the default header.
	 */
	do_action( 'get_header', $name );

	$templates = array();
	$name = (string) $name;
	if ( '' !== $name ) {
		$templates[] = "header-{$name}.php";
	}

	$templates[] = 'header.php';

	locate_template( $templates, true );
}

not much to it so it’s pretty easy to see that there is no mechanism in that code to prevent it from running multiple times. So every call to get_header() will result in the ‘header.php’ template (or specified alternative) being included and therefore displayed.

This means that your archives templates absolutely can not be calling get_header() and get_footer() from within the loop like your Registration template is, and are either making those calls outside of the loop as is the expected norm, or have added some additional code to ensure that those are only firing once. Which is silly because you can simply move those two function calls outside of the loop and not have to bother with any of that.

So anyways, before we can go any farther, we will need you to restructure your Registration template file to be as follows:


get_header();

if ( have_posts() ) : while ( have_posts() ) : the_post();

    // template HTML

endwhile; endif;

get_footer();

so that our notices container can even have a chance of being injected properly. I can guarantee you that it will not function properly the way you have that template structured now. If after making that change, things continue to not operate correctly, then we will need ftp access to your site, or access to the entire theme in order to be able to fully troubleshoot what other problems are happening.

Lastly, I just want to say that I apologize if my comments above come across as condescending or offensive in any way as that is absolutely not my intent. It is imperative however that you understand that the existing code you have shown us will absolutely not function properly and would almost certainly be considered “doing it wrong” by the vast majority of WordPress developers out there. We need this issue corrected before we can continue to troubleshoot the issues on your site.

  • This reply was modified 1 week, 5 days ago by  Brent Christensen. Reason: trying to fix display of code blocks
  • This reply was modified 1 week, 5 days ago by  Brent Christensen.
  • This reply was modified 1 week, 5 days ago by  Brent Christensen. Reason: note re: access to theme files


Grant

October 3, 2018 at 10:58 am

Hi Brent,

I appreciate your thorough response. It is not condescending or offensive but I think you’ve missed some of my responses in the thread since we’re still talking about the header and footer, and it doesn’t really feel like my concerns with the support process have been addressed. I think you have a good product, but this was not a good experience.

In my reply dated October 2, 2018 at 7:44 am, I think that I pretty clearly stated that I had implemented the suggested fix (moving the header and footer) and that there was still markup being injected into the footer that was breaking the layout. I’ll assume you’re correct regarding the way WordPress handles repeated header and footer calls when the loop iterates (I only quickly tested repeated calls in sequence outside of a loop and observed no repetition), but none of this is relevant to my issue because I don’t have any problems with it and as I told support, there’s no functionality in the theme to mess with that default functionality. As you assumed, the archives templates aren’t setup in the way the registration template initially was, the rest of the theme is fine. I just needed help with the markup still being injected into the footer of the registration template.

Because the suggestions provided so far did not fix my issues with the markup in the footer, I asked some questions to help me understand the functionality I was dealing with and then asked for confirmation of the two issues I had observed: the issue I saw when nesting a query within the loop (issue #1) and the issue I saw in the registration flow that happened regardless of nesting (issue #2). Based on what you’ve told me, it sounds like the response should have been a confirmation that you do support nested loops and that the only cause of the issue is the header and footer includes (fair enough) and a request for FTP access to help diagnose the second issue (which may or may not be a legitimate bug).

That is not the response I received. The issues were immediately dismissed and I was given a dead-end answer with no way to move forward. After expressing my frustration with this, the follow up was to tell me that asking for confirmation of my issues is somehow not really asking for support, which I don’t understand or agree with. I’m also not sure where the assumption that I am hesitant to share the code has come from since I have already shared code in the format requested when it was asked for. Should I have inferred that a generic request for “more context” meant FTP access to the full theme or should support have just made that request to begin with and saved us all the hassle?

Thank you for sharing the explanation of how the markup injection works. I have made edits to the plugin files that have corrected my issue with the duplicate markup in the footer. The registration flow is now working as expected.


Josh

  • Support Staff

October 3, 2018 at 1:35 pm

Hi Grant,

My sincere apologies if any of my replies came across like they were a dead end with no way forward. We try very hard to have a solution for issues like these.

With regards to getting more context, maybe you didn’t see my earlier reply about sending the theme files?

In any case the offer still stands to help you get this sorted out without resorting to hacking core plugin files. Your client will really appreciate everyone’s efforts in making sure this is resolved the right way. As you’re probably aware, editing plugin files can make for missing functionality and present maintenance headaches with plugin updates going forward.


Brent Christensen

  • Support Staff

October 3, 2018 at 1:58 pm

Hi Grant,

I’m glad you got things working. When you say:

I have made edits to the plugin files that have corrected my issue with the duplicate markup in the footer.

Do you mean you edited Event Espresso plugin files? Because as Josh has pointed out, it’s not wise to change core plugin files since those would get overwritten during any updates.

Any chance you can share exactly what changes you made since that may reveal a way that we can improve our product so that others don’t have to experience the same issue?

You must be logged in to reply to this support post. Sign In or Register for an Account

Support forum for Event Espresso 3 and Event Espresso 4.
Documentation for EE3 and EE4
Documentation for Event Espresso 3

Documentation for Event Espresso 4

Status: publish

Updated by  Brent Christensen 1 week, 4 days ago ago

Topic Tags

Notifications

This topic is: not resolved
Do NOT follow this link or you will be banned from the site!