First, I will add here 3 resources for learning most of the things you need about shortcodes:
The idea is that you don’t echo
the content in your shortcode, but you return it so that WordPress can only print it where it is needed.
For your specific shortcode, the code should look look like this:
add_shortcode('week_menu','week_menu');
function week_menu() {
$week = date("W");
$year = date("Y");
$page_id = 3947;
$page_object = get_post($page_id);
$html="";
$html += '<div class="weekmanu-wrapper"><div class="weekmenu-content"><h2 class="h2wm">Menu for '.$year.', week '.$week.'.</h2></div>';
$html += $page_object->post_content;
$html += '</div>';
return $html;
}
Another way you could write this using the ob_
functions . Doing it this way, you no longer have to add all the content in a variable, but you can echo it and the result will be stored in the output buffer for being retrieved in the return
statement.
add_shortcode('week_menu','week_menu');
function week_menu() {
$date_string = date("Y, \w\e\e\k W");
$page_id = 3947;
$page_object = get_post($page_id);
// Here we turn on output buffering.
// Anything that is being output ( echoed ) after this line will be
// caught by the buffer.
// https://www.php.net/manual/en/function.ob-start.php
ob_start();
?>
<div class="weekmanu-wrapper">
<div class="weekmenu-content">
<h2 class="h2wm">Menu for <?php echo $date_string ?>.</h2>
</div>
<?php echo $page_object->post_content; ?>
</div>
<?php
// Here we get the contents of the output buffer and clean (erase) the buffer contents.
// After this line, echoing starts working normally again.
// https://www.php.net/manual/en/function.ob-get-clean.php
return ob_get_clean();
}