Cum să adaugi opțiunea "Fixează acest articol pe prima pagină" în front-end?

18 iul. 2012, 02:49:26
Vizualizări: 1.87K
Voturi: 6

Am un site despre baseball cu multiple autori. Folosesc funcția "Fixează acest articol pe prima pagină" pentru a marca un articol ca "Alegerea Editorului". Aș dori să adaug un link/buton care să permită editorilor să facă acest lucru direct din front-end. Metoda poate fi fie în articolul în sine, fie în bara de administrare. Nu am o preferință anume.

Am căutat prin multe, multe plugin-uri pentru "Bara de administrare", dar nu am găsit nimic legat de "Fixează acest articol pe prima pagină".

Mulțumesc

0
Toate răspunsurile la întrebare 3
7

Sunt câteva funcții care ne sunt utile aici:

Cu aceste trei funcții în minte, tot ce trebuie să facem este să le combinăm cu un pic de "clei" din bara de meniu de administrare.

În primul rând, să încapsulăm totul într-o clasă pentru distracție și profit. Această clasă va avea câteva constante pe care le vom folosi mai târziu: un nonce, o acțiune pentru anularea fixării articolului și o acțiune pentru fixarea articolului.

class WPSE_58818_Stick_Post
{
    /**
     * Ajax nonce.
     *
     * @since   1.0
     */
    const NONCE = 'wpse58818_nonce_';

    /**
     * Acțiunea Ajax pentru anularea fixării
     *
     * @since   1.0
     */
    const UNSTICK = 'wpse58818_unstick';

    /**
     * Acțiunea Ajax pentru fixare
     *
     * @since   1.0
     */
    const STICK = 'wpse58818_stick';
} // sfârșitul clasei

Apoi să adăugăm o funcție de inițializare pentru a adăuga acțiunile noastre. Prima acțiune fiind să ne conectăm la template_redirect.

<?php
class WPSE_58818_Stick_Post
{
    // tăiat tăiat

    /**
     * Adaugă acțiuni și altele.
     *
     * @since   1.0
     * @access  public
     * @uses    add_action
     */
    public static function init()
    {
        add_action(
            'template_redirect',
            array(__CLASS__, 'template_r')
        );
    }
}

NOTĂ: de acum încolo voi omite partea cu class. Puteți vedea întregul cod aici.

În funcția conectată la template_redirect, vom verifica dacă suntem pe o pagină de articol unic și dacă utilizatorul poate să-l editeze. Dacă poate, ne vom conecta la admin_bar_menu și wp_footer.

/**
 * Conectat la `template_redirect`. Adaugă butonul de fixare/anulare fixării
 * în bara de administrare dacă suntem pe o pagină de articol unic și utilizatorul curent
 * poate edita articolul
 * 
 * @since   1.0
 * @access  public
 * @uses    add_action
 */
public static function template_r()
{
    if(
        !is_single() ||
        !current_user_can('edit_post', get_queried_object_id())
    ) return; // nu este un articol unic sau utilizatorul nu poate să-l editeze

    // Conectare la admin_bar_menu pentru a adăuga elemente
    add_action(
        'admin_bar_menu',
        array(__CLASS__, 'menu'),
        100
    );

    // Conectare la subsol și afișare de JavaScript
    add_action(
        'wp_footer',
        array(__CLASS__, 'footer')
    );
}

În funcția menu, conectată la admin_bar_menu, putem adăuga noul nostru element:

/**
 * Conectat la `admin_bar_menu`. Adaugă nodul nostru de fixare/anulare fixării.
 *
 * @since   1.0
 * @access  public
 */
public static function menu($mb)
{
    // obține ID-ul articolului curent
    $post_id = get_queried_object_id();

    $mb->add_node(array(
        'id'    => 'wpse58818-sticker',
        'meta'  => array(
            'class' => 'wpse58818-sticker',
            'title' => is_sticky($post_id) ? 'anulează fixarea' : 'fixează'
        ),
        'title' => is_sticky($post_id) ? __('Anulează fixarea') : __('Fixează'),
        'href'  => self::get_url($post_id)
    ));
}

Aici avem prima "funcție utilitară" care construiește un URL pentru nodul din bara de meniu de administrare. Este doar un wrapper în jurul add_query_arg pentru a adăuga nonce și a construi un URL pe care îl vom folosi cu AJAX mai târziu:

