La mejor colección de código para tu archivo 'functions.php'

9 sept 2010, 11:29:00
Vistas: 169K
Votos: 346

Al igual que muchos otros que ahora están viendo esta publicación, he estado leyendo varios blogs, foros y grupos de discusión para aprender y mejorar mis habilidades en WordPress. Durante los últimos 12 meses, me he propuesto sustituir el uso de plugins añadiendo código a mi archivo functions.php.

Si bien estoy completamente de acuerdo en que los plugins son muy útiles en muchas situaciones, mi experiencia demostró que en el 90% de los casos, aunque existe un plugin, utilizarlo podría crear complicaciones innecesarias y problemas de compatibilidad. Además, en muchos casos, estos plugins añadían menús y otros elementos administrativos que no quiero ni necesito.

En la mayoría de los casos, he descubierto que al analizar el código de los plugins, pude extraer el fragmento de código que quería e implementarlo directamente en mi functions.php. Esto me proporcionó exactamente la funcionalidad que necesitaba sin tener que incluir elementos innecesarios.

Así que el propósito de esta publicación es mi intento de involucrarte a ti, el lector/administrador/desarrollador, a compartir conmigo y con otros aquí cualquier fragmento de código que encuentres útil y hayas añadido al archivo functions.php de tu tema para extender o mejorar WordPress sin utilizar un plugin.

Cuando envíes una respuesta aquí, por favor, dale un título a cada fragmento de código, háznoslo saber con qué versión de WordPress sabes que es compatible, incluye cualquier descripción que consideres que mejor describe su función y (si corresponde) incluye un enlace al plugin original o la fuente donde encontraste la información.

Espero con interés todas vuestras respuestas y, por supuesto, continuaré añadiendo mis propios descubrimientos cuando los encuentre.

Por favor, vota la pregunta y cualquier respuesta que encuentres útil haciendo clic en la flecha hacia arriba en el lado izquierdo de la pregunta o respuesta.

25
Comentarios

Por favor, añade también tus hallazgos antiguos y existentes.

hakre hakre
9 sept 2010 11:38:16

Hola @NetConstructor: Me preocupa esta pregunta porque es una pregunta de "Lista de X" sobre la que la gente de StackExchange nos ha advertido: http://meta.stackexchange.com/questions/57226/should-we-have-a-list-of-x-close-reason Mi mayor preocupación es que cuando pienso en tu pregunta, puedo imaginar un número casi infinito de respuestas y, como tal, me preocupa que esta pregunta resulte en una colección de respuestas aleatorias pero nada definitivo. Quiero obtener las opiniones de otros antes de (votar para) cerrarla, ya que no quiero ser demasiado estricto, solo tengo dudas.

MikeSchinkel MikeSchinkel
9 sept 2010 14:00:40

Mi voto es cerrarla o convertirla en wiki comunitaria

Chris_O Chris_O
9 sept 2010 15:37:41

Considerando que las primeras 5 respuestas fueron del autor de la pregunta y que la pregunta parece estar más orientada a recopilar un conjunto de respuestas en lugar de una única respuesta definitiva, esto debería ser un wiki comunitario.

EAMann EAMann
9 sept 2010 17:43:16

Parece que no se puede simplemente modificar una pregunta para convertirla en wiki. ¿Es esto correcto?

NetConstructor.com NetConstructor.com
9 sept 2010 18:31:53

Sin embargo, esto es útil (he encontrado 2 fragmentos de código que usaré mucho). Si va a ser un wiki comunitario y hay que empezar desde cero para hacerlo, ¿quizás podríamos simplemente trasladar el contenido de aquí allí?

Lemon Bacon Lemon Bacon
10 sept 2010 02:58:46

@NetConstructor.com ... Convertí la pregunta en un wiki cuando escribí mi último comentario. Perdón si eso causó alguna confusión. Normalmente, tú (como el autor original) puedes convertir una pregunta en wiki en cualquier momento.

EAMann EAMann
10 sept 2010 03:56:15

@EAMann gracias... Estaba buscando esa opción pero no estaba seguro de dónde estaba ubicada. ¿Tal vez después de que la convertiste ya no pude ver la opción?

NetConstructor.com NetConstructor.com
10 sept 2010 08:37:41

@NetConstructor.com - Exacto. Una vez que se convierte, ya está convertida... la opción se establece y desaparece de la página.

EAMann EAMann
10 sept 2010 17:23:26

Considero que esto es un mal estilo y prefiero los plugins. a) Están construidos por desarrolladores dedicados b) se mantienen y actualizan fácilmente. Para pequeños fragmentos de código personalizados, recomiendo el plugin Shortcode Exec PHP que ofrece una forma muy limpia y portable de personalizar tu Wordpress.

Raphael Raphael
10 nov 2010 11:43:21

Aunque interesante, creo que la mayoría estaría de acuerdo en que cuando desarrollas temas, prefieres tener las cosas localizadas dentro de un archivo functions.php

NetConstructor.com NetConstructor.com
24 nov 2010 19:01:50

@NetConstructor - Si vas a editar las entradas de otros, por favor ten cuidado al hacerlo, arruinaste la indentación en mi publicación. Siempre me esfuerzo por mantener la indentación para mejor legibilidad. También agradecería que te tomaras el tiempo de explicar las ediciones que haces (no pude ver ninguna razón para que editaras mi entrada - y no hubo un resumen de la edición).

t31os t31os
28 ene 2011 18:53:26

@t31os -- Lo edité para mantenerlo consistente con todas las entradas

NetConstructor.com NetConstructor.com
7 feb 2011 15:53:20

Todas las respuestas no relacionadas con un tema deberían ser eliminadas. Este hilo es un buen ejemplo de malas prácticas de codificación.

fuxia fuxia
13 jun 2011 15:09:56

Tendría que discrepar. La pregunta no estaba relacionada con el tema. Todas las modificaciones de functions.PHP aplicables son bienvenidas y los usuarios deberían votar arriba/abajo en consecuencia.

NetConstructor.com NetConstructor.com
14 jun 2011 07:56:23

Es interesante que no se mencione en ningún lugar que el archivo functions.php es el que está en el directorio de tu tema, lo que lleva a confusión, como esta: http://wordpress.stackexchange.com/questions/25341/error-after-editing-functions-php

scribu scribu
9 ago 2011 03:07:10

Creo que sería mejor animar a la gente a crear un plugin de funcionalidad personalizado en lugar de usar el functions.php de su tema

Ian Dunn Ian Dunn
16 ene 2012 20:49:10

@rarst - Con respecto a tu comentario sobre cerrar este hilo, ¿no es esta la razón por la que está listado en la wiki de la comunidad?

User User
19 feb 2012 15:35:19

@Cor van Noorloos el uso del estatus de wiki comunitaria se ha reducido considerablemente y es desalentado por la red. En pocas palabras, la excusa de "no es realmente adecuado para preguntas y respuestas, pero es una wiki comunitaria" ya no es válida. Las respuestas aquí se convirtieron en un desorden mal mantenido, solo visitado por el factor diversión/curiosidad. Ha habido mucho movimiento en toda la red para eliminar preguntas como esta.

Rarst Rarst
19 feb 2012 15:43:03

@rarst - Entendible. Punto tomado.

User User
19 feb 2012 15:55:04

En relación al cierre de esta "wiki" específica, voto porque se reabra. Obviamente esta publicación wiki es muy popular, como lo demuestra el hecho de que tiene 30,000 visitas, que es tres veces más que CUALQUIER otra pregunta o wiki en este sitio, y el tema en sí ha recibido 119 votos positivos, el doble que cualquier otra pregunta o tema. Si estás de acuerdo con su valor, por favor vota para reabrirlo haciendo clic en el enlace "reopen".

NetConstructor.com NetConstructor.com
20 feb 2012 13:12:40

@NetConstructor.com El número puro de visitas a la página no es un indicador de calidad. Deberíamos fomentar preguntas específicas con respuestas específicas y buenas prácticas de codificación. Este hilo es lo opuesto.

fuxia fuxia
22 feb 2012 04:44:30

@toscho - Esa es precisamente la razón por la que esto se configuró como un wiki y, por lo tanto, esta publicación es perfectamente válida. El punto que mencioné respecto a las visitas se mencionó porque este tema obviamente es 3 veces más popular que cualquier otro en este sitio. Este sitio web es popular específicamente debido a preguntas como estas y, por lo tanto, no tiene sentido cerrarlo. No creo que se pueda debatir esto a menos que el interés de la comunidad en temas como estos no tenga valor para los administradores.

NetConstructor.com NetConstructor.com
24 feb 2012 18:38:34

