Cómo agregar "Fijar esta entrada en la página principal" en el front end
Tengo un sitio web sobre béisbol con múltiples autores. Uso la opción "Fijar esta entrada en la página principal" para marcar artículos como "Elección del Editor". Me gustaría agregar un enlace/botón para permitir que los editores hagan esto desde el front end. El método puede estar en el artículo mismo o en la Barra de Administración. No tengo una preferencia específica.
He revisado muchos, muchos plugins diferentes para la "Barra de Administración", pero no he podido encontrar nada relacionado con "Fijar esta entrada en la página principal".
Gracias

Hay algunas funciones que resultan útiles aquí:
unstick_post
- Desfijar una entradastick_post
- Fijar una entradais_sticky
- Determinar si una entrada está fijada
Con esas tres en mente, todo lo que necesitamos hacer es unirlas con un poco de "pegamento" en la barra de menú de administración.
Primero, vamos a envolver todo en una clase por diversión y beneficio. Esta clase tendrá algunas constantes que usaremos más tarde: un nonce, una acción para desfijar la entrada y una acción para fijar la entrada.
class WPSE_58818_Stick_Post
{
/**
* Nonce para Ajax.
*
* @since 1.0
*/
const NONCE = 'wpse58818_nonce_';
/**
* Acción Ajax para desfijar
*
* @since 1.0
*/
const UNSTICK = 'wpse58818_unstick';
/**
* Acción Ajax para fijar
*
* @since 1.0
*/
const STICK = 'wpse58818_stick';
} // fin de la clase
Luego, agreguemos una función init para añadir nuestras acciones. La primera acción es engancharnos a template_redirect.
<?php
class WPSE_58818_Stick_Post
{
// recorte recorte
/**
* Añade acciones y demás.
*
* @since 1.0
* @access public
* @uses add_action
*/
public static function init()
{
add_action(
'template_redirect',
array(__CLASS__, 'template_r')
);
}
}
NOTA: a partir de aquí omitiré la parte de class
. Puedes ver todo completo aquí.
En la función enganchada a template_redirect
, verificaremos si estamos en una página de entrada única y si el usuario puede editarla. Si es así, nos engancharemos a admin_bar_menu
y wp_footer
.
/**
* Enganchado a `template_redirect`. Añade el botón de fijar/desfijar
* en la barra de administración si estamos en una página de entrada única
* y el usuario actual puede editar la entrada.
*
* @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; // no es una entrada única o el usuario no puede editarla
// Enganchar a admin_bar_menu para añadir elementos
add_action(
'admin_bar_menu',
array(__CLASS__, 'menu'),
100
);
// Enganchar al pie de página y mostrar algo de JavaScript
add_action(
'wp_footer',
array(__CLASS__, 'footer')
);
}
En la función menu
, enganchada a admin_bar_menu
, podemos añadir nuestro nuevo elemento:
/**
* Enganchado a `admin_bar_menu`. Añade nuestro nodo de fijar/desfijar.
*
* @since 1.0
* @access public
*/
public static function menu($mb)
{
// obtener el ID de la entrada actual
$post_id = get_queried_object_id();
$mb->add_node(array(
'id' => 'wpse58818-sticker',
'meta' => array(
'class' => 'wpse58818-sticker',
'title' => is_sticky($post_id) ? 'desfijar' : 'fijar'
),
'title' => is_sticky($post_id) ? __('Desfijar') : __('Fijar'),
'href' => self::get_url($post_id)
));
}
Aquí tenemos nuestra primera "función de utilidad" que construye una URL para el nodo de la barra de menú de administración. Es solo un envoltorio alrededor de add_query_arg
para el nonce y construir una URL que usaremos con AJAX más adelante:
/**
* Obtener una URL Ajax para usar con una entrada dada
*
* @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 función footer
simplemente muestra algo de JavaScript para hacer las llamadas AJAX. Resumen básico: cuando alguien hace clic en nuestro nuevo enlace, hacer una petición GET a la URL dada. Si es exitosa, cambiar el href, texto y título del enlace de (des)fijar.
/**
* Enganchado a `wp_footer`. Muestra un poco de JS para fijar/desfijar una entrada
*
* @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(__('Ocurrió un error')); ?>');
return;
}
$(that).attr('href', data);
if('fijar' == action) {
$(that).html('<?php echo esc_js(__('Desfijar')); ?>');
$(that).attr('title', 'desfijar');
} else {
$(that).html('<?php echo esc_js(__('Fijar')); ?>');
$(that).attr('title', 'fijar');
}
}
);
});
});
</script>
<?php
}
Y ahora llegamos a las devoluciones de llamada AJAX. Vale la pena leer sobre Ajax en plugins/temas.
Modificaremos un poco nuestra función init
para añadir dos acciones más:
/**
* Añade acciones y demás.
*
* @since 1.0
* @access public
* @uses add_action
*/
public static function init()
{
add_action(
'template_redirect',
array(__CLASS__, 'template_r')
);
// Acciones Ajax
add_action(
'wp_ajax_' . self::STICK,
array(__CLASS__, 'stick')
);
add_action(
'wp_ajax_' . self::UNSTICK,
array(__CLASS__, 'unstick')
);
}
Y nuestras devoluciones de llamada AJAX. Estas podrían ser fácilmente la misma función. Las separé aquí porque parecía más fácil extender/cambiar en el futuro. Ambas verifican si la petición AJAX es válida, (des)fijan la entrada según corresponda y muestran la nueva URL para futuras (des)fijaciones.
/**
* Devolución de llamada Ajax para la función de fijar
*
* @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();
}
/**
* Devolución de llamada Ajax para la función de desfijar
*
* @since 1.0
* @access public
* @uses unstick_post
*/
public static function unstick()
{
$post_id = self::can_ajax();
// nonces verificados, todo está listo. ¡Desfijar!
unstick_post($post_id);
echo self::get_url($post_id);
die();
}
Nuestra segunda "función de utilidad" aparece aquí. can_ajax
verifica nuestros nonces y permisos de usuario y devuelve el ID de la entrada a (des)fijar. Si alguna verificación falla, termina (mediante die('1')
).
/**
* Verifica si el usuario actual puede hacer Ajax. Devuelve el ID de la entrada
* para fijar/desfijar si es exitoso. Termina el programa de lo contrario.
*
* @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;
}
Aquí está todo ese desorden como un plugin.

+1 por el plugin funcional, hace exactamente lo que se pide en la pregunta.

Recibo este error al subir el archivo .php del plugin a través de WordPress. The package could not be installed. PCLZIP_ERR_BAD_FORMAT (-10) : Unable to find End of Central Dir Record signature

¿Entonces subirlo vía FTP y reportar? Probablemente sea porque el plugin no está en su propia carpeta o algo así.

Agregué el archivo .php a una carpeta, luego la carpeta a un .zip. Subí el plugin a través de WordPress. Todo se subió e instaló correctamente. El botón "Stick" aparece en la barra de administración, pero al hacer clic, muestra un error que simplemente dice - "Ocurrió un error". Estoy usando Google Chrome, no sé si eso influya.

Eso significa que algo salió mal en la llamada ajax. Puede ser un nonce defectuoso, ID de publicación o permisos. A menos que entre a tu sitio para solucionarlo (lo cual no voy a hacer), no puedo ayudarte - funciona bien en mi máquina local. Paso 1: ¿funciona con el tema por defecto? ¿Hay otros plugins que puedan estar causando problemas?

En mi caso, está fijando y desfijando correctamente, pero la página no se actualiza (WP 3.4.1, sin plugins activos, TwentyTen sin modificar). Se queda atascado en la llamada Ajax, captura: http://cl.ly/IOo8 . . . . . +1+ Excelente trabajo, muy profesional de verdad :)

Creo que este pequeño código fuente es tu solución. Actualmente no tiene retroalimentación en el frontend para el cambio de Sticky Post, pero puedes mejorar esta cadena, clase o lo que quieras en la función fb_stick_post
.
La primera función agrega el elemento en la Barra de Administración y crea una nueva URL con un valor de parámetro. Además, on click
llama a una función para leer el parámetro de la URL y, si es verdadero, entonces realiza el cambio al estado sticky de este ID de publicación.
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 );
}
Actualización 30/07/2012
Ahora un pequeño plugin con solución fácil. El plugin agrega un elemento dentro de la Barra de Administración. La cadena del botón verifica si es sticky y da la posibilidad de hacer o quitar el sticky a la publicación actual.
Cambié el hook para agregar el elemento de la barra de administración a `template_redirect` para usar un redireccionamiento después de actualizar el flag sticky en la publicación.
<?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 )
) {
// verifica si es un post 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();
}
}
}
o descarga este plugin Gist 3214922

La pequeña fuente (y elegante) funciona de inmediato, solo echo en falta la función Unstick, pero bueno: ¡no se pidió!

Sí, yo también lo creo; pero no estaba en la pregunta. También es posible mediante parámetro URL y la función unstick( $post_id )
. También echo en falta una retroalimentación visible para cambiar el estado de sticky.

¡Bienvenido! Ahora también un plugin para descargar en un Gist 3214922

Aquí hay una solución mucho más simple que hará el trabajo utilizando el gancho de filtro the_content
add_filter('the_content','simplest_sticky_solution');
function simplest_sticky_solution($content){
global $post;
//salida temprana si no es necesario
if (!is_single() || !current_user_can('edit_post',$post->ID))
return $content;
//verificar si el formulario fue enviado y actuar según sea necesario
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);
}
}
//crear el formulario
$label = (is_sticky())? "Desfijar": "Fijar";
$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;
}

Estoy recibiendo este error Parse error: syntax error, unexpected T_RETURN in /home1/travisp2/public_html/crowncrazed/wp-content/themes/qawker/functions.php on line 7
que es return $content;