/**
 * Obține un URL Ajax pentru a folosi pentru un articol dat
 *
 * @since   1.0
 * @access  protected
 */
protected static function get_url($post_id)
{
    return add_query_arg(array(
        'post_id' => absint($post_id),
        'action'  => is_sticky($post_id) ? self::UNSTICK : self::STICK,
        'nonce'   => wp_create_nonce(self::NONCE . $post_id)
    ), admin_url('admin-ajax.php'));
}

Funcția footer doar afișează un pic de JavaScript pentru a face apelurile AJAX. Prezentare generală: când cineva dă clic pe noul nostru link, se face o cerere GET la URL-ul dat. Dacă este reușită, se schimbă href-ul, textul și titlul linkului de (anulare) fixare.

/**
 * Conectat la `wp_footer`. Afișează un pic de JS pentru a fixa/anula fixarea unui articol
 *
 * @since   1.0
 * @access  public
 */
public static function footer()
{
    ?>
    <script type="text/javascript">
    jQuery(document).ready(function($) {
        $('.wpse58818-sticker a').on('click', function(e) {
            e.preventDefault();
            var action = $(this).attr('title');
            var that = this;
            $.get(
                $(this).attr('href'),
                {},
                function(data) {
                    if('0' == data)
                    {
                        console.log(data);
                        alert('<?php echo esc_js(__('A apărut o eroare')); ?>');
                        return;
                    }

                    $(that).attr('href', data);
                    if('fixează' == action) {
                        $(that).html('<?php echo esc_js(__('Anulează fixarea')); ?>');
                        $(that).attr('title', 'anulează fixarea');
                    } else {
                        $(that).html('<?php echo esc_js(__('Fixează')); ?>');
                        $(that).attr('title', 'fixează');
                    }
                }
            );
        });
    });
    </script>
    <?php
}

Și acum ajungem la callback-urile AJAX. Ajax în plugin-uri/teme merită citit.

Vom modifica puțin funcția noastră init pentru a adăuga încă două acțiuni:

/**
 * Adaugă acțiuni și altele.
 *
 * @since   1.0
 * @access  public
 * @uses    add_action
 */
public static function init()
{
    add_action(
        'template_redirect',
        array(__CLASS__, 'template_r')
    );

    // Acțiuni Ajax
    add_action(
        'wp_ajax_' . self::STICK,
        array(__CLASS__, 'stick')
    );

    add_action(
        'wp_ajax_' . self::UNSTICK,
        array(__CLASS__, 'unstick')
    );
}

Și callback-urile noastre AJAX. Acestea ar putea fi foarte ușor aceeași funcție. Le-am separat aici pentru că părea mai ușor de extins/modificat în viitor. Ambele verifică dacă cererea AJAX este validă, (anulează) fixează articolul în consecință și afișează noul URL pentru viitoarele operații de (anulare) fixare.

/**
 * Callback Ajax pentru funcția de fixare
 *
 * @since   1.0
 * @access  public
 */
public static function stick()
{
    $post_id = self::can_ajax();

    stick_post($post_id);

    echo self::get_url($post_id);
    die();
}

/**
 * Callback Ajax pentru funcția de anulare fixării
 *
 * @since   1.0
 * @access  public
 * @uses    unstick_post
 */
public static function unstick()
{
    $post_id = self::can_ajax();

    // nonce-urile verificate, totul este în regulă. Anulează fixarea!
    unstick_post($post_id);

    echo self::get_url($post_id);
    die();
}

Aici apare a doua noastră "funcție utilitară". can_ajax verifică nonce-urile și permisiunile utilizatorului și returnează ID-ul articolului de (anulat) fixat. Dacă orice verificare eșuează, se termină (prin die('1')).

/**
 * Verifică dacă utilizatorul curent poate folosi Ajax. Returnează ID-ul articolului
 * de fixat/anulat fixarea dacă este reușit. În caz contrar, oprește programul
 *
 * @since   1.0
 * @access  protected
 */
protected static function can_ajax()
{
    $post_id = isset($_REQUEST['post_id']) ? $_REQUEST['post_id'] : '';

    if(
        !$post_id ||
        !check_ajax_referer(self::NONCE . $post_id, 'nonce', false)
    ) die('0');

    if(!current_user_can('edit_post', $post_id))
        die('0');

    return $post_id;
}

Iată întregul mizerie ca un plugin.

29 iul. 2012 23:58:44
Comentarii

+1 pentru plugin-ul funcțional, face exact ce se cere în întrebare.