Agregaré un comentario más aquí basado en unos cálculos que acabo de hacer. Hay menos de 790 usuarios registrados en este sitio web con una calificación de "1" o más. Asumiendo que este grupo de individuos representa a aquellos que realmente votan y/o contribuyen en este sitio (y siendo 790 increíblemente justo), entonces 117 personas que votaron positivamente esta pregunta representan más del 14% de todos los usuarios activos que encontraron este tema útil. Voten para reabrir el tema, por favor.

NetConstructor.com NetConstructor.com
24 feb 2012 18:47:01

@NetConstructor.com Discútelo en Meta donde la gente podrá ver mejor tus argumentos. :)

fuxia fuxia
24 feb 2012 19:10:14
Mostrar los 20 comentarios restantes
Todas las respuestas a la pregunta 30
2
15

Incluir tipos de contenido personalizados en el panel de administración "Ahora mismo"

Esto incluirá tus tipos de contenido personalizados y el recuento de publicaciones para cada tipo en el widget del panel "Ahora mismo".

// AÑADIR TIPOS DE CONTENIDO PERSONALIZADOS AL WIDGET 'AHORA MISMO' DEL PANEL
function wph_right_now_content_table_end() {
 $args = array(
  'public' => true ,
  'show_ui' => true ,
  '_builtin' => false
 );
 $output = 'object';
 $operator = 'and';
 
 $post_types = get_post_types( $args , $output , $operator );
 foreach( $post_types as $post_type ) {
  $num_posts = wp_count_posts( $post_type->name );
  $num = number_format_i18n( $num_posts->publish );
  $text = _n( $post_type->labels->singular_name, $post_type->labels->name , intval( $num_posts->publish ) );
  if ( current_user_can( 'edit_posts' ) ) {
   $num = "<a href='edit.php?post_type=$post_type->name'>$num</a>";
   $text = "<a href='edit.php?post_type=$post_type->name'>$text</a>";
  }
  echo '<tr><td class="first b b-' . $post_type->name . '">' . $num . '</td>';
  echo '<td class="t ' . $post_type->name . '">' . $text . '</td></tr>';
 }
 $taxonomies = get_taxonomies( $args , $output , $operator ); 
 foreach( $taxonomies as $taxonomy ) {
  $num_terms  = wp_count_terms( $taxonomy->name );
  $num = number_format_i18n( $num_terms );
  $text = _n( $taxonomy->labels->singular_name, $taxonomy->labels->name , intval( $num_terms ));
  if ( current_user_can( 'manage_categories' ) ) {
   $num = "<a href='edit-tags.php?taxonomy=$taxonomy->name'>$num</a>";
   $text = "<a href='edit-tags.php?taxonomy=$taxonomy->name'>$text</a>";
  }
  echo '<tr><td class="first b b-' . $taxonomy->name . '">' . $num . '</td>';
  echo '<td class="t ' . $taxonomy->name . '">' . $text . '</td></tr>';
 }
}
add_action( 'right_now_content_table_end' , 'wph_right_now_content_table_end' );
26 ene 2011 16:19:21
Comentarios

¡De repente, apareció un tipo de publicación "WooFramework Internal Container" en el widget RightNow! . . . se necesita un argumento adicional 'show_ui' => true y ahora está todo bien

brasofilo brasofilo
4 abr 2012 03:37:39

Esto es exactamente lo mismo que había publicado anteriormente.

jaredwilli jaredwilli
9 dic 2012 19:52:30
4
14

Añadir un formulario de búsqueda del codex al encabezado del panel

Esta es una forma sencilla de añadir un formulario de búsqueda del codex al encabezado del panel, en la parte superior derecha junto al menú desplegable de enlaces rápidos.

/**
 * AÑADIR FORMULARIO DE BÚSQUEDA DEL CODEX DE WP AL ENCABEZADO DEL PANEL
 */
function wp_codex_search_form() {
    echo '<form target="_blank" method="get" action="http://wordpress.org/search/do-search.php" class="alignright" style="margin: 11px 5px 0;">
        <input type="text" onblur="this.value=(this.value==\'\') ? \'Buscar en el Codex\' : this.value;" onfocus="this.value=(this.value==\'Buscar en el Codex\') ? \'\' : this.value;" maxlength="150" value="Buscar en el Codex" name="search" class="text"> <input type="submit" value="Ir" class="button" />
    </form>';
}

if( current_user_can( 'manage_plugins' )) {
// ¡El número 11 necesita ser un 10 para que esto funcione!
    add_filter( 'in_admin_header', 'wp_codex_search_form', 11 );
}
9 nov 2010 05:22:03
Comentarios

¿puedes actualizar este código para mostrar que esto solo se muestra a usuarios con un rol específico (específicamente administradores)?

NetConstructor.com NetConstructor.com
22 feb 2011 22:19:14

@NetConstructor.com Lo edité para mostrar si current_user_can puede gestionar plugins, entonces añade el filtro. Es así de simple.

jaredwilli jaredwilli
23 feb 2011 02:56:13

¿Esto sigue funcionando en la versión actual de WP... no pude hacer que funcione?

Zach Lysobey Zach Lysobey
15 feb 2012 19:06:32

Envolví el add_filter en esta llamada de acción: add_action('plugins_loaded', 'pluginInit');, y luego function pluginInit(){if...add_filter(...)} - lo estoy ejecutando en WP 3.4-alpha, y tuve que usar in_admin_footer

brasofilo brasofilo
2 abr 2012 14:28:28
0
14

Nueva columna en la Biblioteca Multimedia para reasignar imágenes

Este código añade una nueva columna a la página de la Biblioteca Multimedia que permite reasignar imágenes

add_filter("manage_upload_columns", 'upload_columns');
add_action("manage_media_custom_column", 'media_custom_columns', 0, 2);

function upload_columns($columns) {
    unset($columns['parent']);
    $columns['better_parent'] = "Padre";
    return $columns;
}
function media_custom_columns($column_name, $id) {
    $post = get_post($id);
    if($column_name != 'better_parent')
        return;
        if ( $post->post_parent > 0 ) {
            if ( get_post($post->post_parent) ) {
                $title =_draft_or_post_title($post->post_parent);
            }
            ?>
            <strong><a href="<?php echo get_edit_post_link( $post->post_parent ); ?>"><?php echo $title ?></a></strong>, <?php echo get_the_time(__('Y/m/d')); ?>
            <br />
            <a class="hide-if-no-js" onclick="findPosts.open('media[]','<?php echo $post->ID ?>');return false;" href="#the-list"><?php _e('Reasignar'); ?></a>
            <?php
        } else {
            ?>
            <?php _e('(Sin asignar)'); ?><br />
            <a class="hide-if-no-js" onclick="findPosts.open('media[]','<?php echo $post->ID ?>');return false;" href="#the-list"><?php _e('Asignar'); ?></a>
            <?php
        }
}
14 nov 2010 17:57:56
1
13

Bucle personalizado con temas usando shortcodes

Los argumentos son los mismos que los de query_posts. El contenido envuelto entre la etiqueta de consulta es la plantilla.

add_shortcode('query', 'shortcode_query');

function shortcode_query($atts, $content){
  extract(shortcode_atts(array( // algunos valores por defecto
   'posts_per_page' => '10',
   'caller_get_posts' => 1,
   'post__not_in' => get_option('sticky_posts'),
  ), $atts));

  global $post;

  $posts = new WP_Query($atts);
  $output = '';
  if ($posts->have_posts())
    while ($posts->have_posts()):
      $posts->the_post();

      // estos argumentos estarán disponibles desde dentro de $content
      $parameters = array(
        'PERMALINK' => get_permalink(),
        'TITLE' => get_the_title(),
        'CONTENT' => get_the_content(),
        'COMMENT_COUNT' => $post->comment_count,
        'CATEGORIES' => get_the_category_list(', '),
        // añade aquí más...
      );

      $finds = $replaces = array();
      foreach($parameters as $find => $replace):
        $finds[] = '{'.$find.'}';
        $replaces[] = $replace;
      endforeach;
      $output .= str_replace($finds, $replaces, $content);

    endwhile;
  else
    return; // no se encontraron posts

  wp_reset_query();
  return html_entity_decode($output);
}

Uso:

[query post_type=page posts_per_page=5]
Listando algunas páginas:    
<h5>{TITLE}</h5>
<div>{CONTENT}</div>
<p><a href="{PERMALINK}">{COMMENT_COUNT} comentarios</a></p>
[/query]

(realizará una consulta para 5 páginas)


Insertar widgets preconfigurados en cualquier lugar usando shortcodes

