Shortcode afișează conținutul în partea de sus a the_content

19 nov. 2012, 00:05:59
Vizualizări: 2.62K
Voturi: 7

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');
1
Comentarii

posibil duplicat al Shortcode afișat întotdeauna în partea de sus a paginii

Michael Michael
19 nov. 2012 00:20:57
Toate răspunsurile la întrebare 4
1
10

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.

19 nov. 2012 00:16:00
Comentarii

Ah, ai dreptate; are logică. Bună soluție. Mulțumesc.

markratledge markratledge
19 nov. 2012 00:20:03
1

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.

19 nov. 2012 00:18:01
Comentarii

Mulțumesc, și ai dreptate. toscho te-a întrecut cu două minute.

markratledge markratledge
19 nov. 2012 00:20:43
1

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;
19 nov. 2012 00:23:22
Comentarii

Această metodă funcționează excelent; în sfârșit am reușit să o încerc. Mulțumesc.

markratledge markratledge
29 aug. 2013 07:18:20
0

Răspuns scurt și rapid:

Ar trebui să return rezultatul și nu să-l echo.

$output = 'primul';
$output .= 'al doilea'; //observă punctul (.=) după prima variabilă
$output .= 'al treilea';
return $output;
10 mar. 2019 16:39:36