• Resolved allm

    (@realblueorange)


    Today I ran into a situation where a shortcode was processed twice in a page, although it was only once in the content of the page.

    After a lot of trial and error / looking at what others have done in the past the problem went away when I stopped adding the registry of the shortcode through the init hook. The add_shortcode call is now all by itself in the functions.php file.

    I noticed the problem because I needed to register the firing of the shortcode, after which some info was written to SESSION variables. This was done twice per page, so I was really surprised.

    This process left me with 3 questions:

    1. Will the fact that I stopped registry of the shortcode through the init hook assure me of the fact that the shortcode is only run once on a page? (assuming the shortcode is only once in the content of the page)

    2. If it is still unknown how often the shortcode function fires: why is that? It seems to be bad for response times to execute a function twice, where once is sufficient.

    3. Is there some way to guarantee that a shortcode is run exactly the number of times it is in the content of a page? Which is what you would expect intuitively. Isn’t that so?

Viewing 8 replies - 1 through 8 (of 8 total)
  • Moderator bcworkz

    (@bcworkz)

    Calling add_shortcode() for the same shortcode tag both in functions.php and in the ‘init’ hook will indeed cause the shortcode run twice for each occurrence. Do one or the other, but not both. I’ve only added shortcodes in functions.php outside of any hook and they have always worked fine.

    All add_shortcode() really does is add the tag and callback to a reference array. As long as the array is established, I don’t think it matters much where it’s called, but it must be done only once or the array gets two entries, resulting in the double output.

    You could possibly add some sort of run once code using a transient or global value that’s set the first time and checked each time, doing nothing if found already set. This should not be necessary if you add the shortcode only once. It could cause issues in situations where the shortcode is desired to run more than once, perhaps on archive pages that display full content of multiple posts or something like that.

    Thread Starter allm

    (@realblueorange)

    @bcworkz
    Thanks for your reply!
    I think there is a misunderstanding. Right now I only have an add_shortcode in functions.php. Really nothing special. And nothing twice. But: the shortcode is performed twice, where there is only one reference to the shortcode in the content. On pages where the shortcode is not in the content the code is not performed, which is what you would expect. There is one situation though (leaving a page where the shortcode is in the content, and going to the home page that doesn’t have the shortcode in the content) where the code is performed once, although the shortcode is not in the content of the page. This results in unexpected behaviour as one might expect.

    I have thought about your method with a transient, but that won’t work as there might be cases where the shortcode is more than once on the page.

    What I will do is get the code that actually is not needed to expand the shortcode out of there. I will need to find another way to register that the shortcode has been performed with a certain id, which is a puzzle in itself.

    I am left behind wondering why shortcodes are performed twice, even though the shortcode is only once in the content of a page. It seems that is not good for performance. If you Google you will find that it is a symptom that has been detected quite often, but I have not found a solution to this.

    How are you returning the HTML content from your shortcode function? I ask this because one big trap that I’ve fallen into (many times…) is that I have tried to directly output the HTML from the sortcode function – which is the wrong way to do it. All of the content has to be returned as a string from the function, no echo’ing or iutput should happen in the function at all.

    Thread Starter allm

    (@realblueorange)

    @catacaustic:
    Thanks for replying.
    There are no echo’s. The content is returned as it should be.

    I can see how often the shortcode is performed because I have a session going on and I am registering things in $_SESSION.

    I’ll check some older sites as well (later this week) just to see what is going on…

    Thread Starter allm

    (@realblueorange)

    An update:

    I have done a lot of testing and now have a situation that is really weird (or I need some sleep ??

    I have sessions on and can store in $_SESSION. I am using Twenty Twelve. No caching. Inside the shortcode function I append the arguments to the shortcode function to a $_SESSION string which is displayed in a widget.

    In a new session I go to page X which has shortcode “A”. All this shortcode does is register itself in my $_SESSION variable and return a string. This shortcode is evaluated twice. I find that rather strange.

    When I go from page X to another page where there is no shortcode I notice that the shortcode on a completely other page (Y) is being evaluated. This shortcode is different from “A”, but it does the same as “A”: it just registers its execution in the $_SESSION string. I noticed that page Y is the next page after X if you take the ID as index.

    So there are 2 problems going on:

    1. Why does the shortcode get executed twice?
    2. And why does a shortcode get evaluated on a page that is not displayed?

    My ideas to solve this have dried up…

    I noticed that this problem has been reported before quite often, but I have not found a solution. It has been reported in connection to Jetpack, which I do not use. But it has been reported by people who do not use Jetpack as well.

    Any ideas?

    Later I will check this scenario on another website, or maybe start with a blank domain / empty database.

    Moderator bcworkz

    (@bcworkz)

    Sorry about my confusion, I apparently read into your post what I wanted to see.

    If you are not seeing double output from the shortcode, only double execution through $_SESSION, I would have to say nothing is wrong. It’s not unheard of for a plugin (and core code for all I know) to use do_shortcodes() for some reason, then discard the returned string once it has been evaluated. Perhaps some sort of searching procedure or something.

    The sole purpose of shortcodes is to be expanded into output. I consider any other use such as counting calls or other procedures unrelated to output as a misuse of the feature.

    Thread Starter allm

    (@realblueorange)

    @bcworkz and others:

    Thanks for your reactions.

    SPOILER: solution to my problem at the end of this reaction.

    You are right. I should not count/register things during the evaluation of a shortcode. It is wrong and I see that. I need to register which products have been seen by a visitor during a session and display a list of “products you have just seen”. The shortcode to show a product can be 0, 1 or more times on the page.

    As I cannot register this inside the shortcode (you are right, it can be evaluated more than once per page) I need to create a function that interprets the content of the page and hook it up to a hook that is at the start of the page. Not nice, but it can be done.

    So far so good.

    But there was also the problem that shortcodes were evaluated on pages that were never visited. I noticed that at least FireFox does this.

    The problem is that FF prefetches pages, and it does this by following rel=next links (or others?) in the source of the page. There apparently even is an addon to FF that prefetches all the linked-to pages. I have seen that Chrome does prefetching as well. I am not sure about other browsers.

    The prefetching registers products as “seen” that were never really seen by the visitor.

    My next step is to stop the prefetching on a .htaccess level (saves bandwidth too), but there are a lot of examples flowing around. I’ll look into these and when I find something that helps to stop prefetching I’ll report here. I don’t want to stop Google from following rel=next links, so they should stay in the source.

    Thanks all!

    BTW If anyone has any experience with this and can tell me the correct way to stop prefetching at a server level I’ll be very grateful.

    Thread Starter allm

    (@realblueorange)

    I have decided not to go deeper and refrain from using the functionality I wanted.

    There are just too many angles where things can go wrong, or not as intended.

    I’ll set this to “resolved”.

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘shortcodes running twice’ is closed to new replies.