(algunas ideas de http://webdesign.anmari.com/shortcode-any-widget)

add_action('widgets_init', 'create_arbitrary_sidebar');
function create_arbitrary_sidebar(){
  register_sidebar(array(
    'name' => __('Widgets Arbitrarios'),
    'id' => 'arbitrary',
    'description' => sprintf(__('Los widgets de esta área pueden añadirse a entradas/páginas usando los shortcodes %1$s o %2$s.'), '[widget ID]', '[widget Name]'),
    'before_widget' => '<div class="block"><div class="block-content block-%2$s clear-block" id="instance-%1$s">',
    'after_widget' => '</div></div>',
    'before_title' => '<h3 class="title">',
    'after_title' => '</h3>'
   ));
}

add_action('in_widget_form', 'widget_shortcodes_info', 10, 3);
function widget_shortcodes_info($widget, $return, $instance){
  if(!is_numeric($widget->number)) return; // bug de wp-save :( el widget necesita guardarse primero...

  global $wp_registered_widgets;

  // obtener los widgets activos de todas las barras laterales
  $sidebars_widgets = wp_get_sidebars_widgets();

  // preparar coincidencias
  $matches = array();
  foreach($wp_registered_widgets as $i => $w)
    if($w['name'] == $widget->name) $matches[] = $w['id'];

  // averiguar la posición del widget (número)
  $number = 0;
  $is_arbitrary = false;
  if(!empty($sidebars_widgets['arbitrary']))
    foreach($sidebars_widgets['arbitrary'] as $i => $value):
      if(in_array($value, $matches) && !$is_arbitrary) $number = $number +1;
      if($value == $widget->id) $is_arbitrary = true;
    endforeach;

  echo '<div style="background:#eee; padding: 5px;">Para incluir este widget en tus entradas o páginas usa uno de los siguientes shortcodes: <br />';
  echo '<code>[widget '.substr(md5($widget->id), 0, 8).']</code> <br /> <code>[widget "'.$widget->name.'"'.(($number > 1) ? ' number='.$number : null).']</code></div>';
}

add_shortcode('widget', 'shortcode_widget');
function shortcode_widget($atts){
  global $wp_registered_widgets, $wp_registered_sidebars;
  extract(shortcode_atts(array(
    'number' => false,        // solo se tiene en cuenta si el 1er argumento es el "Nombre del Widget" (no el ID hasheado)
    'title' => true,          // mostrar títulos?
    'area' => 'arbitrary'     // barra lateral para buscar
  ), $atts));

  // obtener el 1er parámetro (asumiendo que es el ID o nombre del widget objetivo)
  if (!empty($atts[0])) $widget = esc_attr($atts[0]); else return;

  $sidebar = esc_attr($area);
  $number = intval($number);

  $callback = false;
  $possible_matches = array();
  $sidebars_widgets = wp_get_sidebars_widgets();
  if((empty($sidebars_widgets[$sidebar]) || empty($wp_registered_widgets)) && (current_user_can('edit_themes')))
    return "no hay widgets activos válidos en {$sidebar}";

  // asumiendo que obtenemos el ID hasheado con md5
  foreach ($wp_registered_widgets as $i => $w)
    if ($widget == substr(md5($w['id']), 0, 8)):
      $callback = ($w['callback']);
      $widget = $w['id']; // ID real del widget

    // comparar nombres de widgets también, y construir un array con las posibles coincidencias de widgets
    // (que se usa más tarde si falla la coincidencia de ID)
    elseif($widget == $w['name']):
      $possible_matches[] = $w['id'];

    endif;

  // no se encontró nada, asumir que es el "Nombre del Widget".
  if(!$callback):
    $valid_matches = array();
    foreach($sidebars_widgets[$sidebar] as $i => $w)
      foreach($possible_matches as $id) if($id == $w) $valid_matches[] = $w;

    if(!empty($valid_matches)) $widget = $number ? $valid_matches[$number-1] : $widget = $valid_matches[0];
    if($widget && isset($wp_registered_widgets[$widget]['callback'])) $callback = $wp_registered_widgets[$widget]['callback'];
  endif;

  // ¡bien! lo encontramos
  if($callback):
    ob_start();

    $params = array_merge(array(array_merge($wp_registered_sidebars[$sidebar], array('widget_id' => $widget, 'widget_name' => $wp_registered_widgets[$widget]['name']))), (array)$wp_registered_widgets[$widget]['params']);

    $classname_ = '';
    foreach ((array)$wp_registered_widgets[$widget]['classname'] as $cn)
      if (is_string($cn)) $classname_ .= '_'.$cn; elseif (is_object($cn)) $classname_ .= '_'.get_class($cn);
    $classname_ = ltrim($classname_, '_');
    $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $widget, $classname_);
    $params = apply_filters('dynamic_sidebar_params', $params);

    if (is_callable($callback)) call_user_func_array($callback, $params);
    $output = ob_get_clean();

    // eliminar h3 si title = false
    if(!$title) $output = preg_replace('#<h3 class="title">(.*?)</h3>#', '', $output);
    return $output;
  else:
   return "no se encontró la instancia del widget: ".esc_attr($atts[0]);
  endif;
}

Uso:

Coloca un widget en la barra lateral "widgets arbitrarios", guárdalo y obtendrás los shortcodes :)


Obtener el valor de un campo personalizado a través de shortcodes

add_shortcode('field', 'shortcode_field');

function shortcode_field($atts){
  extract(shortcode_atts(array(
   'post_id' => NULL,
  ), $atts));

  if(!isset($atts[0])) return;
  $field = esc_attr($atts[0]);

  global $post;
  $post_id = (NULL === $post_id) ? $post->ID : $post_id;

  return get_post_meta($post_id, $field, true);
}

Uso:

  • [field "mi_clave"]
  • [field "mi_clave" post_id=1]

Obtener el TinyURL de un enlace a través de shortcodes

add_shortcode('tinyurl', 'shortcode_tinyurl'); 

function shortcode_tinyurl($atts){
  extract(shortcode_atts(array(
   'url' => get_permalink(),
   'title' => '',
   'rel' => 'nofollow'
  ), $atts));
  if(!$title) $title = $url;

  if (FALSE === ($cache = get_transient('tinyurl_'+md5($url))):
    $cache = wp_remote_retrieve_body(wp_remote_get('http://tinyurl.com/api-create.php?url='.$url));

    set_transient('tinyurl_'+md5($url), $cache, 60*60*24); // caché de 1 día, podría aumentarse
  endif;

  return '<a href="'.esc_url($cache).'" rel="'.esc_attr($rel).'">'.esc_attr($title).'</a>';
}

Uso:

  • [tinyurl]
  • [tinyurl url="http://google.com" title="google"]
21 dic 2010 22:03:19
Comentarios

Sería mejor que uses Javascript: <a href="javascript:window.open('http://tinyurl.com/api-create.php?url='+location.href"> Obtener enlace corto </a> (para evitar CIENTOS de consultas de apertura de página innecesarias (por bots u otros) a TinyUrl...

T.Todua T.Todua
23 ene 2015 12:22:10
1
12

Establecer el Editor Predeterminado como WYSIWYG o HTML

function my_default_editor() {
    $r = 'tinymce'; // html o tinymce
    return $r;
}
add_filter( 'wp_default_editor', 'my_default_editor' );

Aquí está cómo eliminar el Editor HTML

jQuery(document).ready(function($) {
$("#edButtonHTML").remove();
});

ACTUALIZADO aquí hay otra forma de establecer el editor predeterminado como HTML

add_filter('wp_default_editor', create_function('', 'return "html";'));
16 nov 2010 06:56:16
Comentarios

ver más información en el origen: http://wpengineer.com/1946/disable-html-editor-wordpress/

bueltge bueltge
17 nov 2010 14:44:36
11
11

Eliminar el Metabox de Autor/Opciones y Moverlo al Metabox de Publicación

Probado en: WordPress 3.0.1

Una de las cosas que me vuelve loco es un área de administración de WordPress desordenada. Uno de los elementos que ahora siempre configuro desde el principio en mi archivo functions.php es eliminar el Metabox de Autor y las Opciones de Pantalla, y luego agregar la opción dentro del metabox de publicación. En mi opinión, esto tiene sentido y mantiene las cosas limpias. Esto también respeta los permisos aplicables.

Para lograr este objetivo, simplemente copia y pega el siguiente código en tu archivo functions.php.

Si crees que hay una mejor manera de hacer esto, por favor sugiérela.

NOTA: ACTUALIZADO EL CÓDIGO PARA CORREGIR UN PROBLEMA DE CODIFICACIÓN

// MOVER EL METABOX DE AUTOR DENTRO DEL METABOX DE PUBLICACIÓN
add_action( 'admin_menu', 'remove_author_metabox' );
add_action( 'post_submitbox_misc_actions', 'move_author_to_publish_metabox' );
function remove_author_metabox() {
    remove_meta_box( 'authordiv', 'post', 'normal' );
}
function move_author_to_publish_metabox() {
    global $post_ID;
    $post = get_post( $post_ID );
    echo '<div id="author" class="misc-pub-section" style="border-top-style:solid; border-top-width:1px; border-top-color:#EEEEEE; border-bottom-width:0px;">Autor: ';
    post_author_meta_box( $post );
    echo '</div>';
}
30 sept 2010 06:06:41
Comentarios

No agrega el Metabox de Autor a mi Caja de Publicación. Supuse que era porque no había un add_action para la función move_author_to_publish_box, así que agregué add_action('admin_menu', 'move_author_to_publish_box'); pero eso me dio un "Error fatal: Llamada a función indefinida post_author_meta_box()"

matt matt
5 dic 2010 07:02:43

¿Qué versión de WordPress estás usando?

NetConstructor.com NetConstructor.com
6 dic 2010 19:21:32

¿Y cómo agregarías el autor a la publicación? En admin_init o en admin_menu no funcionaría.

kaiser kaiser
1 feb 2011 09:42:15

@kaiser -- No estoy seguro de entender tu pregunta. Este código simplemente elimina el metabox "author" y coloca la opción para seleccionar el autor dentro del metabox "publish".

NetConstructor.com NetConstructor.com
1 feb 2011 17:07:08

@NetConstructor: Lo probé ayer (3.0.4) y sí, el cuadro de autor desapareció, pero no se movió al cuadro de publicación. Al revisar el código no veo ninguna forma, porque la función no se activa en ningún lado... solo agregaste la función remove_author_box() al hook admin_menu, pero no la función move_author_to_publish_box().

kaiser kaiser
1 feb 2011 20:55:29

@kaiser -- tienes razón, después de revisar esto me di cuenta del problema. Actualicé el código en mi respuesta, así que simplemente elimina todo lo que incluiste de esto antes y pega el código completo de arriba. Avísame si esto soluciona las cosas. Vota positivo la pregunta y la respuesta si resuelve el problema - CH :)

NetConstructor.com NetConstructor.com
2 feb 2011 00:29:12

@CH/NC: Claro que funciona, ni siquiera hay que probarlo. Voto a favor: n/p. Podría/Debería extenderse para incluir también algo de la otra basura/desorden... (discusiones, miniatura de entrada). No voy a modificar tu respuesta, pero si tienes algo de tiempo, incluso valdría la pena un artículo en el blog. :)

