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.

Añadir automáticamente imágenes de cabecera desde una ubicación de directorio
Dentro del tema predeterminado que viene con WordPress, notarás un menú de tema adicional que se activa y te permite seleccionar una imagen de cabecera para usar. En el código del tema predeterminado, estas imágenes están codificadas directamente en el archivo functions.php. El código a continuación permite que WordPress detecte automáticamente nuevas imágenes basadas en un directorio específico de imágenes de cabecera que puedes crear en tu servidor (o dentro de la carpeta de tu tema).
Incluirá automáticamente cualquier archivo .jpg o .jpeg. Cada imagen debe tener un archivo de miniatura asociado, pero puede ser simplemente una copia del original con un nombre diferente que debe terminar en "-thumbnail". El nombre asociado se usa como descripción en los ajustes de apariencia de cabeceras y los guiones bajos se reemplazan automáticamente con espacios. (Por ejemplo, Mi_Imagen_Cabecera_A.jpg, Mi_Imagen_Cabecera_A-thumbnail.jpg tendrá una descripción que se mostrará automáticamente como "Mi Imagen Cabecera A").
if ($handle = opendir( TEMPLATEPATH . '/images/headers/') ) {
$headers = array();
while (false !== ($file = readdir($handle))) {
$pos = strrpos( $file, '.' );
if( $pos !== false && $pos > 0 ) {
$file_name = substr( $file, 0, $pos );
if( strpos( $file_name, "-thumbnail" ) === false ) {
$file_ext = substr( $file, $pos+1 );
$file_ext_low = strtolower( $file_ext );
if( $file_ext_low == "jpg" || $file_ext_low == "jpeg" ) {
$headers[$file_name] = array (
'url' => '%s/images/headers/' . $file,
'thumbnail_url' => '%s/images/headers/' . $file_name ."-thumbnail." . $file_ext,
'description' => __( str_replace( "_", " ", $file_name ), 'twentyten' )
);
}
}
}
}
closedir($handle);
register_default_headers( $headers );
}

Mostrando información para usuarios registrados
if ( is_user_logged_in() ) {
}
no funciona en el archivo functions.php. Puedes usar este código:
if ( !function_exists('is_user_logged_in') ) :
function is_user_logged_in() {
$user = wp_get_current_user();
if ( $user->id == 0 ){
// Esta sección si el usuario no está registrado
} else {
// Esta sección si el usuario está registrado
}
}
endif;

