Using anchor links to open accordions and tabs in Divi – from another page!

The most popular article on my blog so far (by way of comments on it) is the one on Using anchor links to open accordions and tabs in Divi. It’s so popular that when the demo page broke recently I even had a few people comment to ask if the process still worked with newer versions of Divi (it does, by the way).

It being the most popular article, the most popular question I get about it is “How do I link to and open an accordion or tab, from an external page?” Well, today I share that solution.

Before we begin – This article is going to be a little more advanced than my usual Divi posts. This is because it is going to require delving into the world of PHP and WordPress action hooks. For the purposes of this article I am not going to delve too deeply into those topics, so I do suggest reading the relevant documentation on WordPress.org. Also, for the purposes of this article, you are going to need to know how to include PHP into your WordPress site (either via a Divi child theme or a plugin). If you are new to PHP I recommend reading my Child Theme series, especially the article on Making child themes part of your development best practice. For this article, we’ll use a child theme, because it’s the easiest way.

Ok, all caught up? Good, let’s begin!

Preparation: Understand Query Strings

The first thing you need to understand is query strings. Query strings are not something you see a lot of lately (as pretty permalinks are the norm) but they are what existed before permalinks were made popular. Query strings look something like this:

http://mycooldomain.com/?post_name=my-cool-article

See how I am specifying that post_name is equal to my-cool-article after the question mark sign? This is a query string. In this string I am passing the variable post_name and giving it a value of my-cool-article. Once the url before the query string loads (in this case just the home page of the domain) I can check for that variable using the global PHP $_GET variable array and, if it exists, do something with it.

$passed_post_name = $_GET['post_name'];
// do something with the $passed_post_name variable

In order to open a specific tab or accordion on page A from page B, I need to setup my anchor links on page B to point to page A, but those links should also include a query string variable, in this instance the name of the accordion or tab item I want to open.

So, for the purposes of this topic my query string will something look like this

?et_open_accordion=et_pb_accordion_item_1

or

?et_open_tab=et_pb_tab_1

You’ll see that I am passing the class identifier of the accordion or tab item to open as the value. (more on this later)

Step 1: Making some jQuery changes

Let’s first take a look at the accordion ‘open’ snippet I posted in the original article:

The important thing to look at is the css class identifier for the accordion or item we’re triggering the click on, in this case .et_pb_accordion_item_1 or .et_pb_tab_1. See how this is the same as the value being passed in the query string above. What we need to do now is to be able to specify that value as a JavaScript variable somehow and pass that variable into the JavaScript, to trigger the click of our selected accordion item, when the page loads.

The second thing we will need to do is make sure that this code only fires, once the entire document has loaded. Currently it waits for you to click a link on the same page, but now we’ll be loading the page with the accordion or tab content and then triggering the click.

Note how I have changed the et_pb_accordion_item_1 and et_pb_tab_1 to openers.accordion and openers.tab and instead of those variables being inside the class selector string they are being concatenated to the string (see, I told you this was a little more advanced). I’m also wrapping the entire thing inside a $( document ).ready(function() {} and removing the on(“click”) event handlers and checking if there is an instance of either openers.accordion or openers.tab. If either exists it will fire the relevant ‘open and animate to’ code.

Step 2: Mix in some PHP

Right, so now that we have this updated JavaScript we need to setup those openers variables, based on the query string. Do to this we need to do two things a) enqueue the JavaScript in the child theme and b) pass some PHP variables to the JavaScript. To achieve this we’ll put all our PHP code into a functions.php file of a child theme.

Instead of using the Divi Theme Options Code Integration tab for the JavaScript, we need to save it in a file in our child theme and hook a function into the wp_enqueue_scripts action hook (the same one used to enqueue child theme CSS). It looks something like this:

We also need to make the PHP variable available to the script. This is done by using the wp_localize_script function, which allows you to pass any variable from PHP to the JavaScript script you are enqueuing using wp_localize_script.

There are also some other things we need to setup, like defining path urls for enqueing files and setting up the Divi parent stylesheets. Again I’m not going to go into too much detail, but the final functions.php file looks like this:

So, you have your functions.php file, retrieving the passed variables, setting up the javascript variables and enqueing the relevant javascript file to make it all work. All you have to do now is create a page with anchors that link to the correct location, including your query strings. And we’re all set.

One thing to note, this article and child theme are for the purposes of explaining the basics of linking to open tabs or accordions. In the real world you should be considering escaping the query variables in the PHP to ensure no one injects any dodgy code into your site. This article is a good place to start.

Happy Divi-ing.

Update: Thanks to Nathan Duvall for pointing out how to manage this with Divi toggles.

Great article, Jonathan! I was actually looking for something similar, but for toggles. Apparently the process is a little easier with those vs. accordions/tabs. For anyone else needing this functionality for tabs, it’s just a matter of giving each toggle a unique ID, copy/pasting this code into the integration tab and then setting up the link.

Great article although I am worried I may have missed something as it isn’t quite working how I expected, both links I have put in just go to the same open tab.(I am not very familiar with scripting so if you could point me in the right direction that would be great).