kaiser kaiser
2 feb 2011 01:50:33

@kaiser -- no estoy exactamente seguro de dónde ves el valor en esto? Mi objetivo era solo eliminar algunos de los metaboxes que eran extras e innecesarios como los slugs y autores.

NetConstructor.com NetConstructor.com
2 feb 2011 07:11:09

@tú: No, yo absolutamente veo el beneficio. No solo me malinterpretaste, me entendiste al revés por 180 grados. Dije que es tan bueno que a) debería extenderse a discusiones y miniaturas y b) merece un artículo en el blog sobre "limpiando las páginas de edición de contenido" o algo así. Edición: Con "no hay necesidad de probarlo" quiero decir que sé que funciona.

kaiser kaiser
2 feb 2011 08:53:13

@kaiser -- agradezco el cumplido, pero lo que todavía no entiendo es cómo ves que sería beneficioso para los usuarios tener discusiones o miniaturas integradas en el metabox de publicación. Solo veía el beneficio de eliminar los metaboxes de slug y autor, ya que esos lógicamente deberían estar dentro del metabox de publicación. ¿Sigo malinterpretando tu punto?

NetConstructor.com NetConstructor.com
3 feb 2011 18:05:34

@NC: No, me entendiste bien. Para mí no es "el cuadro de publicación", sino simplemente un cuadro en la parte superior derecha para cosas pequeñas. No veo la necesidad de tener un cuadro separado para la sola línea de texto "añadir miniatura" o las dos casillas de verificación de discusiones. Nada más.

kaiser kaiser
3 feb 2011 19:09:35
Mostrar los 6 comentarios restantes
3
11

Determinar Rápidamente los Detalles del Servidor y el Entorno

Si tienes múltiples servidores y múltiples entornos como desarrollo, QA y producción, esto puede ser muy útil.

Para mis sistemas, el entorno se determina por las primeras 3 letras del nombre del host, pero esto podría modificarse fácilmente para adaptarse a tus necesidades.

add_action( 'admin_notices', 'report_environment_status', 3 );

// Informar sobre qué servidor y detalles del entorno
function report_environment_status() {
    $server = php_uname('n');
    switch (strtolower(substr($server,0,3))) {
        case 'pXX':
            $msg = "PRODUCCIÓN";
            break;
        case 'qXX':
            $msg = "QA";
            break;
        case 'dXX':
            $msg = "DESARROLLO";
            break;
        default :
            $msg = 'DESCONOCIDO';
    }
    echo "<div id='update-nag'>";
    echo "<b>Estás en el entorno $msg. (Servidor: $server)</b>";
    echo "</div>";
}

Esto me ha salvado muchas veces de realizar actualizaciones en el entorno incorrecto.

También puedes convertirlo en un plugin y activarlo en red para que todos los sitios reciban la notificación.

5 nov 2010 22:03:12
Comentarios

gracias por este artículo. ¿Podrías elaborar un poco más sobre esto y diferentes casos de uso? Creo que también sería MUY útil para mí y para otros si pudieras incluir cualquier otro código que utilices cuando ejecutas diferentes versiones de desarrollo de código. Además, si utilizas alguna forma eficiente de mover un sitio de desarrollo a producción o migrar de un dominio a otro diferente. Todas estas cosas son muy útiles. Finalmente, ¿utilizas algún tipo de cliente de subversión al actualizar tus archivos? Si es así, ¿hay algo específico que hagas para esto?

NetConstructor.com NetConstructor.com
5 nov 2010 23:28:48

Por favor no marques esto como la respuesta. De lo contrario esta lista no funcionará.

hakre hakre
6 nov 2010 19:41:34

Creo que sería mejor usar diferentes clases CSS en el mensaje, para que los mensajes puedan tener diferentes colores de fondo en los entornos además de solo tener texto ligeramente diferente. De lo contrario, creo que dejarías de notar las diferencias de texto bastante rápido.

Ian Dunn Ian Dunn
16 ene 2012 21:01:09
0
10

Corregido: Eliminar los Meta Boxes Predeterminados de WordPress

Esto era muy útil pero tenía algunos errores

// ELIMINAR META BOXES DE LA PANTALLA DE ENTRADAS PREDETERMINADA
function remove_default_post_screen_metaboxes() {
 remove_meta_box( 'postcustom','post','normal' ); // Meta Box de Campos Personalizados
 remove_meta_box( 'postexcerpt','post','normal' ); // Meta Box de Extracto
 remove_meta_box( 'commentstatusdiv','post','normal' ); // Meta Box de Comentarios
 remove_meta_box( 'trackbacksdiv','post','normal' ); // Meta Box de Retroenlaces
 remove_meta_box( 'slugdiv','post','normal' ); // Meta Box de Slug
 remove_meta_box( 'authordiv','post','normal' ); // Meta Box de Autor
}
add_action('admin_menu','remove_default_post_screen_metaboxes');


// ELIMINAR META BOXES DE LA PANTALLA DE PÁGINAS PREDETERMINADA
function remove_default_page_screen_metaboxes() {
 global $post_type;
 remove_meta_box( 'postcustom','page','normal' ); // Meta Box de Campos Personalizados
 remove_meta_box( 'postexcerpt','page','normal' ); // Meta Box de Extracto
 remove_meta_box( 'commentstatusdiv','page','normal' ); // Meta Box de Comentarios
 remove_meta_box('commentsdiv','page','normal'); // Comentarios
 remove_meta_box( 'trackbacksdiv','page','normal' ); // Meta Box de Retroenlaces
 remove_meta_box( 'slugdiv','page','normal' ); // Meta Box de Slug
 remove_meta_box( 'authordiv','page','normal' ); // Meta Box de Autor
}
add_action('admin_menu','remove_default_page_screen_metaboxes');
9 nov 2010 00:45:36
2
10

Extendiendo el Período de Cierre de Sesión Automático

Probado en: Wordpress 3.0.1

Usando el siguiente código puedes incrementar el tiempo que las cookies se mantienen y por lo tanto los usuarios que han iniciado sesión permanecerán conectados por más tiempo:

function keep_me_logged_in_for_1_year( $expirein ) {
   return 31556926; // 1 año en segundos
}
add_filter( 'auth_cookie_expiration', 'keep_me_logged_in_for_1_year' );
11 nov 2010 14:57:07
Comentarios

hay otro truco que se puede usar y que encontré aquí: http://wpengineer.com/2064/stop-wordpress-from-ever-logging-out/

