How to pass extra variables in URL with WordPress

PhpWordpressUrlGet

Php Problem Overview


I am having trouble trying to pass an extra variable in the url to my WordPress installation.

For example /news?c=123

For some reason, it works only on the website root www.example.com?c=123 but it does not work if the url contains any more information www.example.com/news?c=123. I have the following code in my functions.php file in the theme directory.

if (isset($_GET['c'])) 
{
  setcookie("cCookie", $_GET['c']); 
}

if (isset($_SERVER['HTTP_REFERER']))
{
  setcookie("rCookie", $_SERVER['HTTP_REFERER']);
}

Any Ideas?

Php Solutions


Solution 1 - Php

To make the round trip "The WordPress Way" on the "front-end" (doesn't work in the context of wp-admin), you need to use 3 WordPress functions:

  • add_query_arg() - to create the URL with your new query variable ('c' in your example)
  • the query_vars filter - to modify the list of public query variables that WordPress knows about (this only works on the front-end, because the WP Query is not used on the back end - wp-admin - so this will also not be available in admin-ajax)
  • get_query_var() - to retrieve the value of your custom query variable passed in your URL.

Note: there's no need to even touch the superglobals ($_GET) if you do it this way.

Example

On the page where you need to create the link / set the query variable:

if it's a link back to this page, just adding the query variable

<a href="<?php echo esc_url( add_query_arg( 'c', $my_value_for_c ) )?>">

if it's a link to some other page

<a href="<?php echo esc_url( add_query_arg( 'c', $my_value_for_c, site_url( '/some_other_page/' ) ) )?>">

In your functions.php, or some plugin file or custom class (front-end only):

function add_custom_query_var( $vars ){
  $vars[] = "c";
  return $vars;
}
add_filter( 'query_vars', 'add_custom_query_var' );

On the page / function where you wish to retrieve and work with the query var set in your URL:

$my_c = get_query_var( 'c' );

On the Back End (wp-admin)

On the back end we don't ever run wp(), so the main WP Query does not get run. As a result, there are no query vars and the query_vars hook is not run.

In this case, you'll need to revert to the more standard approach of examining your $_GET superglobal. The best way to do this is probably:

$my_c = filter_input( INPUT_GET, "c", FILTER_SANITIZE_STRING );

though in a pinch you could do the tried and true

$my_c = isset( $_GET['c'] ? $_GET['c'] : "";

or some variant thereof.

Solution 2 - Php

There are quite few solutions to tackle this issue. First you can go for a plugin if you want:

Or code manually, check out this post:

Also check out:

Solution 3 - Php

Since this is a frequently visited post i thought to post my solution in case it helps anyone. In WordPress along with using query vars you can change permalinks too like this

www.example.com?c=123 to www.example.com/c/123

For this you have to add these lines of code in functions.php or your plugin base file.

From shankhan's anwer

add_filter( 'query_vars', 'addnew_query_vars', 10, 1 );
function addnew_query_vars($vars)
{   
    $vars[] = 'c'; // c is the name of variable you want to add       
    return $vars;
}

And additionally this snipped to add custom rewriting rules.

function custom_rewrite_basic() 
{
    add_rewrite_rule('^c/([0-9]+)/?', '?c=$1', 'top');
}
add_action('init', 'custom_rewrite_basic');

For the case where you need to add rewrite rules for a specifc page you can use that page slug to write a rewrite rule for that specific page. Like in the question OP has asked about

www.example.com/news?c=123 to www.example.com/news/123

We can change it to the desired behaviour by adding a little modification to our previous function.

function custom_rewrite_basic() 
{
    add_rewrite_rule('^news/([0-9]+)/?', 'news?c=$1', 'top');
}
add_action('init', 'custom_rewrite_basic');

Hoping that it becomes useful for someone.

Solution 4 - Php

add following code in function.php

add_filter( 'query_vars', 'addnew_query_vars', 10, 1 );
function addnew_query_vars($vars)
{	
	$vars[] = 'var1'; // var1 is the name of variable you want to add    	
	return $vars;
}

then you will b able to use $_GET['var1']

Solution 5 - Php

<?php
$edit_post = add_query_arg('c', '123', 'news' );

?>

<a href="<?php echo $edit_post; ?>">Go to New page</a>

You can add any page inplace of "news".

Solution 6 - Php

One issue you might run into is is_home() returns true when a registered query_var is present in the home URL. For example, if http://example.com displays a static page instead of the blog, http://example.com/?c=123 will return the blog.

See https://core.trac.wordpress.org/ticket/25143 and https://wordpress.org/support/topic/adding-query-var-makes-front-page-missing/ for more info on this.

What you can do (if you're not attempting to affect the query) is use add_rewrite_endpoint(). It should be run during the init action as it affects the rewrite rules. Eg.

add_action( 'init', 'add_custom_setcookie_rewrite_endpoints' );

function add_custom_setcookie_rewrite_endpoints() {
    //add ?c=123 endpoint with
    //EP_ALL so endpoint is present across all places
    //no effect on the query vars
    add_rewrite_endpoint( 'c', EP_ALL, $query_vars = false );
}

This should give you access to $_GET['c'] when the url contains more information like www.example.com/news?c=123.

Remember to flush your rewrite rules after adding/modifying this.

Solution 7 - Php

to add parameter to post urls (to perma-links), i use this:

add_filter( 'post_type_link', 'append_query_string', 10, 2 );
function append_query_string( $url, $post ) 
{
	return add_query_arg('my_pid',$post->ID, $url);
}

output:

http://yoursite.com/pagename?my_pid=12345678

Solution 8 - Php

This was the only way I could get this to work

add_action('init','add_query_args');
function add_query_args()
{ 
    add_query_arg( 'var1', 'val1' );
}

http://codex.wordpress.org/Function_Reference/add_query_arg

Solution 9 - Php

In your case, Just add / after url and then put query arguments. like

www.example.com/news/?c=123 or news/?c=123

instead of

www.example.com/news?c=123 or news?c=123

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChuck DView Question on Stackoverflow
Solution 1 - PhpTom AugerView Answer on Stackoverflow
Solution 2 - PhpSarfrazView Answer on Stackoverflow
Solution 3 - PhpShahbaz A.View Answer on Stackoverflow
Solution 4 - PhpshankhanView Answer on Stackoverflow
Solution 5 - Phpuser3777827View Answer on Stackoverflow
Solution 6 - Phpniall.campbellView Answer on Stackoverflow
Solution 7 - PhpT.ToduaView Answer on Stackoverflow
Solution 8 - PhpbrenjtView Answer on Stackoverflow
Solution 9 - PhpVicky PView Answer on Stackoverflow