Amit Kosti Amit Kosti
30 iul. 2012 00:11:52

Primesc această eroare la încărcarea fișierului .php al plugin-ului prin WordPress. The package could not be installed. PCLZIP_ERR_BAD_FORMAT (-10) : Unable to find End of Central Dir Record signature

Travis Pflanz Travis Pflanz
30 iul. 2012 00:45:24

Deci încarcă prin FTP și raportează înapoi? Probabil se întâmplă pentru că plugin-ul nu este în propriul său folder sau ceva de genul.

chrisguitarguy chrisguitarguy
30 iul. 2012 00:50:50

Am adăugat fișierul .php într-un folder, apoi folderul într-un arhiv .zip. Am încărcat plugin-ul prin WordPress. Totul s-a încărcat și instalat. Butonul "Stick" este prezent în bara de administrare, dar când este apăsat, apare o eroare care spune simplu - "A apărut o eroare". Folosesc Google Chrome, dacă asta face vreo diferență.

Travis Pflanz Travis Pflanz
30 iul. 2012 01:03:17

Asta înseamnă că ceva nu a funcționat în apelul ajax. Fie un nonce defect, ID-ul postării sau probleme de permisiuni. Fără să intru pe site-ul tău să-l repar (ceea ce nu am de gând să fac), nu te pot ajuta — la mine funcționează perfect pe mașina locală. Pasul 1: funcționează cu tema implicită? Alte plugin-uri cauzează probleme?

chrisguitarguy chrisguitarguy
30 iul. 2012 01:13:51

La mine, funcționează corect Stick și Unstick, dar pagina nu se reîmprospătează (WP 3.4.1, fără plugin-uri active, TwentyTen nemodificat). Se blochează în apelul Ajax, captură: http://cl.ly/IOo8 . . . . . +1+ Foarte bună treabă, lucrare profesională într-adevăr :)

brasofilo brasofilo
30 iul. 2012 01:42:18

Tocmai am asimilat totul și am încercat să modific aproape toate funcțiile, dar nu reușesc să fac refresh-ul să se întâmple... Cu toate acestea, felicitări din nou, se pare că ceea ce numești mizerie totală este adesea numit poezie, nu-i așa ¿!

brasofilo brasofilo
30 iul. 2012 02:02:33
Arată celelalte 2 comentarii
3

Cred că acest mic cod sursă este soluția ta. În prezent, nu are feedback în partea de frontend pentru schimbarea postării Sticky, dar poți îmbunătăți acest șir, clasă sau orice altceva dorești în funcția fb_stick_post.

Prima funcție adaugă elementul în bara de administrare și creează un URL nou cu o valoare de parametru. De asemenea, on click apelează o funcție pentru a citi parametrul URL și, dacă este adevărat, atunci face schimbarea în starea sticky pentru acest ID de postare.

add_action( 'admin_bar_menu', 'fb_add_admin_bar_sticky', 35 );
function fb_add_admin_bar_sticky() {
    global $wp_admin_bar;

    if ( ! is_super_admin() || ! is_admin_bar_showing() )
        return;

    $current_object = get_queried_object();
    if ( empty($current_object) )
        return;

    if ( ! empty( $current_object->post_type ) && 
        ( $post_type_object = get_post_type_object( $current_object->post_type ) ) && 
        current_user_can( $post_type_object->cap->edit_post, $current_object->ID ) 
    ) {
        $wp_admin_bar->add_menu( 
            array(
                'id' => 'sticky_post', 
                'title' => __('Sticky'), 
                'href' => get_permalink() . '?stick_post=true', 
                'meta' => array(
                    'title' => __( 'Click me' ),
                    'onclick' => fb_stick_post( get_the_ID() )
                )
            )
        );
    }
}

function fb_stick_post( $post_id ) {

    if ( isset($_GET['stick_post']) && 'true' == htmlspecialchars( $_GET['stick_post'] ) )
        stick_post( $post_id );
}

Actualizare 30.07.2012

Acum un mic plugin cu o soluție simplă. Plugin-ul adaugă un element în bara de administrare. Șirul butonului verifică dacă postarea este sticky și oferă posibilitatea de a face sau anula sticky postarea curentă.

Exemplu în tema Twenty Eleven pentru o postare, care are un marcaj sticky

