La mejor colección de código para tu archivo 'functions.php'
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.

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

¡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

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

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

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

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

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

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"]

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";'));

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

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

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()"

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

@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: 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 -- 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 :)

@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 -- 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.

@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 -- 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?

@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.

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.

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?

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

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.

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

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

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

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

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

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

¡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

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.

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

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

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

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.

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

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?

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

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

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 ?>

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!

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.

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.

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.

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

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.

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:".

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)

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.

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>‹ <?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'); ?> ›</span></a>
<?php } ?>
</div>

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

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/

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

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) :)

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.

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

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
.

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())

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"
