admin管理员组文章数量:1336134
This question is about a very specific circumstance.
The site has one template file that can run a default category query with thumbnail, linked title and excerpt, or it can run a linked title only depending on a viewer choice. That is, once on the category default page, the viewer can click a List Only option. https:// domain/category/ glossary-of-wood-terms ?format=list This part works fine.
The second option (linked title only) should pick up the whole dataset, not a paginated dataset.
Using a pre_get_posts, I can set the query to get the whole dataset (not paginated) with
$query->set( 'posts_per_page', -1 );
and an if test that will only run that code on a particular URL. Here is where the problem lies.
It turns out that WordPress sees the address as https://domain/category/glossary-of-wood-terms?category_name=glossary-of-wood-terms with the query string hidden. But WordPress is treating it as a $_POST variable not a $_GET variable.
What address should I used in the pre_get_posts test?
Here is the code I originally added to functions.php
function get_all_terms($query)
{
// This will run for all main queries that are not in wp-admin.
// You may want "is_archive()", "is_page('slug')" or some other condition.
if(empty($Format))
$Format = 'test 1';
echo $Format;
if ( ! is_admin() && $query->is_main_query() && ($Format == 'list'))
{
$query->set( 'posts_per_page', -1 );
}
}
add_action( 'pre_get_posts', 'get_all_terms' );
Here is code I added to see what WordPress shows as the URL. This code is in header.php. There is an echo on $current_url in the body
global $wp;
if(!empty($_POST['format']))
$Format = $_POST['format'];
$current_url = add_query_arg( $wp->query_vars, home_url( $wp->request ));
This question is about a very specific circumstance.
The site has one template file that can run a default category query with thumbnail, linked title and excerpt, or it can run a linked title only depending on a viewer choice. That is, once on the category default page, the viewer can click a List Only option. https:// domain/category/ glossary-of-wood-terms ?format=list This part works fine.
The second option (linked title only) should pick up the whole dataset, not a paginated dataset.
Using a pre_get_posts, I can set the query to get the whole dataset (not paginated) with
$query->set( 'posts_per_page', -1 );
and an if test that will only run that code on a particular URL. Here is where the problem lies.
It turns out that WordPress sees the address as https://domain/category/glossary-of-wood-terms?category_name=glossary-of-wood-terms with the query string hidden. But WordPress is treating it as a $_POST variable not a $_GET variable.
What address should I used in the pre_get_posts test?
Here is the code I originally added to functions.php
function get_all_terms($query)
{
// This will run for all main queries that are not in wp-admin.
// You may want "is_archive()", "is_page('slug')" or some other condition.
if(empty($Format))
$Format = 'test 1';
echo $Format;
if ( ! is_admin() && $query->is_main_query() && ($Format == 'list'))
{
$query->set( 'posts_per_page', -1 );
}
}
add_action( 'pre_get_posts', 'get_all_terms' );
Here is code I added to see what WordPress shows as the URL. This code is in header.php. There is an echo on $current_url in the body
global $wp;
if(!empty($_POST['format']))
$Format = $_POST['format'];
$current_url = add_query_arg( $wp->query_vars, home_url( $wp->request ));
Share
Improve this question
edited May 31, 2020 at 20:58
Nora McDougall-Collins
asked May 30, 2020 at 23:02
Nora McDougall-CollinsNora McDougall-Collins
3952 silver badges15 bronze badges
8
|
Show 3 more comments
1 Answer
Reset to default 2Looking at the pre_get_posts
hook, the problem becomes apparent, the $Format
variable is being pulled out of thin air:
function get_all_terms($query)
{
if(empty($Format))
$Format = 'test 1';
echo $Format;
This variable is undefined, you cannot declare a variable in one file then use it in in other places like this. To do that you have to declare it as a global variable, and you have to declare this in every place you want to use it.
My recommendation: don't, there is no need for this variable, take a different approach.
Additionally, there's a misunderstanding about URLs. WordPress does not know or care what the URL by the time it gets to the pre_get_posts
step, and sometimes there is no URL! E.g. in a WP CLI command.
Query variables are just the parameters that WP_Query
takes. Rewrite rules convert pretty URLs into lists of query variables, and you can put a query variable in the URL to override most of the time. But query variables isn't meant to be a representation of what WP thinks the URL is. They can even disagree with the URL!
Instead, if you want to change behaviour based on the URL, just check the URL:
function nora_get_all_terms( \WP_Query $query ) {
if ( !isset( $_GET['format' ] ) ) {
return;
}
Here we check the format URL parameter, and if it is not set, we return early. If it is set, continue the function and use $_GET['format']
.
Some notes:
get_all_terms
is a very generic name, at the very least prefix it or use a more specific name- global variables are bad, avoid them
- Don't
echo
out, use a tool such as query monitor to look at the query variables, or better yet, use xdebug + and IDE such as PHPStorm to look at the variables directly with a debugger - keep variable names to lowercase, and follow the WP coding standards
- A decent code editor will automatically indent for you, the codes indenting is broken and this can cause easy mistakes that are impossible when indenting is correct. At a minimum, fix indenting before showing the code to other people as broken indenting makes code difficult to read and understand
$_POST
and$_GET
are populated by PHP, not WordPress.$_POST
won't be populated unless your browser made aPOST
request- Always start with the problem you were trying to solve, don't fall into the trap of an XY question
- Consider looking into rewrite rules, you can add a custom query variable, and remove the URL parameter entirely by embedding it in the URL itself with a
format/list
on the end - whitelist and validate the format value, otherwise people can put malicious values in and if the format value is printed anywhere on the page you'll have a URL injection attack
本文标签: templatesCan a link in WordPress contain a query string that is picked up as POST
版权声明:本文标题:templates - Can a link in WordPress contain a query string that is picked up as $_POST 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742384600a2464776.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
$_POST
variable, WP doesn't handle query values differently if they're GET or POST. Can you include your fullpre_get_posts
filter in your question? It's very difficult to debug without seeing the code – Tom J Nowell ♦ Commented May 30, 2020 at 23:40pre_get_posts
always run on queries, but as I said, yourpre_get_posts
filter is missing from your question, making it 1000x times more difficult to answer your question, if not impossible to answer. Update your question to include the code – Tom J Nowell ♦ Commented May 31, 2020 at 20:40