NetConstructor.com NetConstructor.com
11 nov 2010 14:58:14

Cabe señalar que el tiempo de espera de la sesión está ahí como una precaución de seguridad, por lo que extenderlo/eliminarlo hace que tu sitio sea más vulnerable.

Ian Dunn Ian Dunn
16 ene 2012 20:58:22
3
10

Añadir un enlace de "Configuración" para plugins en la página de lista de plugins

Configurar un enlace "Configuración" para plugins en la página de plugins del backend de WordPress, facilitando a los usuarios el acceso rápido a la configuración (el código también incluye una solución para versiones de WordPress anteriores a la 2.9)

// definiciones del plugin
define( 'FB_BASENAME', plugin_basename( __FILE__ ) );
define( 'FB_BASEFOLDER', plugin_basename( dirname( __FILE__ ) ) );
define( 'FB_FILENAME', str_replace( FB_BASEFOLDER.'/', '', plugin_basename(__FILE__) ) );
function filter_plugin_meta($links, $file) {
  /* crear enlace */
  if ( $file == FB_BASENAME ) {
    array_unshift(
      $links,
      sprintf( '<a href="options-general.php?page=%s">%s</a>', FB_FILENAME, __('Configuración') )
    );
  }
  return $links;
}

global $wp_version;
if ( version_compare( $wp_version, '2.7alpha', '>' ) ) {
    add_filter( 'plugin_action_links_' . FB_WM_BASENAME, 'filter_plugin_meta', 10, 2);
} else {
    add_filter( 'plugin_action_links', 'filter_plugin_meta', 10, 2 );
}
15 nov 2010 01:07:46
Comentarios

He intentado usar este código pero parece que no funciona en WordPress 3.1. ¿Puedes confirmarlo y actualizarlo?

NetConstructor.com NetConstructor.com
22 feb 2011 22:37:19

@NetConstructor.com He actualizado un poco uno de mis plugins gratuitos, en todos mis plugins esto funciona bien

bueltge bueltge
28 feb 2011 19:23:56

Ojalá todos los autores de plugins hicieran esto (para los plugins que tienen páginas de configuración, por supuesto) para que este tipo de código no fuera necesario.

JimmyPena JimmyPena
6 dic 2011 21:00:37
1
10

Eliminar el enlace automático de URLs en los comentarios de WordPress

remove_filter('comment_text', 'make_clickable', 9);
28 dic 2010 02:14:24
Comentarios

¡Genial! Estaba buscando esa función make_clickable() para aplicarla a the_content! ¿Por qué no lo hicieron desde el principio? Es tan simple como añadir add_filter( 'the_content', 'make_clickable'); Alternativamente se podría hacer cuando se guarda el post usando un hook diferente

fregante fregante
11 ene 2014 02:57:27
1
10

Añadir filtro de plantillas de página al listado de páginas

Probado en: WP 3.1

Añade un filtro de plantillas de página al listado de páginas, permitiéndote ver una lista de páginas que tienen asignada una plantilla específica.

class Page_Template_Filter {
    private $templates = array();
    public function __construct() {
        // Si no es el área de administración o el usuario actual no puede editar páginas, salimos
        if( !is_admin() || !current_user_can('edit_pages') )
            return;
        add_action( 'parse_query',           array( $this, 'pt_parse_query' ) );
        add_action( 'restrict_manage_posts', array( $this, 'pt_restrict_manage_posts' ) );
    }
    public function pt_parse_query( $query ) {
        global $pagenow, $post_type;
        if( 'edit.php' != $pagenow )
            return;

        switch( $post_type ) {
            case 'post':

            break;
            case 'page':
                $this->templates = get_page_templates();

                if( empty( $this->templates ) )
                    return;

                if( !$this->is_set_template() )
                    return;

                $meta_group = array( 'key' => '_wp_page_template', 'value' => $this->get_template() );
                set_query_var( 'meta_query', array( $meta_group ) );
            break;
        }
    }
    public function pt_restrict_manage_posts() {
        if( empty( $this->templates ) )
            return;
        $this->template_dropdown();
    }
    private function get_template() {
        if( $this->is_set_template() )
            foreach( $this->templates as $template ) {
                if( $template != $_GET['page_template'] )
                    continue;
                return $template;
            }
        return '';
    }
    private function is_set_template() {
        return (bool) ( isset( $_GET['page_template'] ) && ( in_array( $_GET['page_template'], $this->templates ) ) );
    }
    private function template_dropdown() {
        ?>
        <select name="page_template" id="page_template">
            <option value=""> - sin plantilla - </option>
            <?php foreach( $this->templates as $name => $file ): ?>
            <option value="<?php echo $file; ?>"<?php selected( $this->get_template() == $file ); ?>><?php _e( $name ); ?></option>
            <?php endforeach;?>
        </select>
        <?php 
    }
}

add_action('admin_init', 'load_ptf');
function load_ptf() {
    $Page_Template_Filter = new Page_Template_Filter;
}

Requiere al menos la versión 3.1 para funcionar, aunque el meta_query podría reemplazarse con los parámetros más antiguos meta_key y meta_value para la versión 3.0.

19 mar 2011 17:52:55
Comentarios

funciona perfectamente, probado en 3.4-alpha

brasofilo brasofilo
2 abr 2012 16:01:27
3
10

Mostrar solo publicaciones y medios del Autor que ha iniciado sesión & corregir los recuentos de publicaciones/medios en las barras de filtro.

Probado en: WordPress 3.4.1

Por defecto, WordPress permite a los Autores ver los títulos de las publicaciones de otros usuarios, borradores no publicados y todos los medios, aunque no puedan editarlos.

Usa este código para permitir que solo se muestren las publicaciones y medios del Autor que ha iniciado sesión actualmente.

A diferencia de otras soluciones, esto también corrige el recuento de publicaciones/medios en las barras de filtro (Todos|Publicados|Borradores|Pendientes|Papelera; Todos|Imágenes|Videos|No adjuntos).

// Mostrar solo publicaciones y medios relacionados con el autor que ha iniciado sesión
add_action('pre_get_posts', 'query_set_only_author' );
function query_set_only_author( $wp_query ) {
    global $current_user;
    if( is_admin() && !current_user_can('edit_others_posts') ) {
        $wp_query->set( 'author', $current_user->ID );
        add_filter('views_edit-post', 'fix_post_counts');
        add_filter('views_upload', 'fix_media_counts');
    }
}