Am schimbat hook-ul pentru a adăuga elementul în bara de administrare la ´template_redirect` pentru a folosi o redirecționare după actualizarea flagului sticky pe postare.

<?php
/**
 * Plugin Name: Stick/Unstick post via Admin bar
 * 
 */

if ( ! function_exists( 'fb_add_admin_bar_sticky' ) ) {

    add_action( 'template_redirect', 'fb_add_admin_bar_sticky' );
    function fb_add_admin_bar_sticky() {
        global $wp_admin_bar;

        if ( ! is_super_admin() || ! is_admin_bar_showing() )
            return;

        $current_object = get_queried_object();
        if ( empty($current_object) )
            return;

        if ( ! empty( $current_object->post_type ) && 
            ( $post_type_object = get_post_type_object( $current_object->post_type ) ) && 
            current_user_can( $post_type_object->cap->edit_post, $current_object->ID ) 
        ) {

            // verifică dacă postarea este sticky
            if ( is_sticky( get_the_ID() ) ) {
                $title = __('Unsticky');
                $link = '?unstick_post=true';
                $attr_title = __( 'Make this post unsticky' );
            } else {
                $title = __('Sticky');
                $link = '?stick_post=true';
                $attr_title = __( 'Make this post sticky' );
            }

            $wp_admin_bar->add_menu(
                array(
                    'id' => 'sticky_post', 
                    'title' => $title, 
                    'href' => get_permalink() . $link, 
                    'meta' => array(
                        'title' => $attr_title,
                        'onclick' => fb_stick_post( get_the_ID() )
                    )
                )
            );
        }
    }

    function fb_stick_post( $post_id ) {

        if ( isset($_GET['stick_post']) && 'true' == htmlspecialchars( $_GET['stick_post'] ) ) {
            stick_post( $post_id );
            wp_redirect( get_permalink( $post_id ) );
            exit();
        }

        if ( isset($_GET['unstick_post']) && 'true' == htmlspecialchars( $_GET['unstick_post'] ) ) {
            unstick_post( $post_id );
            wp_redirect( get_permalink( $post_id ) );
            exit();
        }
    }

}

sau descarcă acest plugin Gist 3214922

29 iul. 2012 23:20:40
Comentarii

Sursa mică (și elegantă) funcționează imediat, doar îmi lipsește funcția Unstick, dar în fine: nu a fost cerută!

brasofilo brasofilo
30 iul. 2012 02:21:13

Da, cred și eu; dar nu era în cerință. Este posibil și prin parametru URL și funcția unstick( $post_id ). De asemenea, îmi lipsește un feedback vizibil pentru schimbarea stării sticky.

bueltge bueltge
30 iul. 2012 09:47:41

Bine ai venit! Acum este disponibil și un plugin pentru descărcare pe Gist 3214922

bueltge bueltge
31 iul. 2012 11:27:06
2

Iată o soluție mult mai simplă care va face treaba folosind cârligul de filtrare the_content

add_filter('the_content','simplest_sticky_solution');
function simplest_sticky_solution($content){
    global $post;
    //ieșire rapidă dacă nu este necesar
    if (!is_single() || !current_user_can('edit_post',$post->ID)) 
        return $content;

    //verifică dacă formularul este trimis și acționează după caz
    if (isset($_POST['sticky_action']) && isset($_POST['sticky_id']) && isset($_POST['sticky_nonce']) && wp_verify_nonce($_POST['sticky_nonce'], 'StickIt')){
        if (is_sticky($post->ID)){
            stick_post($post->ID);
        }else{
            unstick_post($post->ID);
        }
    }

    //creează formularul
    $label = (is_sticky())? "Anulează fixare": "Fixează";
    $form = '
    <form action="" method="POST">
        <input type="hidden" name="sticky_id" value="'.$post->id.'">
        <input type="hidden" name="sticky_action" value="stickit">
        <input type="hidden" name="sticky_nonce" value="'.wp_create_nonce('StickIt').'">
        <input type="button" name="submit" value="'.$label.'">
    </form>';
    return $form.'<br/>'.$content;
}
30 iul. 2012 23:24:19
Comentarii

Primesc această eroare Parse error: syntax error, unexpected T_RETURN in /home1/travisp2/public_html/crowncrazed/wp-content/themes/qawker/functions.php on line 7 care este return $content;

Travis Pflanz Travis Pflanz
30 iul. 2012 23:59:24

Scuze, a fost o greșeală de scriere, e rezolvat acum

Bainternet Bainternet
31 iul. 2012 01:14:04