Key Takeaways
- To make the carousel arrows functional, a JavaScript file is created and linked to WordPress using the wp_enqueue_script() function, which is placed in the display_carousel() function condition to ensure it is only included when the carousel is displayed.
- The carousel’s ul block is moved horizontally to display different items by adjusting its margin-left CSS property; a negative left margin aligns the left side of the next item with the left side of the carousel block.
- A function, carousel_show_another_link(), is created to display another item based on the direction parameter (-1 for previous item, 1 for next item); it calculates the index of the new item to display and checks if it exists before moving the ul block.
- Two functions, carousel_previous_link() and carousel_next_link(), are created and attached to the respective arrow events, and call the carousel_show_another_link() function with the appropriate parameter; a bug is prevented by initializing the margin-left property of the ul block to 0 when the document is ready.
Without styling, the WordPress carousel we’ve built in the first part of this tutorial is just a list of items, but it is at least useful, in the sense that they’re all visible. The CSS we added in part two of this tutorial enhanced the display of the carousel, but now the problem is that only the first item is shown to the user and there’s no way to display the rest of the items.
We added arrows to our carousel, to allow the user to navigate between the different items, and now it’s time to make them usable, with a bit of JavaScript.
In the continuation of this tutorial, we’ll learn how to properly include our script, then we’ll write a script that will launch a function which animates the items when the user hits an arrow.
Linking a JavaScript File
Here we’ll use JavaScript to make our arrows useful. As for the CSS part, create a new file. I called it carousel.js
and placed it in the root of the plugin’s folder.
We need to indicate to WordPress that we are using the JavaScript file. To do this, we’ll use the wp_enqueue_script()
function.
wp_enqueue_script('carousel', plugin_dir_url(__FILE__) . 'carousel.js', array('jquery'), '1.0', true);
The first two parameters are the same as for wp_enqueue_style()
. Then we find an array. This array lists the dependencies, the scripts needed by our script to work. I chose to use jQuery to get around the browser compatibility issues so I indicate to WordPress that I want to use it: as we saw in our article about properly including scripts in WordPress, 'jquery'
is a recognised value in WordPress.
The fourth parameter is the version number of the script. It’s not very important here (see the article previously linked for more information), but we needed to use the last parameter and set it to true
so that our script will be included in the footer.
The advantage of choosing the footer instead of the header is that we can use wp_enqueue_script()
wherever we want. We don’t have the constraint of using it before wp_head()
as with wp_enqueue_style()
. We will then be able to include our script only if it is necessary: only if we display the carousel.
The best place to put wp_enqueue_script()
therefore is in the condition of our display_carousel()
function. We will display the carousel only if there are items to display, so we will include our script with the same condition.
function display_carousel() {
// …
// Here we retrieve the links
// …
if (!empty($links)) {
wp_enqueue_script(/* parameters listed above */);
// …
// Display
// …
}
}
Now we are ready to edit our JavaScript file.
What Do We Want to Do?
First we encapsulate all our code in a function. To prevent collisions with other libraries, WordPress disables the use of $
in jQuery. We can enable it again with this function.
jQuery(function($) {
// The code we will write must be placed here
});
There are many different ways to make a carousel, even without modifying our HTML code. Here I suggest you move the ul
block. It contains all our items in a row so we can move it horizontally to display one or another item by setting its position. See the schema below, already seen in the previous part of this tutorial, to see what we want to do.
To move it we will play with its margin-left
CSS property. By default it is set to 0
and therefore “display” the first item. The first item is big enough to fill the carousel block and the second item, which is next to it, can’t be seen thanks to the overflow
property.
To display the second item, we have to move the ul
block to the left, in order to align the left side of the second item with the left side of the carousel block. This can be achieved with a negative left margin. To test what value we need to use we can experiment with some CSS code (which we remove right after, as we don’t need it).
#carousel ul {
margin-left: -100%;
}
This simple line deserves an explanation. If you test it, you should see that the first item is not displayed, we see instead the second item. You can test another value to better understand what happened. With -50px
we move the ul
block 50 pixels to the left for example. With the values I showed you in the CSS above, as the carousel has a width of 900 pixels, I can display the second item with a value of -900px
.
However we can use percentages instead. The advantage is that this percentage is relative to the container. Here “100%” is equal to “900 pixels” so, if we give a value of -100%
, we hide the first item and display the second. Using percentages allows you to modify the width of the container without modifying the values of the margin-left
property.
The Function to Display Another Item
First, we’ll write the function which will display another item. This one will accept one parameter, the direction. If we want to display the previous item, this direction must be set to -1
and, if we want to display the next item, it must be set to 1
.
function carousel_show_another_link(direction) {
}
Where Do We Go?
To determine the value to be assigned to margin-left
, we need to know where we are. There are a number of possible ways to achieve this, and I chose one that uses only the current value of the margin-left
property.
var ul = $('#carousel ul');
var current = -parseInt(ul[0].style.marginLeft) / 100;
The first line retrieves the ul
block. As we will reuse it later, storing it in a variable is a good idea. The second line can seem a bit weird. The aim is to store an integer representing the current displayed item. The first item will be represented by 0
, the second by 1
, etc.
To achieve this we get the current value of the margin-left
property. The problem is that this value is something like -200%
and we want a number: to remove the “%” we use the parseInt()
function which transforms the value into an integer (e.g. '-200%'
becomes -200
). As we want a positive integer we add a “minus” sign (e.g. to get 200
from -200
), and we divide by 100 to get the value we want (e.g. 2
, not 200
).
You might wonder why we didn’t use ul.css('margin-left')
to get the value of the margin-left
property. In fact, .css()
is a jQuery method and, in our context, seems to be a better idea. The problem is this method won’t give us a percentage. Using the same values as above, if the current item is the third one, the margin-left
property is set to -200%
while the .css()
method will return -1800px
. To calculate the current item using this value in pixels, we then need to use the width of the big container, and I prefer using only the ul
block.
Now we can calculate the index of the item to display, thanks to the direction given in the argument of our function.
var new_link = current + direction;
Does the New Item Exist?
Before displaying the new item we need to test whether it exists. If new_link
is less than or equal to -1
, or is greater than or equal to the total number of items, then it does not exist and we can’t display it, so moving the ul
block is not a good idea. Note that this test can seem redundant as arrows are not displayed when we can’t go further, but ensuring that something can actually be done is always a good idea.
var links_number = ul.children('li').length;
if (new_link >= 0 && new_link < links_number) {
// Moving the block
}
First we get the total number of items, which is the number of li
tags in our list. This number is useful for the condition we described above as we want a positive integer that mustn’t be greater than or equal to the number of items (don’t forget that we begin with 0
and not 1
).
Displaying the New Item
Finally, the block move can be achieved with a single line. We have to calculate the new value of margin-left
. To do that, let’s think about it. For every “passed” item we have a width of 100%
to travel. That way, the new value of margin-left
is 100 times the new item position we just calculated, with a minus sign to go to the left.
ul.animate({'margin-left': -(new_link * 100) + '%'});
I chose here to use a jQuery animation, but you are free to create your own, or even modify the settings of this one.
Some Aliases for a More Practical Use
We will now create the functions which will be called every time the user clicks on an arrow. These functions don’t require a huge amount of code, as the only thing they do is call the carousel_show_another_link()
function with the right parameter. Below is the code for the function which is called when we click a “previous” arrow.
function carousel_previous_link() {
carousel_show_another_link(-1);
return false;
}
Note the return false;
to prevent the default behavior of our arrows (don’t forget that they are links). That way, the URL won’t change when the user clicks an arrow.
The function which displays the “next” item is exactly the same, but with 1
as the parameter for carousel_show_another_link()
. I chose to call it carousel_next_link()
.
Attaching the Events
Finally we have to make these functions useful, by attaching the right events to the right elements. We will do that in a new function, called when we can be sure that our elements are created: when the document is loaded.
$(document).ready(function() {
// Here we attach the events
});
We want to attach the carousel_previous_link()
function to every “previous” arrow. With the DOM tree of our carousel we can retrieve them easily, in the same way we retrieved them when we wanted to style them in the CSS.
$('#carousel ul li a.carousel-prev').click(carousel_previous_link);
Then we can attach the carousel_next_link()
function to the right arrows (#carousel ul li a.carousel-next
) in the same way.
You can test this code but a bug should appear: the first time the carousel_show_another_link()
function is called, the CSS property margin-left
for our ul
block doesn’t exist, so an error will occur when we try to retrieve its value.
To prevent this bug we can initialize the value of this property. Still in the function called when the document is ready (before attaching the events for example), add the following line.
$('#carousel ul').css('margin-left', 0);
This sets the margin-left
property of our ul
block to 0
as a default. This property will now exist, without moving the block.
You can now click away at the arrows, the carousel is finished and it works!
In Conclusion
In this tutorial we walked through building a carousel plugin using the WordPress Links Manager API. It was a good example of use of this API, but also it was a good way to see how to combine PHP, HTML, CSS and JavaScript in a WordPress plugin.
In closing, I would say that there are many different ways to build a carousel, even if we keep the HTML code we generated: we could choose different styles, or different ways to write the script. In fact, the script we wrote here is just an example and we could write a totally different one with the same result.
You can decide for yourself if you like the code we used here. If not, don’t hesitate to edit it!
Even if you liked what we did here, you can still enhance the result. For example, visitors must hit the arrows to see other items: you can try to automatically animate the carousel with the function setTimeout()
.
If you’d like to see the finished code, or try the plugin for yourself, it is available to download here.
Currently a math student, Jérémy is a passionate guy who is interested in many fields, particularly in the high tech world for which he covers the news everyday on some blogs, and web development which takes much of his free time. He loves learning new things and sharing his knowledge with others.