// Corregir recuentos de publicaciones
function fix_post_counts($views) {
    global $current_user, $wp_query;
    unset($views['mine']);
    $types = array(
        array( 'status' =>  NULL ),
        array( 'status' => 'publish' ),
        array( 'status' => 'draft' ),
        array( 'status' => 'pending' ),
        array( 'status' => 'trash' )
    );
    foreach( $types as $type ) {
        $query = array(
            'author'      => $current_user->ID,
            'post_type'   => 'post',
            'post_status' => $type['status']
        );
        $result = new WP_Query($query);
        if( $type['status'] == NULL ):
            $class = ($wp_query->query_vars['post_status'] == NULL) ? ' class="current"' : '';
            $views['all'] = sprintf(__('<a href="%s"'. $class .'>Todos <span class="count">(%d)</span></a>', 'all'),
                admin_url('edit.php?post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'publish' ):
            $class = ($wp_query->query_vars['post_status'] == 'publish') ? ' class="current"' : '';
            $views['publish'] = sprintf(__('<a href="%s"'. $class .'>Publicados <span class="count">(%d)</span></a>', 'publish'),
                admin_url('edit.php?post_status=publish&post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'draft' ):
            $class = ($wp_query->query_vars['post_status'] == 'draft') ? ' class="current"' : '';
            $views['draft'] = sprintf(__('<a href="%s"'. $class .'>Borrador'. ((sizeof($result->posts) > 1) ? "es" : "") .' <span class="count">(%d)</span></a>', 'draft'),
                admin_url('edit.php?post_status=draft&post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'pending' ):
            $class = ($wp_query->query_vars['post_status'] == 'pending') ? ' class="current"' : '';
            $views['pending'] = sprintf(__('<a href="%s"'. $class .'>Pendientes <span class="count">(%d)</span></a>', 'pending'),
                admin_url('edit.php?post_status=pending&post_type=post'),
                $result->found_posts);
        elseif( $type['status'] == 'trash' ):
            $class = ($wp_query->query_vars['post_status'] == 'trash') ? ' class="current"' : '';
            $views['trash'] = sprintf(__('<a href="%s"'. $class .'>Papelera <span class="count">(%d)</span></a>', 'trash'),
                admin_url('edit.php?post_status=trash&post_type=post'),
                $result->found_posts);
        endif;
    }
    return $views;
}

// Corregir recuentos de medios
function fix_media_counts($views) {
    global $wpdb, $current_user, $post_mime_types, $avail_post_mime_types;
    $views = array();
    $_num_posts = array();
    $count = $wpdb->get_results( "
        SELECT post_mime_type, COUNT( * ) AS num_posts 
        FROM $wpdb->posts 
        WHERE post_type = 'attachment' 
        AND post_author = $current_user->ID 
        AND post_status != 'trash' 
        GROUP BY post_mime_type
    ", ARRAY_A );
    foreach( $count as $row )
        $_num_posts[$row['post_mime_type']] = $row['num_posts'];
    $_total_posts = array_sum($_num_posts);
    $detached = isset( $_REQUEST['detached'] ) || isset( $_REQUEST['find_detached'] );
    if ( !isset( $total_orphans ) )
        $total_orphans = $wpdb->get_var("
            SELECT COUNT( * ) 
            FROM $wpdb->posts 
            WHERE post_type = 'attachment' 
            AND post_author = $current_user->ID 
            AND post_status != 'trash' 
            AND post_parent < 1
        ");
    $matches = wp_match_mime_types(array_keys($post_mime_types), array_keys($_num_posts));
    foreach ( $matches as $type => $reals )
        foreach ( $reals as $real )
            $num_posts[$type] = ( isset( $num_posts[$type] ) ) ? $num_posts[$type] + $_num_posts[$real] : $_num_posts[$real];
    $class = ( empty($_GET['post_mime_type']) && !$detached && !isset($_GET['status']) ) ? ' class="current"' : '';
    $views['all'] = "<a href='upload.php'$class>" . sprintf( __('Todos <span class="count">(%s)</span>', 'archivos subidos' ), number_format_i18n( $_total_posts )) . '</a>';
    foreach ( $post_mime_types as $mime_type => $label ) {
        $class = '';
        if ( !wp_match_mime_types($mime_type, $avail_post_mime_types) )
            continue;
        if ( !empty($_GET['post_mime_type']) && wp_match_mime_types($mime_type, $_GET['post_mime_type']) )
            $class = ' class="current"';
        if ( !empty( $num_posts[$mime_type] ) )
            $views[$mime_type] = "<a href='upload.php?post_mime_type=$mime_type'$class>" . sprintf( translate_nooped_plural( $label[2], $num_posts[$mime_type] ), $num_posts[$mime_type] ) . '</a>';
    }
    $views['detached'] = '<a href="upload.php?detached=1"' . ( $detached ? ' class="current"' : '' ) . '>' . sprintf( __( 'No adjuntos <span class="count">(%s)</span>', 'archivos no adjuntos' ), $total_orphans ) . '</a>';
    return $views;
}
26 nov 2011 15:11:36
Comentarios

buen fragmento, solo un inconveniente, si no hay elementos multimedia en la biblioteca, muestra errores porque el resultado no es un array.

chrismccoy chrismccoy
25 feb 2012 02:38:23

Definí $_num_posts como un array. Esto debería corregir los errores que obtienes cuando no hay elementos multimedia en la biblioteca.

Paul Paul
17 ago 2012 00:02:53

Sé que ha pasado bastante tiempo para preguntar sobre esto, pero lo probé con mi CPT y el conteo de publicaciones parece no funcionar aunque he cambiado todo el tour type por mi CPT.

Además, ¿hay alguna manera de aplicar el filtro para los términos en mi CPT también?

Por cierto, muchas gracias por tu código.

Loc_rabbirt Loc_rabbirt
14 feb 2020 02:06:54
2

Eliminar XML-RPC cuando no se use para mejorar el rendimiento

Probado en: WordPress 3.0.1

WordPress utiliza una operación CURL para probar la capacidad SSL para XML-RPC. Si estás usando XML-RPC pero no lo necesitas, puedes eliminar el filtro. Esto representa una pequeña mejora en el rendimiento (ya que básicamente WP hace un GET con cURL en la URL https y 1) recibe un mensaje de denegación, o 2) se agota el tiempo de espera, lo que puede tardar hasta 5 segundos), pero en nuestro caso en realidad evitó un tiempo de espera de la pasarela donde un proxy se agotaba antes de que la operación cURL GET se agotara, haciendo que XML-RPC fuera inutilizable.

// Evita que WordPress pruebe la capacidad ssl en dominio.com/xmlrpc.php?rsd
remove_filter('atom_service_url','atom_service_url_filter');
13 sept 2010 22:24:19
Comentarios

Gracias por la sugerencia de código. Una pregunta, si estás usando XML-RPC pero no estás utilizando las capacidades SSL, ¿la inclusión de este código aceleraría algo? Si no es así, ¿en qué situaciones sería beneficioso incluir este código?

NetConstructor.com NetConstructor.com
14 sept 2010 05:37:28

Tiene un efecto mínimo en el rendimiento para las llamadas XML-RPC, ya que ya no tienen que verificar la capacidad SSL a través de una solicitud HTTP.

gabrielk gabrielk
19 sept 2010 20:57:49
2

Colección de ediciones rápidas en functions.php

Tengo algunos ajustes geniales en functions.php también. Encontré la mayoría de estos buscándolos a lo largo de los años.

Final del extracto (Excerpt)

function new_excerpt_more($more) {
    return '...';
}
add_filter('excerpt_more', 'new_excerpt_more');

Reemplazar el logo del administrador de WP

function new_admin_logo() {
  echo '<style type="text/css">#header-logo { background-image: url('.get_bloginfo('template_directory').'/images/admin_logo.png) !important; }</style>';
}
add_action('admin_head', 'new_admin_logo');

Favicon personalizado para el área de administración

function admin_favicon() {
 echo '<link rel="shortcut icon" type="image/x-icon" href="' . get_bloginfo('template_directory') . '/images/favicon.ico" />';
}
add_action( 'admin_head', 'admin_favicon' );

Pie de página personalizado en el administrador

function custom_admin_footer() {
echo '¡Bienvenido/a a mi blog! ¡No más enlaces de documentación!';
}
add_filter('admin_footer_text', 'custom_admin_footer');
6 nov 2010 23:08:39
Comentarios

gracias, pero estos ya han sido agregados.

NetConstructor.com NetConstructor.com
8 nov 2010 17:12:18

¿podrías revisar estos y asegurarte de que no haya entradas duplicadas, además de separar cada una en su propia respuesta en las próximas semanas?

NetConstructor.com NetConstructor.com
26 ene 2011 16:30:41
2

Obtener todos los campos personalizados globalmente

function get_custom_field($key, $echo = FALSE) {
    global $post;
    $custom_field = get_post_meta( $post->ID, $key, true );
    if ( $echo == false ) 
        return $custom_field;
    echo $custom_field;
}

Luego llama al campo con una sola línea

<?php get_custom_field('nombre-del-campo-personalizado', TRUE); ?>
15 nov 2010 07:45:04
Comentarios

¿Por qué alguien usaría esto? ¿Cuál es el beneficio?

matt matt
5 dic 2010 07:10:33

para sitios / temas que usan muchos campos personalizados (que uso frecuentemente en trabajos para clientes) permite tener menos código en el tema, y también agregar condicionales sobre si mostrar o no el campo.

Norcross Norcross
11 dic 2010 00:44:34
0

Devolver el número de comentarios

Esto es similar a count_user_posts(), pero devuelve el número de comentarios en su lugar:

function count_user_comments($id) {
global $wpdb;
$users = $wpdb->get_var("
        SELECT COUNT( * ) AS total
        FROM $wpdb->comments
        WHERE comment_approved = 1 
        AND user_id = $id");
return $users;
}

Más: Contar publicaciones del usuario (incluyendo tipos de post personalizados) o comentarios:

function atom_count($user_id, $what_to_count = 'post') {
  global $wpdb;    
  $where = $what_to_count == 'comment' ? "WHERE comment_approved = 1 AND user_id = {$user_id}" : get_posts_by_author_sql($what_to_count, TRUE, $user_id);
  $from = "FROM ".(($what_to_count == 'comment') ? $wpdb->comments : $wpdb->posts);    
  $count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) {$from} {$where}"));
  return $count;
}

Ejemplos de uso:

<?php echo atom_count(1, 'movie'); // muestra el conteo del tipo de post 'movie' ?>

<?php echo atom_count(1, 'comment'); // muestra el conteo de comentarios ?>

17 nov 2010 04:52:13
0

Habilitar oEmbed en Widgets de Texto/HTML

add_filter( 'widget_text', array( $wp_embed, 'run_shortcode' ), 8 );
add_filter( 'widget_text', array( $wp_embed, 'autoembed'), 8 );

Yo uso esto para widgets de videos de YouTube y contenido de Flickr.

28 dic 2010 02:07:12
3

Contador de Palabras en Publicaciones

Probado en: Wordpress 3.0.1

(Extraído originalmente del plugin Post Word Count por Nick Momrik)

Añade un conteo del total de palabras publicadas al final del cuadro "Ahora mismo" en el panel de administración. Útil si estás utilizando tu blog como medio para algo como NaNoWriMo o si simplemente quieres llevar un registro de cuán prolíficas se han vuelto tus habilidades de blogging.

function post_word_count() {
    $count = 0;
    $posts = get_posts( array(
        'numberposts' => -1,
        'post_type' => array( 'post', 'page' )
    ));
    foreach( $posts as $post ) {
        $count += str_word_count( strip_tags( get_post_field( 'post_content', $post->ID )));
    }
    $num =  number_format_i18n( $count );
    // Este bloque añadirá tu conteo de palabras a la sección de estadísticas del cuadro "Ahora mismo"
    $text = _n( 'Palabra', 'Palabras', $num );
    echo "<tr><td class='first b'>{$num}</td><td class='t'>{$text}</td></tr>";
    // Esta línea añadirá tu conteo de palabras al final del cuadro "Ahora mismo".
    echo '<p>Este blog contiene un total de <strong>' . $num . '</strong> palabras publicadas!</p>';
}

// añade a la tabla de Estadísticas de Contenido
add_action( 'right_now_content_table_end', 'post_word_count');
// añade al final del cuadro de Actividad
add_action('activity_box_end', 'post_word_count');

¡Créditos a Rarst por la limpieza del código sin consultas!

15 sept 2010 18:58:01
Comentarios

Gracias por la ayuda, Rarst. Normalmente no me gusta incluir consultas directas a la base de datos en el código del archivo function.php del plugin, pero como dije, originalmente lo tomé del plugin de otra persona.

EAMann EAMann
15 sept 2010 19:56:22

No hay problema, lo intenté hace mucho tiempo y fue un desastre. :) Ahora con habilidades mejoradas era el momento de hacerlo bien. ¿Por qué dejaste la parte antigua de salida? Creo que tiene sentido mostrarla con el resto de estadísticas. Por cierto, esta versión da un total diferente (comparado con explode), probablemente debido a los filtros en el camino y demás al obtener los datos mediante la API.

Rarst Rarst
15 sept 2010 20:05:31

La diferencia en el conteo de entradas es resultado de los filtros... pero usar get_posts() probablemente dará un conteo de palabras más preciso de todos modos. Dejé la línea antigua de salida simplemente porque así es como lo he estado usando... más una diferencia de opinión que otra cosa... Volveré a agregar tu ejemplo para incluirlo en las estadísticas y que la gente pueda elegir.

EAMann EAMann
15 sept 2010 20:17:22
0

Cargar scripts condicionalmente

Aquí hay una forma de cargar scripts solo si un shortcode o widget específico está presente. fuente: Cargar scripts solo si un shortcode o widget específico está presente

function has_my_shortcode($posts) {
    if ( empty($posts) )
        return $posts;
    $found = false;
    foreach ($posts as $post) {
        if ( stripos($post->post_content, '[my_shortcode') )
            $found = true;
            break;
        }
    if ($found){
        $urljs = get_bloginfo( 'template_directory' ).IMP_JS;
    wp_register_script('my_script', $urljs.'myscript.js' );
    wp_print_scripts('my_script');
}
    return $posts;
}
add_action('the_posts', 'has_my_shortcode');

Y así es como cargar scripts solo si un widget específico está presente

Para cargar el script solo en la página donde se carga el widget, deberás agregar el código is_active_widget() en tu clase de widget. Por ejemplo, mira el widget predeterminado de comentarios recientes (wp-includes/default-widgets.php, línea 602):

class WP_Widget_Recent_Comments extends WP_Widget {
    function WP_Widget_Recent_Comments() {
        $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'Los comentarios más recientes' ) );
        $this->WP_Widget('recent-comments', __('Comentarios recientes'), $widget_ops);
        $this->alt_option_name = 'widget_recent_comments';
        if ( is_active_widget(false, false, $this->id_base) )
        add_action( 'wp_head', array(&$this, 'recent_comments_style') );
        add_action( 'comment_post', array(&$this, 'flush_widget_cache') );
        add_action( 'transition_comment_status', array(&$this, 'flush_widget_cache') );
    }
30 sept 2010 14:57:18
0

CSS Personalizado para el Panel de Control

/* Cambiar el CSS del panel de WordPress */
function custom_admin_styles() {
    echo '<style type="text/css">#wphead{background:#069}</style>';
}
add_action('admin_head', 'custom_admin_styles');

Puedes agregar cualquier cambio de CSS entre las etiquetas.

10 nov 2010 20:42:26
0

Eliminar los Prefijos "Privado" y "Protegido"

Esta función elimina el prefijo "Privado:" de las entradas y páginas marcadas como privadas. Útil para contenido solo visible para usuarios registrados o grupos específicos.

function the_title_trim($title) {
$title = attribute_escape($title);
$findthese = array(
    '#Protegido:#', // Busca el prefijo "Protegido:"
    '#Privado:#'   // Busca el prefijo "Privado:"
);
$replacewith = array(
    '', // Reemplaza "Protegido:" con cadena vacía
    ''  // Reemplaza "Privado:" con cadena vacía
);
$title = preg_replace($findthese, $replacewith, $title);
return $title;
}
add_filter('the_title', 'the_title_trim');

ACTUALIZACIÓN: Se ha actualizado para incluir también la eliminación del prefijo "Protegido:".

3 dic 2010 20:13:33
0

Longitud personalizada del extracto

function excerpt($num) {
    $limit = $num+1;
    $excerpt = explode(' ', get_the_excerpt(), $limit);
    array_pop($excerpt);
    $excerpt = implode(" ",$excerpt)."... (<a href='" .get_permalink($post->ID) ." '>Leer más</a>)";
    echo $excerpt;
}

Limita la longitud del extracto mostrado escribiendo en el tema: excerpt('20');

Ejemplo: <?php excerpt('22'); ?> Esto limitará el extracto a 22 caracteres.

El extracto se interrumpirá con ... (Leer más)

2 ene 2011 22:00:51
0

Añadir el slug de la página padre a body_class

/***************************************************************
* Función body_class_section
* Añade la página de nivel superior a la clase del body para secciones coloreadas
***************************************************************/

add_filter('body_class','body_class_section');

function body_class_section($classes) {
    global $wpdb, $post;
    if (is_page()) {
        if ($post->post_parent) {
            $parent  = end(get_post_ancestors($current_page_id));
        } else {
            $parent = $post->ID;
        }
        $post_data = get_post($parent, ARRAY_A);
        $classes[] = 'section-' . $post_data['post_name'];
    }
    return $classes;
}

Este filtro añade una clase única al body basada en el padre de nivel más alto de la página actual. Lo uso para sitios que tienen colores o diseños específicos para cada sección del sitio. Funciona mejor con sitios basados en páginas. Ejemplos de CSS:

.section-about { background: red; }
.section-portfolio { background: blue; }

Tu tema también debe hacer uso de la función body_class.

Corregir objetos flash en oEmbed

/***************************************************************
* Función my_oembed_wmode
* Corrige el modo de ventana para objetos flash en oEmbed
***************************************************************/

add_filter('embed_oembed_html', 'my_oembed_wmode', 1);

function my_oembed_wmode( $embed ) {
    if ( strpos( $embed, '<param' ) !== false ) {
        $embed = str_replace( '<embed', '<embed wmode="transparent" ', $embed );
        $embed = preg_replace( '/param>/', 'param><param name="wmode" value="transparent" />', $embed, 1);
    }
    return $embed;
}

He tenido problemas en el pasado donde los objetos Flash de oEmbed colisionaban con menús de navegación desplegables. Este filtro soluciona ese problema añadiendo un modo de ventana transparente a los embeds.

Eliminar la columna "comentarios" de la lista de páginas en el Admin

/***************************************************************
* Función custom_pages_columns
* Elimina "comentarios" de la vista general de páginas (rara vez uso comentarios en páginas)
***************************************************************/

add_filter('manage_pages_columns', 'custom_pages_columns');

function custom_pages_columns($defaults) {
    unset($defaults['comments']);
    return $defaults;
}

Casi nunca hago uso de los comentarios en páginas y esto ayuda a mantener el WordPress dashboard más ordenado.

21 feb 2011 21:03:12
1

Habilitar Paginación Numérica

Probado en: Wordpress 3.0.1

/* Paginación Numérica ********************************************/

function numeric_pagination ($pageCount = 9, $query = null) {

 if ($query == null) {
  global $wp_query;
  $query = $wp_query;
 }

 if ($query->max_num_pages <= 1) {
  return;
 }

 $pageStart = 1;
 $paged = $query->query_vars['paged'];

 // establecer página actual si estamos en la primera página
 if ($paged == null) {
  $paged = 1;
 }

 // calcular si el inicio de página está a la mitad de las páginas visibles actuales y ajustarlo en consecuencia
 if ($paged > floor($pageCount / 2)) {
  $pageStart = $paged - floor($pageCount / 2);
 }

 if ($pageStart < 1) {
  $pageStart = 1;
 }

 // asegurarse de que el inicio de página sea correcto
 if ($pageStart + $pageCount > $query->max_num_pages) {
  $pageCount = $query->max_num_pages - $pageStart;
 }

?>
 <div id="archive_pagination">
<?php
 if ($paged != 1) {
?>
 <a href="<?php echo get_pagenum_link(1); ?>" class="numbered page-number-first"><span>&lsaquo; <?php _e('<< Primera', 'global'); ?></span></a>
<?php
 }
 // primera página no visible...
 if ($pageStart > 1) {
  //echo 'anterior';
 }
 for ($p = $pageStart; $p <= $pageStart + $pageCount; $p ++) {
  if ($p == $paged) {
?>
  <span class="numbered page-number-<?php echo $p; ?> current-numeric-page"><?php echo $p; ?></span>
<?php } else { ?>
  <a href="<?php echo get_pagenum_link($p); ?>" class="numbered page-number-<?php echo $p; ?>"><span><?php echo $p; ?></span></a>

<?php
  }
 }
 // última página no visible
 if ($pageStart + $pageCount < $query->max_num_pages) {
  //echo "última";
 }
 if ($paged != $query->max_num_pages) {
?>
  <a href="<?php echo get_pagenum_link($query->max_num_pages); ?>" class="numbered page-number-last"><span><?php _e('>> Última', 'global'); ?> &rsaquo;</span></a>
<?php } ?>

 </div>
10 sept 2010 03:04:37
Comentarios

Ya existe una función en WordPress para hacer paginación numérica, consulta http://codex.wordpress.org/Function_Reference/paginate_links

t31os t31os
11 nov 2010 19:09:23
1

Mostrar contenido específico solo para usuarios registrados

Probado en: WordPress 3.0.1

function content_only4logged_in($content) {

    // TODOS LOS USUARIOS REGISTRADOS
    if ( is_user_logged_in() &&
            !is_null($content) &&
            !is_feed()
         ) {
        return $content;
    } else {
        $content  = wp_html_excerpt( $content, 80 );
        $content .= ' …';
        $content .= __( 'Lo sentimos, el resto de este contenido solo está disponible para usuarios registrados.', FB_TEXTDOMAIN );
        return $content;
    }
}
add_action( 'the_content', 'content_only4logged_in' );

más posibilidades e información en el post http://wpengineer.com/2046/control-the-wordpress-content-via-userrights-or-time/

17 sept 2010 11:34:49
Comentarios

No puedo hacer que esto muestre contenido alterado para usuarios no registrados... la primera parte funciona bien, pero si el usuario no está registrado y la página está marcada como privada, simplemente me muestra el error 404 regular?

gillespieza gillespieza
9 feb 2011 22:58:07
2

Haz que tus Enlaces Cortos sean Más Cortos Eliminando WWW

Probado en: Wordpress 3.0.1

Haz que tus enlaces cortos sean más cortos si incluyes www. en tu dominio. Vía scratch99.com:

// Filtro para modificar los enlaces cortos eliminando 'www.'
add_filter('get_shortlink','sjc_alter_shortlink');
function sjc_alter_shortlink($shortlink) {
    // Elimina 'www.' del enlace corto usando una expresión regular
    $shortlink = preg_replace('/^(https?:\/\/)?(www\.)/','$1',$shortlink);
    return $shortlink;
}
28 sept 2010 03:53:46
Comentarios

Se debería agregar una verificación para asegurarse de que la cadena "www." solo se elimine si se encuentra al principio de la parte del dominio de la URL original. Reemplazarla de manera ingenua en cualquier parte de la URL generará errores si se usa en un dominio como owww.com (que en realidad parece estar ejecutando WordPress) :)

Ingve Ingve
29 may 2012 00:30:34

@Ingve Lo corregí, ahora solo eliminará el www inicial

fregante fregante
11 ene 2014 03:04:48
2

Verificar si una publicación tiene contenido incrustado

Comprueba si una publicación tiene contenido incrustado, funciona dentro del bucle usando el ID de la publicación actual, o alternativamente se le puede pasar un ID para determinar qué publicación verificar.

function has_embed( $post_id = false ) {
    if( !$post_id ) $post_id = get_the_ID();
    else $post_id = absint( $post_id );
    if( !$post_id ) return false;

    $post_meta = get_post_custom_keys( $post_id );
    $post_meta = array_map( 'trim' , $post_meta );

    foreach( $post_meta as $meta ) {
        if( '_oembed' != substr( $meta , 0 , 7 ) )
            continue;
        return true;
    }
    return false;
}

Usarías la función de la misma manera que verificas si una publicación tiene una etiqueta..

if( has_embed() ) {
   // hacer lo que sea
}

La función devuelve true si se encuentra un contenido incrustado, false en caso contrario.

4 nov 2010 19:11:02
Comentarios

Interesante, pero me pregunto, ¿por qué lo usarías? ¿Qué tipo de aplicaciones tiene?

matt matt
5 dic 2010 07:08:44

Verificar si una publicación tiene un embed en una página que muestra extractos sería un uso (y es el caso de uso original para el que lo escribí). Otros casos de uso posibles serían con usuarios que escriben sus propias plantillas de temas y quieren proporcionar funcionalidad dependiendo de si una publicación (o tipo) tiene contenido incrustado, sin la necesidad de un filtro en the_content o numerosas llamadas a get_post_custom_keys.

t31os t31os
5 dic 2010 11:34:42
0

Mostrar Publicaciones de Diferentes Tipos de Entradas Personalizadas en la página de inicio

Al agregar el siguiente código al final de esta publicación en tu archivo functions.php, puedes hacer que WordPress muestre automáticamente publicaciones de diferentes tipos de entradas personalizadas que hayas creado. Actualmente, por defecto, WordPress solo muestra publicaciones que pertenecen al tipo de entrada predeterminado "post".

En el ejemplo proporcionado a continuación, necesitarás cambiar la sección que llama:

$query->set( 'post_type', array('post', 'page', 'services', 'attachment'));

Con tus propios tipos de entradas personalizadas que te gustaría incluir en los resultados de la lista de publicaciones de la página de inicio. En este caso, le estamos pidiendo a WordPress que nos devuelva todas las publicaciones pertenecientes a los tipos de entrada predeterminados "post" y "page", luego le pedimos a WordPress que también incluya el tipo de entrada personalizado que creamos para "services" y finalmente el tipo de entrada predeterminado de WordPress "attachment", lo que significa que cada vez que se agregue algo a la biblioteca multimedia, se mostrará automáticamente en la página de inicio como una entrada separada.

// LISTA DE PUBLICACIONES PERSONALIZADAS EN LA PÁGINA DE INICIO QUE INCLUYE DIFERENTES POST_TYPES
// asegúrate de editar los tipos de entradas que deseas incluir en la lista a continuación
add_filter( 'pre_get_posts', 'my_homepage_post_list' );
function my_homepage_post_list ( $query ) {
    if ( is_home() && false == $query->query_vars['suppress_filters'] )
        $query->set( 'post_type', array('post', 'page', 'services', 'attachment'));
    return $query;
}

También puedes utilizar esta consulta personalizada en diferentes ubicaciones, como en un feed personalizado a través de algo como esto:

if (( is_home() && false == $query->query_vars['suppress_filters'] ) || is_feed())
14 nov 2010 21:53:13
0

Eliminar los campos de información de contacto predeterminados del perfil de usuario y reemplazarlos con algo más útil

La segunda parte de esta función ya se mencionó anteriormente, pero eliminar los campos predeterminados - AIM, Yahoo IM y Jabber/Google Talk - aún no:

function update_contact_methods( $contactmethods ) {

// Eliminar campos predeterminados molestos e innecesarios
unset($contactmethods['aim']);  
unset($contactmethods['jabber']);  
unset($contactmethods['yim']);  

// Agregar nuevos campos  
$contactmethods['phone'] = 'Teléfono';  
$contactmethods['mobile'] = 'Móvil';  
$contactmethods['address'] = 'Dirección';  

return $contactmethods;
}
add_filter('user_contactmethods', 'update_contact_methods');

Por supuesto, puedes agregar tantos campos como desees (ver ejemplos anteriores en este hilo) bajo "Agregar nuevos campos"

22 dic 2010 10:46:37