WordPress includes a lot of helper functions that can make your life as a developer much easier. One function in particular that I really love is add_query_arg(), which provides an extremely simply way to append query variables to any URL. Query vars, in case you’re not familiar with them, allow you to perform any number of tasks based on the information passed through the URL.
The add_query_arg() function accepts three parameters:
- name – the argument name
- value – the value of the argument in the first parameter
- URL – the URL to append the argument to. This defaults to the current URL
Let’s say, for example, that you want to create a button that redirects to a URL like this:
http://yoursite.com/?view=list
The view variable can be used, for example, to modify your template layout, and so you might also have this:
http://yoursite.com/?view=grid
It is pretty easy to create your URL like this:
<?php echo home_url('?view=list'); ?> |
But if you are dealing with more complex URL structures, especialy URLs that are not always the same, perhaps because they contain other query variables, this does not work reliably. And this is where add_query_arg() comes in.
The example below will render the exact same thing as the example above with home_url(), but it will be much more flexible (I’ll show you why in a moment):
<?php echo add_query_arg( 'view', 'list', home_url() ); ?> |
The result of this will be:
http://yoursite.com/?view=list
The question you should ask now is “why should I use add_query_arg() instead of just adding ?view=list to my URL?”. The answer is simple: add_query_arg() allows you to append a query arg to any existing URL without disturbing existing variables AND it will ensure that the resulting URL has proper trailing slashes (or doesn’t). Take the following URL as an example:
http://yoursite.com/?something=value&second-var=this-value
Imagine that is the URL you are working with and you need to now append the “view=list” argument. First of all, the following will fail:
http://yoursite.com/?something=value&second-var=this-value?view=list
It will fail because only the very first argument starts with a ?, all others are separated with an &, so this puts you in a situation where you need to do some checking to figure out whether you need to use “?view=list” or “&view=list”. Checks like that, while not terribly difficult, do require a couple of conditional checks. Why do that when you can simply do the following?
1 2 3 4 5 6 7 | <?php echo add_query_arg( 'view', 'list', 'http://yoursite.com/?something=value&second-var=this-value' ); ?> |
The add_query_arg() function will take care of adding our new argument with either ? or &. This means that the following will also work:
1 2 3 4 5 6 7 | <?php echo add_query_arg( 'view', 'list', home_url() ); ?> |
And let’s say that you don’t necessarily know what the URL is, or perhaps you just want to append the arguments to the current URL, no matter what it is. You can do this:
1 2 3 4 5 6 | <?php echo add_query_arg( 'view', 'list' ); ?> |
By leaving out the third parameter, WordPress will simply append your arguments to whatever the current URL is, including any existing query variables.
Adding Multi Query Arguments
Often times you will need to add multiple variables to your URL, and add_query_arg() makes this extremely simple. The first two parameters can be replaced with an associative array of key to value pairs. Like this:
1 2 3 4 5 6 7 8 9 | <?php echo add_query_arg( array( 'var_key' => 'key_value', 'another_var' => 'My Value' ), home_url() ); ?> |
This will result in a URL like this:
http://yoursite.com/?var_key=key_value&another_var=My%20Value
Note that add_query_arg() takes care of URL encoding the values through the use of urlencode_deep() automatically, so there is no need to encode the values yourself.
Second note: add_query_arg() does not escape the values returned so please be sure you properly escape URLs from this function. For example:
echo esc_url( add_query_arg( array( 'action' => 'edit', => 'post_id' => $_REQUEST['id'] ) ) ); |
Hi Pippin,
Very, very useful. Needed this before and built it myself, because I didn’t know this helper existed.
Thanks!
Gijs
For added security, especially for dynamically generated URLs, use esc_url e.g.
When is this called? What hook do I use to render this link in a list of posts, say, in a “recent posts” widget? I want to add a query argument to all posts with a variable.
You have to use it when you build the URL. Modifying site-wide URLs is a completely different can of worms. You could probably use the “pre_post_link” filter to modify it: http://core.trac.wordpress.org/browser/tags/3.7.1/src/wp-includes/link-template.php#L115
I believe the example for Adding Multi Query Arguments is incorrect.
‘My Value’ does not get urlencoded.
For an example, see https://gist.github.com/salcode/a43940a2ab9b858f317a
Yep, sure enoughm you are right.
instead of home_url, if we want to use it on product category URLs only, then how shall we use it?
I want to add URL parameter on product categories dynamically, for example:
by default you have product category url like:
example.com/product-category/furniture/living/armchairs/
Now I want to append:
example.com/product-category/furniture/living/armchairs/?fwp_product_categories=armchairs (append the last category dynamically).