I basically have 2 top level main menu items which when clicked I would like to open up not only the relevant page but also open the correct highlighted tab.

Hi Jonathan, thanks for getting back to me so quickly and pointing that out for me – I have now got it working correctly.

One more quick question when it goes to the correct tab the page scrolls down a little bit thus obscuring the highlighted tab name – it looks like the page scrolls to the top and then hides behind the primary navigation header – is there a way to avoid that at all?

Basically that is scrolling the window to the top of the accordion. So you could change it to scroll to the top of the opened accordion item by appending the class selector variable for the opened accordion item.

Great article Jonathan!
Building in this functionality seems to be to be a fundamental requirement if you have content in Tabs, Accordions and Toggle modules. However, the procedure that you outline is a little outside my capabilities!
Elegant Themes appear to be neatly sidestepping the issue at the moment, so wouldn’t it be nice if some one could develop a plugin (I would gladly pay for it!), or a complete step by step idiots tutorial?

Thanks much Jonathan for this solution, which I really wanted to learn.

Just one thing is I am little bit slow on getting this.

How about putting all the jquery scripts, php, and the html, in a zip. I believe by running these files and then studying them by tests will help me on understanding this most looked for solution you have provided.

On the topic of security, since we aren’t printing or writing to a database we apparently need be concerned with the data we are getting from the url (key, value pairs) via the “$_GET[‘et_open_accordion’]” and $_GET[‘et_open_tab’], correct?

Sure, that function would be fine. To be honest, because of how the parameter is only being used to setup some jQuery functionality, I don’t really think you even need to perform any data sanitisation. Just doing something like checking to make sure that the correct string has been passed would be sufficient

I’m afraid that I can’t comment on the snippet plugin, I prefer not to use such plugins and implement custom code as either a child theme or a plugin. AS such I don’t know if the wp_localize_script functionality works using that plugin. What I can recommend is if you don’t want to use a child theme, package the code into a plugin.

As for the JavaScript, there is no reason I am aware of that you couldn’t put it in the Divi’s theme options code integration tab.

Apparently, i’m not able to open tabs by the css id with that code running (example if css id of the tabs is: my-tabs, then http://site.com/my-tabs|0 and 1 and so on will produce a blank space where the tabs should be on that page).
If i go to the page url where the tabs are, then they are fine.

Due to this error in chrome inspect: unrecognized expression: .et_pb_toggle#my-tabs|0

Another question, if i may: I have pretty long tabs, is it possible to open tab classes (et_pb_tab_0, et_pb_tab_1, etc…) with different auto-scroll to different content on those tabs?

For instance:

If i click the anchor linking to et_pb_tab_0 it will open that tab 0 with $(‘#my-tabs’).offset + 150().top }, 1000);

but if i click the anchor linking to et_pb_tab_1 it will open tab 1 with, say $(‘#my-tabs’).offset + 800().top }, 1000);

I’ve added ids and classes to sections and im trying to switch them with wordpress menu (divi). I’m trying to do something similar to yours. In browser view works great, when it gets to mobile view it dosnt work anymore.

Thanks for the in depth article! It really helped me, with more than just this feature.
I was looking into creating a child theme for Divi and hit a bug that’s present in WordPress 4.9 that won’t allow editing in the child theme editor. I was starting to wonder if I should bother using a child theme but after seeing the layout of your files clearly in your GitHub sample, I decided to proceed. I wasn’t sure whether .js files should be placed in the same folder as the functions.php, or whether I should still use the areas provided in the Divi theme foe adding extra code.

Long story short, I understand the file layout now and have working anchors for my tabs! 🙂

Great articles, liked them both and good code. Question, I am having an issue with the code executing, it goes to the page fine but the accordion flashes by and does not stay open. It only also does only the first link. I checked my URL which was correct.

Hi, I’m fairly new to css coding and stuff. I have an accordion with treatments on a clients page that I’m making. She wants the treatments in the menu and when people click on the menu-item that it opens up the right part of the accordion. Do I have to put in code for every accordion part? Since in this code it says et_pb_accordion_item_1? Or does that work automatically?

Thank you for a great article, it is working perfectly.
I would like to know, is it possible to assign an ID to a specific Accordion item so that I can use that rather than …/?et_open_accordion=et_pb_accordion_item_1
I have an accordion with over 100 artists, this will be edited over time so it would be easier to link to …/?et_open_accordion=et_pb_accordion_fred_smith rather than have to find and change each and every link when and addition or deletion happens.

Do you think, theoretically speaking, that this concept could be used to target a particular video in a Divi video slider? I’d like to have a page with a slider full of videos, but from other pages, be able to link to, say, mywebsite.com/video/?argument_to_open_third_video, so that upon arrival on the video page, it plays the third video, rather than the first.

Hi Erik, I’ve not used the video slider, but theoretically speaking it probably is possible. One way to do it would be to trigger the slider control that brings the video you want into view, once the page loads. Another way could be to see if you can tell the slider which video should be the first visible one, once the page loads.