Come aggiungere "Fissa questo articolo in prima pagina" nel front end?

18 lug 2012, 02:49:26
Visualizzazioni: 1.87K
Voti: 6

Ho un sito web sul baseball con più autori. Uso la funzione "Fissa questo articolo in prima pagina" per contrassegnare una "Scelta della Redazione". Vorrei aggiungere un link/pulsante per permettere agli editori di farlo direttamente dal front end. Il metodo può essere implementato sia nell'articolo stesso che nella Admin Bar. Non ho particolari preferenze.

Ho cercato tra molti plugin diversi per la Admin Bar, ma non ho trovato nulla relativo alla funzione "Fissa questo articolo in prima pagina".

Grazie

0
Tutte le risposte alla domanda 3
7

Ci sono alcune funzioni che tornano utili in questo caso:

Con queste tre funzioni in mente, tutto ciò che dobbiamo fare è combinarle con un po' di codice per la barra di amministrazione.

Per prima cosa, incapsuliamo tutto in una classe per divertimento e profitto. Questa classe avrà alcune costanti che useremo in seguito: un nonce, un'azione per rimuovere il post dagli sticky e un'azione per aggiungerlo.

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

    /**
     * Azione Ajax per rimuovere dagli sticky
     *
     * @since   1.0
     */
    const UNSTICK = 'wpse58818_unstick';

    /**
     * Azione Ajax per aggiungere agli sticky
     *
     * @since   1.0
     */
    const STICK = 'wpse58818_stick';
} // fine della classe

Poi aggiungiamo una funzione init per aggiungere le nostre azioni. La prima azione è l'hook a template_redirect.

<?php
class WPSE_58818_Stick_Post
{
    // taglia taglia

    /**
     * Aggiunge azioni e simili.
     *
     * @since   1.0
     * @access  public
     * @uses    add_action
     */
    public static function init()
    {
        add_action(
            'template_redirect',
            array(__CLASS__, 'template_r')
        );
    }
}

NOTA: da qui in avanti ometterò la parte della class. Puoi vedere l'intero codice qui.

Nella funzione agganciata a template_redirect, controlleremo se siamo su una pagina di singolo post e se l'utente può modificarlo. Se può, agganceremo admin_bar_menu e wp_footer.

/**
 * Agganciato a `template_redirect`. Aggiunge il pulsante stick/unstick
 * alla barra di amministrazione se siamo su una pagina di singolo post
 * e l'utente corrente può modificare il post
 * 
 * @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; // non è un singolo post o l'utente non può modificarlo

    // Aggancia admin_bar_menu per aggiungere elementi
    add_action(
        'admin_bar_menu',
        array(__CLASS__, 'menu'),
        100
    );

    // Aggancia il footer e stampa un po' di JavaScript
    add_action(
        'wp_footer',
        array(__CLASS__, 'footer')
    );
}

Nella funzione menu, agganciata a admin_bar_menu, possiamo aggiungere il nostro nuovo elemento:

/**
 * Agganciato a `admin_bar_menu`. Aggiunge il nostro nodo stick/unstick.
 *
 * @since   1.0
 * @access  public
 */
public static function menu($mb)
{
    // ottieni l'ID del post corrente
    $post_id = get_queried_object_id();

    $mb->add_node(array(
        'id'    => 'wpse58818-sticker',
        'meta'  => array(
            'class' => 'wpse58818-sticker',
            'title' => is_sticky($post_id) ? 'rimuovi dagli sticky' : 'aggiungi agli sticky'
        ),
        'title' => is_sticky($post_id) ? __('Rimuovi dagli sticky') : __('Aggiungi agli sticky'),
        'href'  => self::get_url($post_id)
    ));
}

Qui abbiamo la nostra prima "funzione di utilità" che costruisce un URL per il nodo della barra di amministrazione. È semplicemente un wrapper attorno a add_query_arg per il nonce e per costruire un URL che useremo con AJAX più avanti:

/**
 * Ottiene un URL Ajax da usare per un determinato post
 *
 * @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'));
}

La funzione footer stampa semplicemente un po' di JavaScript per effettuare le chiamate AJAX. Panoramica di base: quando qualcuno clicca sul nostro nuovo link, effettua una richiesta GET all'URL specificato. Se ha successo, cambia l'href, il testo e il titolo del link (rimuovi/aggiungi agli sticky).

/**
 * Agganciato a `wp_footer`. Stampa un po' di JS per aggiungere/rimuovere un post dagli sticky
 *
 * @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(__('Si è verificato un errore')); ?>');
                        return;
                    }

                    $(that).attr('href', data);
                    if('aggiungi agli sticky' == action) {
                        $(that).html('<?php echo esc_js(__('Rimuovi dagli sticky')); ?>');
                        $(that).attr('title', 'rimuovi dagli sticky');
                    } else {
                        $(that).html('<?php echo esc_js(__('Aggiungi agli sticky')); ?>');
                        $(that).attr('title', 'aggiungi agli sticky');
                    }
                }
            );
        });
    });
    </script>
    <?php
}

E ora arriviamo alle callback AJAX. Ajax in plugin/temi è una lettura utile.

Modificheremo un po' la nostra funzione init per aggiungere altre due azioni:

/**
 * Aggiunge azioni e simili.
 *
 * @since   1.0
 * @access  public
 * @uses    add_action
 */
