admin管理员组文章数量:1026989
Preamble
In my functions.php
file I added a custom shortcode. This shortcode takes a query as a parameter and queries the wordpress database. From there it takes the posts content and returns it. This shortcode is then used on a non-custom page.
The issue
Using the shortcode on any page with a given and correct query, the shortcode will display the properly formatted content, but twice. This is although the query only returns one post.
So let's say I had [query_post query='post_type="post"']
on a page. The shortcode returns all posts of the type post
(which in my example is just one). The content is displayed fine, but at the end of the page the already displayed content repeats again. Why is this?
The code
In the functions.php
I appended this:
function query_post_shortcode_function( $atts ) {
// Argument parsing
$arguments = shortcode_atts( array(
'query' => "",
), $atts );
// Query
$posts = query_posts( $arguments['query'] );
// Getting the content for each queried post
unset($content);
foreach ($posts as $post) {
$content .= apply_filters( 'the_content', $post->post_content );
}
return wpautop($content);
}
add_shortcode( 'query_post', 'query_post_shortcode_function');
Which, as I've stated already, will query the wordpress database for a post and then return its content.
Steps taken already
- Instead of appending the content from all posts, I tried just assigning it. So
$content = apply_filters(...)
insted of.=
. This did not change the result - Echoing something inbetween will show in the first iteration of the returned content, but not in the second one
Preamble
In my functions.php
file I added a custom shortcode. This shortcode takes a query as a parameter and queries the wordpress database. From there it takes the posts content and returns it. This shortcode is then used on a non-custom page.
The issue
Using the shortcode on any page with a given and correct query, the shortcode will display the properly formatted content, but twice. This is although the query only returns one post.
So let's say I had [query_post query='post_type="post"']
on a page. The shortcode returns all posts of the type post
(which in my example is just one). The content is displayed fine, but at the end of the page the already displayed content repeats again. Why is this?
The code
In the functions.php
I appended this:
function query_post_shortcode_function( $atts ) {
// Argument parsing
$arguments = shortcode_atts( array(
'query' => "",
), $atts );
// Query
$posts = query_posts( $arguments['query'] );
// Getting the content for each queried post
unset($content);
foreach ($posts as $post) {
$content .= apply_filters( 'the_content', $post->post_content );
}
return wpautop($content);
}
add_shortcode( 'query_post', 'query_post_shortcode_function');
Which, as I've stated already, will query the wordpress database for a post and then return its content.
Steps taken already
- Instead of appending the content from all posts, I tried just assigning it. So
$content = apply_filters(...)
insted of.=
. This did not change the result - Echoing something inbetween will show in the first iteration of the returned content, but not in the second one
1 Answer
Reset to default 1Solution attempt
Due to @AlexanderHolsgrove's comment, I tried reutrning a simple string, so instead of return wpautop($content);
I tried return "test return";
. This outputted the string on top of the queried post content. Which is weird, because I do not echo nor do I return the post content in any way now.
So I tried leaving out the echo entirely, and it still displayed the post content. Now @MikeNGarret's and @mrben522's answer comes into play. After reading through the SO answer and the corresponding WordPress Codex entry, I found out that query_posts()
actually kind of replaces the post you are running the query on (it's all a bit confusing, read through the codex or view the answer to get some more detail). This finally left me with two answers:
Solution
The not suggested way is to just use query_posts()
. It displayed the content fine in my circumstances, but from what I understand, it is not optimal at all and should not be used.
The real solution is to use WP_Query
or rather an isntance of it. Basically I rewrote the whole lower section of my code to achieve this:
function query_post_shortcode_function( $atts ) {
// Argument parsing
$arguments = shortcode_atts( array(
'query' => "",
), $atts );
// Query
$wpQuery = new WP_Query( $arguments['query'] );
// The Loop
if ( $wpQuery->have_posts() ) {
// Capture output
ob_start();
while ( $wpQuery->have_posts() ) {
$wpQuery->the_post();
echo apply_filters( 'the_content', get_the_content() );
}
// Return output
return ob_get_clean();
}
}
add_shortcode( 'query_post', 'query_post_shortcode_function');
I create a new instance of the WP_Query and give my single argument to it. Then I check if the created instance has posts and if there are, I loop through them echoing all output with the applied 'the content'
filter. This output is captured by ob_start()
and then returned by ob_get_clean()
.
So far it has worked flawlessly and did exactly what I wanted to achieve. I hope others can use this information as well and that my self-written answer is correct and applicable to not just me.
Preamble
In my functions.php
file I added a custom shortcode. This shortcode takes a query as a parameter and queries the wordpress database. From there it takes the posts content and returns it. This shortcode is then used on a non-custom page.
The issue
Using the shortcode on any page with a given and correct query, the shortcode will display the properly formatted content, but twice. This is although the query only returns one post.
So let's say I had [query_post query='post_type="post"']
on a page. The shortcode returns all posts of the type post
(which in my example is just one). The content is displayed fine, but at the end of the page the already displayed content repeats again. Why is this?
The code
In the functions.php
I appended this:
function query_post_shortcode_function( $atts ) {
// Argument parsing
$arguments = shortcode_atts( array(
'query' => "",
), $atts );
// Query
$posts = query_posts( $arguments['query'] );
// Getting the content for each queried post
unset($content);
foreach ($posts as $post) {
$content .= apply_filters( 'the_content', $post->post_content );
}
return wpautop($content);
}
add_shortcode( 'query_post', 'query_post_shortcode_function');
Which, as I've stated already, will query the wordpress database for a post and then return its content.
Steps taken already
- Instead of appending the content from all posts, I tried just assigning it. So
$content = apply_filters(...)
insted of.=
. This did not change the result - Echoing something inbetween will show in the first iteration of the returned content, but not in the second one
Preamble
In my functions.php
file I added a custom shortcode. This shortcode takes a query as a parameter and queries the wordpress database. From there it takes the posts content and returns it. This shortcode is then used on a non-custom page.
The issue
Using the shortcode on any page with a given and correct query, the shortcode will display the properly formatted content, but twice. This is although the query only returns one post.
So let's say I had [query_post query='post_type="post"']
on a page. The shortcode returns all posts of the type post
(which in my example is just one). The content is displayed fine, but at the end of the page the already displayed content repeats again. Why is this?
The code
In the functions.php
I appended this:
function query_post_shortcode_function( $atts ) {
// Argument parsing
$arguments = shortcode_atts( array(
'query' => "",
), $atts );
// Query
$posts = query_posts( $arguments['query'] );
// Getting the content for each queried post
unset($content);
foreach ($posts as $post) {
$content .= apply_filters( 'the_content', $post->post_content );
}
return wpautop($content);
}
add_shortcode( 'query_post', 'query_post_shortcode_function');
Which, as I've stated already, will query the wordpress database for a post and then return its content.
Steps taken already
- Instead of appending the content from all posts, I tried just assigning it. So
$content = apply_filters(...)
insted of.=
. This did not change the result - Echoing something inbetween will show in the first iteration of the returned content, but not in the second one
-
If you change
return wpautop($content);
toreturn "some string";
do you see "some string" twice or just once? If the shortcode is used just once and you only see one "some string" then the problem is with your post query. – Alexander Holsgrove Commented Apr 8, 2019 at 12:56 -
Try using WP_Query instead of
query_posts()
. codex.wordpress/Class_Reference/WP_Query – MikeNGarrett Commented Apr 8, 2019 at 13:03 -
2
@MikeNGarrett is right.
query_posts
is bad. here's a stack overflow answer that's a bit simpler explaining the different ways you can query the database for posts. https://wordpress.stackexchange/questions/1753/when-should-you-use-wp-query-vs-query-posts-vs-get-posts – mrben522 Commented Apr 8, 2019 at 13:44 - @AlexanderHolsgrove When I did that, I saw the string at the very top of the page, but the content of the queried post as well. Weird behavior. But I got it figured out now – moritzgrede Commented Apr 9, 2019 at 12:07
- @MikeNGarrett Thank you for pointing that out. I got it wokring now – moritzgrede Commented Apr 9, 2019 at 12:09
1 Answer
Reset to default 1Solution attempt
Due to @AlexanderHolsgrove's comment, I tried reutrning a simple string, so instead of return wpautop($content);
I tried return "test return";
. This outputted the string on top of the queried post content. Which is weird, because I do not echo nor do I return the post content in any way now.
So I tried leaving out the echo entirely, and it still displayed the post content. Now @MikeNGarret's and @mrben522's answer comes into play. After reading through the SO answer and the corresponding WordPress Codex entry, I found out that query_posts()
actually kind of replaces the post you are running the query on (it's all a bit confusing, read through the codex or view the answer to get some more detail). This finally left me with two answers:
Solution
The not suggested way is to just use query_posts()
. It displayed the content fine in my circumstances, but from what I understand, it is not optimal at all and should not be used.
The real solution is to use WP_Query
or rather an isntance of it. Basically I rewrote the whole lower section of my code to achieve this:
function query_post_shortcode_function( $atts ) {
// Argument parsing
$arguments = shortcode_atts( array(
'query' => "",
), $atts );
// Query
$wpQuery = new WP_Query( $arguments['query'] );
// The Loop
if ( $wpQuery->have_posts() ) {
// Capture output
ob_start();
while ( $wpQuery->have_posts() ) {
$wpQuery->the_post();
echo apply_filters( 'the_content', get_the_content() );
}
// Return output
return ob_get_clean();
}
}
add_shortcode( 'query_post', 'query_post_shortcode_function');
I create a new instance of the WP_Query and give my single argument to it. Then I check if the created instance has posts and if there are, I loop through them echoing all output with the applied 'the content'
filter. This output is captured by ob_start()
and then returned by ob_get_clean()
.
So far it has worked flawlessly and did exactly what I wanted to achieve. I hope others can use this information as well and that my self-written answer is correct and applicable to not just me.
本文标签: customizationDuplicated content with custom shortcode
版权声明:本文标题:customization - Duplicated content with custom shortcode 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745611040a2159003.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
return wpautop($content);
toreturn "some string";
do you see "some string" twice or just once? If the shortcode is used just once and you only see one "some string" then the problem is with your post query. – Alexander Holsgrove Commented Apr 8, 2019 at 12:56query_posts()
. codex.wordpress/Class_Reference/WP_Query – MikeNGarrett Commented Apr 8, 2019 at 13:03query_posts
is bad. here's a stack overflow answer that's a bit simpler explaining the different ways you can query the database for posts. https://wordpress.stackexchange/questions/1753/when-should-you-use-wp-query-vs-query-posts-vs-get-posts – mrben522 Commented Apr 8, 2019 at 13:44