You have two big issues here are a few minor ones and some room for improvement. Lets look at your major mistakes first
-
What you have done well is to add your output to a variable and then returning the variable in the end. Shortcodes should always return their output, not echo it. What you have done wrong here is to use the wrong template tags. The
the_*
prefix means that the template tag is echoing its output, not returning it. You should be using the template tags with theget_*
prefix which return its output -
You should not hook your shortcode, specially not to
init
.init
runs way to early for most functionalities, by then they are not registered yet. That is why your shortcode does not output anything
Some of the smaller mistakes:
-
You should be using
wp_reset_postdata()
, notwp_reset_query()
. The latter is used withquery_posts
which you must never ever use -
wp_reset_postdata()
should be used right after you close yourwhile
statemnet and before closing yourif
statement. This will prevent resetting something that does not exist if you don’t have any posts -
You should define your variable before using it before the loop. If you don’t, and you do not have posts, this will lead to an undefined variable notice, which is bug, and we don’t want bugs
Now, lets look at the nitty-gritty stuff. This does not improve performance and can be omitted. This is just tips to make your code more readable and easier to debug
-
Although it is valid php, don’t use
:
andendwhile
andendif
. The major reason is debugging and readability. Most (and I would tend to say no) code editors does not support this syntax, making it a nightmare to debug. Ask me how frustrating it is debugging a lot while and if statements using this syntax. I prefer the old curlies (braces), it is supported by all code editors AFAIK, and make debugging a breeze -
Properly indent your code, it does help a lot with readability and debugging
-
Always add your action before you declare your function. With the introduction of closures in php, it just makes much more sense to do it this way
-
Don’t concatenate 10 lines of code to one variable on line one, one tend to get lost down the line. Properly concatenate each line separately
You can try the following:
add_shortcode('service-shortcode', 'service_shortcode');
function service_shortcode()
{
$return_string = '';
$service = new WP_Query(array(
'orderby' => 'rand',
'post_type' => 'our_service' ,
'posts_per_page' => 1,
));
if ($service->have_posts()) {
while ($service->have_posts()) {
$service->the_post();
$return_string .= '<div class="row">';
$return_string .= '<div class="col-md-3 col-sm-6">';
$return_string .= '<div class="content">';
$return_string .= '<h2>'.get_the_title().'</h2>';
$return_string .= '<p>'.get_the_content('').'</p>';
$return_string .= '</div>';
$return_string .= '</div>';
$return_string .= '</div>';
}
wp_reset_postdata();
}
return $return_string;
}