How to pass extra variables in URL with WordPress - php
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?
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.
There are quite few solutions to tackle this issue. First you can go for a plugin if you want:
WordPress Quickie: Custom Query String Plugin
Or code manually, check out this post:
Passing Query String Parameters in WordPress URL
Also check out:
add_query_arg
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.
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']
<?php
$edit_post = add_query_arg('c', '123', 'news' );
?>
Go to New page
You can add any page inplace of "news".
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.
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
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
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
Related
Return URL query into post shortcode from functions.php in Wordpress
I am able to get the shortcode to return the string 'evs' inline in post [ when I plug that in to return ] but unable to return the post thumb url, using the same shortcode from functions.php What am I doing wrong here: function thumburl_func( $atts ){ $url = get_the_post_thumbnail_url('large'); // $eva = 'evs'; return strval($url); } add_shortcode( 'thumburl', 'thumburl_func' ); Been stuck on this for ages now - please save my week !
You are almost there, but you are using get_the_post_thumbnail_url incorrectly. The size of the image you want is the second argument into the function, the first argument is the post id. Although the post id is optional, if you want to pass in the size, you need include something as the first argument. If you are in the Wordpress "loop" and the global $post is set up, you can simply pass in null e.g. $url = get_the_post_thumbnail_url(null, 'large'); However, as this is for a shortcode, the best option is to explicitly pass in the post id - this means the shortcode will work even outside the loop (e.g. in a widget). function thumburl_func( $atts ){ // 1. get the post id of the current post $post_id = get_queried_object_id(); // 2. pass the post is into get_the_post_thumbnail_url $url = get_the_post_thumbnail_url($post_id, 'large'); return $url; } add_shortcode( 'thumburl', 'thumburl_func' );
In the WordPress i18n project, add prefixes by triggering internal links with variables
We are working on a localization project in WordPress. In fact, we can correctly add the active browser URL with language support. I'll add the details and the entire code below. Don't worry, my question will not be so open-ended and I will make it more specific. Step 1 First of all, we should add a variable in the link structure to the WordPress algorithm. function custom_rewrite_basic_query_vars( $query_vars ){ $query_vars[] = 'lang'; return $query_vars; } add_filter( 'query_vars', 'custom_rewrite_basic_query_vars' ); Thus, WordPress detects a variable such as ?lang= and includes it in the query mechanism. Step 2 Using the "add_rewrite_rule" function, you need to add the variable ?lang= to run in the background of WordPress's persistent link structure. Easy Example: /* LANG PREFIX + INDEX = localhost/en/ = localhost/?lang=en */ add_rewrite_rule( '^(en|fr|de|ru|tr)/?$', 'index.php?lang=$matches[1]', 'top' ); I will not add the remaining instances one by one, because you should use close to 20 rewrite rules. (Date, Category, Comment, Page, Text, Pagination, etc.) NOTE: Those who work on such a project and want to use these rules will add it if requested. Now our persistent connection structure supports variables for the language option. localhost/en/hello-world localhost/ru/hello-world localhost/de/04/07/2019 localhost/fr/page/2 etc. all the links you can think of. Step 3 If a variable is detected from the browser (for example: lang = en), we will display the contents of the previously saved inter-language translated. At this point we do not need any support. But when we get to step 4, we're stuck. Step 4 Activating the prefix language variable that was added before, users when using the links within the site, on all in-site navigation links. This means that if a user has access to the localhost/fr/hello-world link, they must reach the localhost/fr/contact link when they return to the Home Page or click the Contact link. To do this, you need to add the language prefix that is currently active in the browser to all in-site links. Unfortunately, this is the only point where we hang out and we can't find a solution. In fact, we tried most things before writing here. (Of course within our knowledge). We even looked at plug-ins that offer some language support. e.g. <WP Multilang> Of course, it's so complicated and so much code. We didn't even understand the plug-in. There is, of course, a logical way of doing this, and I hope that person sees this post and answers. Thank you sincerely for all your supports. One step to Answer After a while, I reached the following code and confirmed that it was working correctly. <?php function link_fn( $url ){ $lang = get_query_var('lang', false); if( $lang !== false && strpos( $url, $lang ) !== false ) $url = $url . $lang . '/'; return $url; } add_filter( 'shortcut_link', 'link_fn' ); add_filter( 'post_link', 'link_fn' ); add_filter( 'page_link', 'link_fn' ); add_filter( 'post_type_link', 'link_fn' ); add_filter( 'attachment_link', 'link_fn' ); add_filter( 'term_link', 'link_fn' ); add_filter( 'author_link', 'link_fn' ); add_filter( 'post_type_archive_link', 'link_fn' ); add_filter( 'day_link', 'link_fn' ); add_filter( 'month_link', 'link_fn' ); add_filter( 'year_link', 'link_fn' ); But at this point, I came across a problem. Here we get data like "localhost/hello-world/[LANG]/". What I want is "localhost/[LANG]/hello-world". To resolve this situation, you must add a REGEX query to the existing URL structure, if it does not contain the LANG, add the language code to the BASE URL. As a REGEX query should be added, I could not do this... I not want to answer my own question and confirm. In addition to the code I have written above, if there is an answer containing the query I want, I will mark it as the answer. Answer function link_fn( $url ){ $lang = get_query_var('lang', false); $site_url = get_option('home'); if( $lang !== false ) { $new_url = str_replace( $site_url, "", $url ); if( preg_match('/\b$lang\b/', $new_url) !== false ) { $url = $site_url."/".$lang.$new_url; } } return $url; } add_filter( 'home_url', 'link_fn' );
You got really far. Very nice effort I understand that what's between you and victory is only to change the outcome link structure? If yes, here is a solution: function link_fn($url){ $lang = get_query_var('lang', false); $url_parts = explode('/', $url); if ( $lang && in_array($lang, $url_parts) === false) { // lang does not exists in URL array_splice($url_parts, 1, 0, $lang); } $url = implode('/', $url_parts); return $url; }
I think one possible approach is to get all the HTML content use ob_start() and ob_get_contents() and then get all the link with regEx. Note: not all links are post/page, there are some static files too.
Can you language constant be a part of query string instead of path? instead of localhost/en/hello-world like this localhost/hello-world?lang=en If so take a look How to pass extra variables in URL with WordPress
I suggest to dig into this direction. add_action( 'pre_get_posts', 'lang_pre_get_posts', 1 ); function lang_pre_get_posts( $query ) { if ( is_admin() || ! $query->is_main_query() ){ return; } add_query_arg( 'lang', filter_var( $_COOKIE["lang"], FILTER_SANITIZE_STRING ) ); }
Pass Query to Wordpress URL
I used to have this structure of URL when user apply for offer on website: /apply/?apply=8282 What I'm trying to do now, is to make it look like /apply/8282 I did some research and come up with this 2 simple functions: function add_custom_query_var( $vars ){ $vars[] = "apply"; return $vars; } add_filter( 'query_vars', 'add_custom_query_var' ); function custom_rewrite_basic() { add_rewrite_rule('^apply/([0-9]+)/?', 'apply?apply=$1', 'top'); } add_action('init', 'custom_rewrite_basic'); However i can't get my ID, : echo "GET APPLY = ".$_GET['apply']."<br />"; How to get 8282 id number?
You could basicly access the id like this: $id = basename($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); It will return 8282. Its probably not that clean but its simple and I am using it aswell in a special case.
How to print out the variables of a redirected query string?
I have a basic redirection set up: function example_add_rewrite_rules() { $made_year = '(\d{4})?'; $make = '([a-z]{1,20})'; $model = '(.+)'; add_rewrite_rule( 'c/'.$made_year.'/?'.$make.'/'.$model.'/?$', 'index.php?page_id=46&made_year=$matches[1]&make=$matches[2]&model=$matches[3]', 'top' ); } add_action( 'init', 'example_add_rewrite_rules' ); My hope is that whenever the user hits the page with a URL of ../c/2015/ford/f150, that URL is stored in a query string. So, hopefully, the user will see this: "/c/2015/ford/f150" While I see this: "?page_id=46&year=2015&make=ford&model=f150" I cant tell if its working or not though. If I type in /c/2015/ford/f150 it will redirect me to the correct page/page_id. But I cant figure out for the life of me how to print those query variables to the page so I can at least see that the query string is configured correctly and has variables stored in year, make, and model. Summary: Have I done anything wrong in the code above? If not, how do I print the query string variables to the page? Aside: I'm jumping into an ocean of PHP and I'm still trying to learn how to swim. If I misstated something, forgive and correct me, for I know not what I do.
To use your own query vars within rewrite rules, you need to add them to the list of known vars: function wpd_query_vars( $qvars ) { $qvars[] = 'my_year'; $qvars[] = 'make'; $qvars[] = 'model'; return $qvars; } add_filter( 'query_vars', 'wpd_query_vars' , 10, 1 ); Then you can output their values in the template with get_query_var: echo get_query_var( 'model' );
Setting a custom canonical URL in Yoast Wordpress SEO Plugin
Reposted due to no replies. I'm having some trouble setting a custom canonical title using the Wordpress SEO API: http://yoast.com/wordpress-seo-api-docs/ I have a custom post type called designs which uses a custom URL rewrite. It takes the base page /design/ and adds the design name to it like /design/a-design/. The canonical in Wordpress SEO by default is the /design/ page. What I want to do is write a function which determines if it is a design page and return a different canonical. I can test whether it's a design page by doing if ($design == ""){ and I tried to use the custom permalink URL, but the function just removes the canonical completely. Here's my basic function: function design_canonical(){ if ($design == "") { // Leave blank and Yoast SEO will use default canonical for posts/pages } else { return $design['detailslink']; } } add_filter( 'wpseo_canonical', 'design_canonical' ) Quite clearly doing something wrong, but I'm not entirely sure what. Thoughts?
You could try something like: function design_canonical($url) { global $post; if ( get_post_type( $post->ID ) == 'design' ) { return site_url( '/design/' . $post->post_name ); } else { // Do nothing and Yoast SEO will use default canonical for posts/pages return $url; } } add_filter( 'wpseo_canonical', 'design_canonical' );
Hi i couldn't answer to the above post so I just make another one. I tried to use the answer from stealthyninja for a similar problem and it almost worked. Except the last part: the empty else statement. It renders no output if the rule doesn't match. Maybe Yoast updated his plugin on this within the last 2 years so I thought I should mention it here. The following Code-Snippet solved my problem: function design_canonical($url) { global $post; if ( get_post_type( $post->ID ) == 'design' ) { return site_url( '/design/' . $post->post_name ); } else { return $url; } } add_filter( 'wpseo_canonical', 'design_canonical' );