Shortcode afișează conținutul în partea de sus a the_content
Shortcode-ul generat de această funcție - o listă cu toate site-urile dintr-o rețea multisite - apare deasupra conținutului în loop, indiferent unde este plasat în editor.
Am analizat alte întrebări și răspunsuri conexe pe WPSE și am realizat că problema este legată de faptul că funcția folosește echo
în loc de return
, dar soluția nu este atât de simplă precum înlocuirea tuturor instanțelor de echo
cu return
în funcția de mai jos. Sau adăugarea parametrului echo=0
cu o funcție WP precum wp_list_pages()
.
Idei? Care este funcția care trebuie să returneze în loc să afișeze?
// Afișează un singur element de meniu
function projects_menu_entry($id, $title, $link_self)
{
global $blog_id;
if ($link_self || $id != $blog_id) {
echo '<li>';
if ($id == $blog_id) {
echo '<strong>';
}
$url = get_home_url($id);
if (substr($url, -1) != '/') {
// Notă: Am adăugat "/" la sfârșitul URL-ului deoarece WordPress
// nu o făcea automat în versiunea 3.0.4
$url .= '/';
}
echo '<a href="' . $url . '">' . $title . '</a>';
if ($id == $blog_id) {
echo '</strong>';
}
echo '</li>';
}
}
// Afișează întregul meniu
// Dacă $link_self este false, omite site-ul curent - folosit pentru afișarea meniului pe pagina principală
function projects_menu($link_self = true)
{
global $wpdb;
echo '<ul>';
projects_menu_entry(1, 'Acasă', $link_self);
$blogs = $wpdb->get_results("
SELECT blog_id
FROM {$wpdb->blogs}
WHERE site_id = '{$wpdb->siteid}'
AND spam = '0'
AND deleted = '0'
AND archived = '0'
AND blog_id != 1
");
$sites = array();
foreach ($blogs as $blog) {
$sites[$blog->blog_id] = get_blog_option($blog->blog_id, 'blogname');
}
natsort($sites);
foreach ($sites as $blog_id => $blog_title) {
projects_menu_entry($blog_id, $blog_title, $link_self);
}
echo '</ul>';
}
// Adaugă un shortcode [bloglist]
function bloglist_shortcode($atts)
{
projects_menu(false);
}
add_shortcode('bloglist', 'bloglist_shortcode');

Toate funcțiile trebuie să returneze un șir de caractere, nu ar trebui să folosești echo
nicăieri. Rescrie funcțiile, folosește o variabilă internă pentru a gestiona șirurile de caractere și returnează acea variabilă:
// Afișează un singur element din meniu
function projects_menu_entry($id, $title, $link_self)
{
global $blog_id;
$out = '';
if ($link_self || $id != $blog_id) {
$out .= '<li>';
if ($id == $blog_id) {
$out .= '<strong>';
}
$url = get_home_url( $id, '/' );
$out .= '<a href="' . $url . '">' . $title . '</a>';
if ($id == $blog_id) {
$out .= '</strong>';
}
$out .= '</li>';
}
return $out;
}
// Afișează întregul meniu
// Dacă $link_self este false, omite site-ul curent - folosit pentru afișarea meniului pe pagina principală
function projects_menu($link_self = true)
{
global $wpdb;
$out = '<ul>';
$out .= projects_menu_entry(1, 'Acasă', $link_self);
$blogs = $wpdb->get_results("
SELECT blog_id
FROM {$wpdb->blogs}
WHERE site_id = '{$wpdb->siteid}'
AND spam = '0'
AND deleted = '0'
AND archived = '0'
AND blog_id != 1
");
$sites = array();
foreach ($blogs as $blog) {
$sites[$blog->blog_id] = get_blog_option($blog->blog_id, 'blogname');
}
natsort($sites);
foreach ($sites as $blog_id => $blog_title) {
$out .= projects_menu_entry($blog_id, $blog_title, $link_self);
}
$out .= '</ul>';
return $out;
}
// Adaugă un shortcode [bloglist]
function bloglist_shortcode($atts)
{
return projects_menu(false);
}
add_shortcode('bloglist', 'bloglist_shortcode');
Pentru un exemplu similar, extins, vezi: Cum să returnezi conținutul buclei.

Nu poți înlocui instanțele echo
pentru că poți returna o singură dată. Trebuie să construiești un șir de caractere și să returnezi acel șir.
function projects_menu_entry($id, $title, $link_self)
{
global $blog_id;
$ret = '';
if ($link_self || $id != $blog_id) {
$ret .= '<li>';
if ($id == $blog_id) {
$ret .= '<strong>';
}
// și așa mai departe
$ret .= '</ul>';
return $ret;
}
Fă asta pentru ambele funcții și mă aștept să funcționeze. Îmi cer scuze dacă am înțeles greșit ceva.

Vreo idee? Unde este funcția care trebuie returnată în loc de afișată cu echo?
O să ofer o soluție alternativă care nu necesită să înlocuiești instanțele de echo sau să construiești un șir de returnat.
Poți activa bufferizarea output-ului și să returnezi buffer-ul ca șir de caractere.
Adaugă ob_start()
la începutul funcției înainte de orice apel echo.
la sfârșitul funcției adaugă:
$response = ob_get_contents();
ob_end_clean();
return $response;