if( !current_user_can('read')
debería captar a los invitados (es decir, usuarios no identificados) ..

Logos personalizados para la página de inicio de sesión y el administrador
/*-----------------------------------------------------------------------------------*/
/* Logos personalizados
/*-----------------------------------------------------------------------------------*/
function custom_admin_logo() {
echo '
<style type="text/css">
#header-logo { background-image: url('.get_bloginfo('template_directory').'/ruta/a/imagenes/admin-logo.png) !important; }
</style>
';
}
add_action('admin_head', 'custom_admin_logo');
function custom_login_logo() {
echo '<style type="text/css">
h1 a { background-image:url('.get_bloginfo('template_directory').'/ruta/a/imagenes/login-logo.png) !important; }
</style>';
}
add_action('login_head', 'custom_login_logo');

Por favor, revisa este gist. Hay opciones aún mejores que las mostradas en el gist. También podrías intentar participar en el ticket de trac (enlace en el encabezado del plugin del gist).

Eliminar al Administrador (Usuario #1) de la lista de usuarios
function your_pre_user_query($user_search) {
$user = wp_get_current_user();
if ($user->ID!=1) { // Si el usuario actual no es el ID 1
global $wpdb;
$user_search->query_where = str_replace('WHERE 1=1',
"WHERE 1=1 AND {$wpdb->users}.ID<>1",$user_search->query_where); // Excluir al usuario con ID 1
}
}
add_action('pre_user_query','your_pre_user_query'); // Añadir acción al hook pre_user_query

Nuevamente: el usuario 1 puede no ser un administrador. Consulta Roles y Capacidades.

Es un ejemplo. Además, en instalaciones predeterminadas el usuario 1 es Admin - el primer usuario creado. Por eso hice énfasis en (Usuario #1)

Es un ejemplo que muestra cómo no verificar capacidades administrativas. No deberías usar este código en un sitio web real.

Exactamente. Este código no verifica capacidades, toscho, sino un usuario específico. Este código no tiene nada que ver con capacidades y no he mencionado capacidades en ningún momento. No veo por qué esto no podría usarse en sitios en producción.

@Daniel Sachs Si estás buscando al primer administrador añadido, primero verifica los roles de todos los usuarios, luego ordénalos por su ID y toma el primero. Como dijo @toscho: Actualmente es un "ejemplo de cómo no deberías hacerlo". Razones: a) el administrador real podría no ser el que tiene el ID más bajo b) Si alguien más trabajara en esto, ella/él no buscaría esta funcionalidad en un tema.

Obtener Atributos de una Miniatura Dada
Utiliza esta función dentro del bucle para determinar el ancho, alto y URL de una imagen en miniatura. Muy útil para asignar una imagen en miniatura como elemento de fondo mediante CSS en línea.
/**
* OBTENER ATRIBUTOS DE LA MINIATURA
*
* Recupera el ancho, alto y URI de una miniatura.
*
* @author Philip Downer <philip@manifestbozeman.com>
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version v1.0
*
* @param string $return Acepta 'path', 'width' o 'height'.
* @param string $size El tamaño de miniatura correspondiente a la función {@link add_image_size() del núcleo de WP}.
* @return mixed Devuelve la información solicitada, o si no hay 'Imagen Destacada' asignada, devuelve 'false'.
*/
function get_thumb_attr($return,$size='thumbnail') {
global $post;
if (has_post_thumbnail($post->ID)) {
$thumb = wp_get_attachment_image_src(get_post_thumbnail_id(), 'intro');
if ( $return == 'path' ) { return $thumb[0]; }
if ( $return == 'width' ) { return $thumb[1]; }
if ( $return == 'height' ) { return $thumb[2]; }
} else {
return false;
}
}//end function

Mostrar el contenido de un widget fuera del contexto de una barra lateral utilizando su ID. El HTML envolvente antes/después no está incluido. Necesitas conocer el ID específico del widget que deseas (ej. 'text-5').
function widget_contents($id) {
list($type,$number) = explode('-',$id);
global $wp_registered_widgets;
$wp_registered_widgets[$id]['callback'][0]->display_callback(array('widget_id'=>$id),$number);
}
Puedes revisar la salida de wp_get_sidebars_widgets() si no estás seguro del ID preciso que necesitas.
Un ejemplo más completo extraído de /wp-includes/widgets.php bajo la función dynamic_sidebar():
function render_widget($id) {
global $wp_registered_widgets;
$params = array_merge(
array( array('widget_id' => $id, 'widget_name' => $wp_registered_widgets[$id]['name']) ),
(array) $wp_registered_widgets[$id]['params']
);
$classname_ = '';
foreach ( (array) $wp_registered_widgets[$id]['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'], $id, $classname_);
if ( is_callable($wp_registered_widgets[$id]['callback']) )
call_user_func_array($wp_registered_widgets[$id]['callback'], $params);
}

Vaya. El método mucho más simple sería usar the_widget()
http://codex.wordpress.org/Function_Reference/the_widget

Emoticonos personalizados (plugin)
/**
* Emoticonos.
*/
function filter_smilies_src($img_src, $img, $siteurl) {
return plugins_url('', __FILE__) . '/img/smilies/' . $img;
}
add_filter('smilies_src', 'filter_smilies_src', 1, 10);
Emoticonos personalizados (tema)
/**
* Emoticonos.
*/
function filter_smilies_src($img_src, $img, $siteurl) {
return get_bloginfo('stylesheet_directory') . '/images/smilies/' . $img;
}
add_filter('smilies_src', 'filter_smilies_src', 1, 10);

Reposicionar el Editor WYSIWYG mediante JQUERY
Probado en: WordPress 3.0.1
Este código te permitirá eliminar cajas meta específicas que WordPress añade por defecto en las pantallas de ENTRADAS y PÁGINAS.
// REPOSICIONAR EL EDITOR WYSIWYG MEDIANTE JQUERY
add_action('admin_head','admin_head_hook');
function admin_head_hook() {
?><style type="text/css">
#postdiv.postarea, #postdivrich.postarea { margin:0; }
#post-status-info { line-height:1.4em; font-size:13px; }
.custom-wysiwyg-editor-container { margin:2px 6px 6px 6px; }
#ed_toolbar { display:none; }
#postdiv #ed_toolbar, #postdivrich #ed_toolbar { display:block; }
</style><?php
}
add_action('admin_footer','admin_footer_hook');
function admin_footer_hook() {
?><script type="text/javascript">
jQuery('#postdiv, #postdivrich').prependTo('.custom-wysiwyg-editor-container');
</script><?php
}

Cerrar automáticamente etiquetas faltantes en el editor WYSIWYG
Probado en: WordPress 3.0.1
Este código cerrará automáticamente cualquier etiqueta faltante al usar el editor WYSIWYG.
// LIMPIA AUTOMÁTICAMENTE EL HTML DEL EDITOR WYSIWYG CERRANDO ETIQUETAS FALTANTES
function clean_bad_content($bPrint = false) {
global $post;
$szPostContent = $post->post_content;
$szRemoveFilter = array("~<p[^>]*>\s?</p>~", "~<a[^>]*>\s?</a>~", "~<font[^>]*>~", "~<\/font>~", "~style\=\"[^\"]*\"~", "~<span[^>]*>\s?</span>~");
$szPostContent = preg_replace($szRemoveFilter, '', $szPostContent);
$szPostContent = apply_filters('the_content', $szPostContent);
if ($bPrint == false) return $szPostContent;
else echo $szPostContent;
}

Eliminar atributos role="search"
para get_search_form()
// Función para eliminar el atributo role de los formularios de búsqueda
function remove_role_search($role)
{
$result = array();
// Busca todos los atributos role en el formulario
preg_match_all('|role="[^"]*"|U', $role, $result);
// Elimina cada atributo role encontrado
foreach ($result[0] as $role_tag) {
$role = str_replace($role_tag, '', $role);
}
return $role;
}
// Aplica el filtro al formulario de búsqueda de WordPress
add_filter('get_search_form', 'remove_role_search');

Añadir un enlace de inicio de sesión a wp_nav_menu
//AÑADIR ENLACE DE LOGIN AL MENÚ
add_filter('wp_nav_menu_items', 'add_login_logout_link', 10, 2);
function add_login_logout_link($items, $args) {
$loginoutlink = wp_loginout('index.php', false);
$items .= '<li>'. $loginoutlink .'</li>';
return $items;
}

Cambiar el nombre del menú "Posts" en el administrador por el que desees (por ejemplo, "Artículos")
// enganchar los filtros de traducción
add_filter('gettext','change_post_to_article');
add_filter('ngettext','change_post_to_article');
function change_post_to_article( $translated ) {
$translated = str_ireplace('Post','Artículo',$translated );// ireplace es solo para PHP5
return $translated;
}
Créditos a smashingmagazine.com

Eliminar el Elemento de Menú "Enlaces"
Muchas de mis instalaciones de WordPress no requieren que los usuarios tengan acceso al elemento de menú 'Enlaces'. Esta función lo elimina de la vista.
add_action( 'admin_menu', 'custom_admin_menu' );
function custom_admin_menu()
{
global $menu;
// var_dump($menu); // usa esto para identificar la clave del elemento de menú que deseas eliminar
unset( $menu[15] ); //la clave 15 corresponde a Enlaces
if ( !current_user_can('manage_options') ) { unset( $menu[75] ); } //la clave 75 corresponde a Herramientas ... pero solo para usuarios que no son super administradores
}

A partir de WP 3.1, también puedes usar remove_submenu_page
http://codex.wordpress.org/Function_Reference/remove_submenu_page

Desactivar el mensaje "Actualizar ahora" para usuarios no administradores
En realidad, no soy muy partidario de usar este código. Prefiero permitir que los clientes actualicen sus propias instalaciones de WordPress. Esto ayuda a mantener el sitio actualizado y me obliga a escribir mejor código.
if ( !current_user_can( 'manage_options' ) ) {
add_action( 'init', create_function( '$a', "remove_action( 'init', 'wp_version_check' );" ), 2 );
add_filter( 'pre_option_update_core', create_function( '$a', "return null;" ) );
}

Agregar automáticamente un campo personalizado oculto y un valor asociado a una publicación cuando se publica
add_action('publish_page', 'add_custom_field_automatically');
add_action('publish_post', 'add_custom_field_automatically');
function add_custom_field_automatically($post_ID) {
global $wpdb;
if(!wp_is_post_revision($post_ID)) {
add_post_meta($post_ID, 'field-name', 'custom value', true);
}
}

Añadir una clase personalizada a los enlaces de siguiente y anterior
add_filter('next_posts_link_attributes', 'posts_link_attributes');
add_filter('previous_posts_link_attributes', 'posts_link_attributes');
function posts_link_attributes(){
return 'class="styled-button"';
}

Añadir tipos de entradas personalizadas a la página de archivos
function namespace_add_custom_types( $query ) {
if( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
$query->set( 'post_type', array(
'post', 'tu-tipo-de-entrada-personalizada-aqui'
));
return $query;
}
}
add_filter( 'pre_get_posts', 'namespace_add_custom_types' );