public static function init()
{
    add_action(
        'template_redirect',
        array(__CLASS__, 'template_r')
    );

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

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

E le nostre callback AJAX. Queste potrebbero facilmente essere la stessa funzione. Le ho separate qui perché sembrava più facile estenderle/cambiarle in futuro. Entrambe verificano se la richiesta AJAX è valida, aggiungono/rimuovono il post dagli sticky di conseguenza e stampano il nuovo URL per future aggiunte/rimozioni.

/**
 * Callback Ajax per la funzione stick
 *
 * @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 per la funzione unstick
 *
 * @since   1.0
 * @access  public
 * @uses    unstick_post
 */
public static function unstick()
{
    $post_id = self::can_ajax();

    // nonce verificati, tutto è pronto. Rimuovi dagli sticky!
    unstick_post($post_id);

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

Qui appare la nostra seconda "funzione di utilità". can_ajax verifica i nostri nonce e i permessi dell'utente e restituisce l'ID del post da aggiungere/rimuovere dagli sticky. Se qualche controllo fallisce, termina (tramite die('1')).

/**
 * Verifica se l'utente corrente può usare Ajax. Restituisce l'ID del post
 * da aggiungere/rimuovere dagli sticky se ha successo. Altrimenti termina il programma
 *
 * @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;
}

Ecco l'intero codice come plugin.

29 lug 2012 23:58:44
Commenti

+1 per il plugin funzionante, fa esattamente quello che è stato chiesto nella domanda.

Amit Kosti Amit Kosti
30 lug 2012 00:11:52

Ricevo questo errore quando carico il file del plugin .php tramite 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 lug 2012 00:45:24

Quindi caricalo via FTP e facci sapere? Probabilmente è perché il plugin non è nella sua cartella o qualcosa del genere.

chrisguitarguy chrisguitarguy
30 lug 2012 00:50:50

Ho aggiunto il file .php a una cartella, poi ho compresso la cartella in un file .zip. Ho caricato il plugin tramite WordPress. Tutto è stato caricato e installato correttamente. Il pulsante "Stick" è presente nella barra di amministrazione, ma quando viene cliccato, viene visualizzato un errore che dice semplicemente - "Si è verificato un errore". Sto utilizzando Google Chrome, non so se questo possa fare la differenza.

Travis Pflanz Travis Pflanz
30 lug 2012 01:03:17

Questo significa che qualcosa è andato storto nella chiamata ajax. Potrebbe essere un nonce non valido, un ID del post errato o problemi di permessi. A meno che non possa accedere al tuo sito per risolvere il problema (cosa che non farò), non posso aiutarti - sul mio computer locale funziona tutto correttamente. Passo 1: funziona con il tema predefinito? Altri plugin potrebbero causare problemi?

chrisguitarguy chrisguitarguy
30 lug 2012 01:13:51

Dalla mia parte, il plugin funziona correttamente nel fissare e rilasciare i post, ma la pagina non si aggiorna (WP 3.4.1, nessun plugin attivo, TwentyTen non modificato). Si blocca nella chiamata Ajax, screenshot: http://cl.ly/IOo8 . . . . . +1+ Ottimo lavoro, davvero professionale :)

brasofilo brasofilo
30 lug 2012 01:42:18

Ho appena digerito tutto e provato a modificare quasi tutte le funzioni ma non riesco a far avvenire il refresh... Ciononostante, ancora complimenti, sembra che quello che tu chiami intero casino sia spesso chiamato poesia, non è vero ¿!

brasofilo brasofilo
30 lug 2012 02:02:33
Mostra i restanti 2 commenti
3

Penso che questo piccolo codice sorgente sia la tua soluzione. Attualmente non ha un feedback frontend per il cambio di Sticky Post, ma puoi migliorare questa stringa, classe o qualsiasi altra cosa nella funzione fb_stick_post.

La prima funzione aggiunge la voce nella Admin Bar e crea un nuovo URL con un parametro. Inoltre, on click chiama una funzione per leggere il parametro dell'URL e, se è vero, esegue il cambio dello stato sticky per questo ID del post.

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 );
}

Aggiornamento 30/07/2012

Ora un piccolo plugin con una soluzione semplice. Il plugin aggiunge una voce all'interno della Admin Bar. La stringa del pulsante verifica se è sticky e offre la possibilità di fissare o rimuovere il post corrente.

Esempio nel tema Twenty Eleven per un post, con un flag sticky

Ho cambiato l'hook per aggiungere la voce della Admin Bar a template_redirect per utilizzare un reindirizzamento dopo l'aggiornamento del flag sticky sul post.

<?php
/**
 * Plugin Name: Fissa/Rimuovi post sticky 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 ) 
        ) {

            // verifica se è un post sticky
            if ( is_sticky( get_the_ID() ) ) {
                $title = __('Rimuovi sticky');
                $link = '?unstick_post=true';
                $attr_title = __( 'Rendi questo post non sticky' );
            } else {
                $title = __('Sticky');
                $link = '?stick_post=true';
                $attr_title = __( 'Rendi questo 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();
        }
    }

}

oppure scarica questo plugin Gist 3214922

29 lug 2012 23:20:40
Commenti

La piccola fonte (ed elegante) funziona subito senza bisogno di configurazioni, mi manca solo la funzione Unstick, ma del resto: non era stata richiesta!

brasofilo brasofilo
30 lug 2012 02:21:13

Sì, penso anche io; ma non era nella domanda. È possibile anche tramite parametro url e la funzione unstick( $post_id ). Manca anche un feedback visibile per cambiare lo stato sticky.

bueltge bueltge
30 lug 2012 09:47:41

Benvenuto! Ora anche un plugin disponibile per il download su Gist 3214922

bueltge bueltge
31 lug 2012 11:27:06
2

Ecco una soluzione molto più semplice che farà il lavoro utilizzando l'hook del filtro the_content

add_filter('the_content','soluzione_piu_semplice_per_sticky');
function soluzione_piu_semplice_per_sticky($content){
    global $post;
    //uscita anticipata se non necessario
    if (!is_single() || !current_user_can('edit_post',$post->ID)) 
        return $content;

    //controlla se il form è stato inviato e agisci di conseguenza
    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);
        }
    }

    //crea il form
    $label = (is_sticky())? "Rimuovi da sticky": "Rendi sticky";
    $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 lug 2012 23:24:19
Commenti

Sto ricevendo questo errore Parse error: syntax error, unexpected T_RETURN in /home1/travisp2/public_html/crowncrazed/wp-content/themes/qawker/functions.php alla riga 7 che corrisponde a return $content;

Travis Pflanz Travis Pflanz
30 lug 2012 23:59:24

Scusa, era un errore di battitura, ora è risolto

Bainternet Bainternet
31 lug 2012 01:14:04