Лучшая подборка кода для вашего файла 'functions.php'
Как и многие другие, кто сейчас читает этот пост, я изучал различные блоги, форумы и дискуссионные группы, чтобы улучшить свои навыки работы с WordPress. В течение последних 12 месяцев я поставил себе цель заменить использование плагинов добавлением кода непосредственно в файл functions.php
.
Хотя я полностью согласен, что плагины очень полезны во многих ситуациях, мой опыт показал, что в 90% случаев использования, даже если плагин существует, его применение может создать ненужные сложности и проблемы совместимости. Кроме того, во многих случаях такие плагины добавляли меню и другие элементы администрирования, которые мне не нужны.
Чаще всего я обнаруживал, что, анализируя код плагинов, я мог выделить нужный мне фрагмент кода и жестко закодировать его в моем functions.php
. Это обеспечивало мне именно ту функциональность, которая мне нужна, без необходимости включать лишние элементы.
Итак, цель этого поста - попытаться привлечь вас, читателей/администраторов/разработчиков, поделиться со мной и другими любыми полезными фрагментами кода, которые вы добавили в файл functions.php
вашей темы для расширения или улучшения WordPress без использования плагинов.
Когда вы публикуете ответ, пожалуйста, дайте каждому фрагменту кода название, сообщите, с какой версией WordPress он совместим, включите описание, которое наилучшим образом описывает его функцию, и (если применимо) добавьте ссылку на оригинальный плагин или источник, где вы нашли информацию.
Я с нетерпением жду всех ваших ответов и, конечно же, буду постоянно добавлять свои новые находки, когда буду их обнаруживать.
Пожалуйста, голосуйте за вопрос и любые ответы, которые вы считаете полезными, нажимая на стрелку вверх слева от вопроса или ответа.

Автоматическое добавление изображений для шапки из указанной директории
В стандартной теме WordPress по умолчанию вы заметите дополнительное меню темы, которое активируется и позволяет выбрать изображение для шапки сайта. В коде стандартной темы эти изображения жёстко прописаны в файле functions.php. Приведённый ниже код позволяет WordPress автоматически подхватывать новые изображения из указанной директории, которую вы можете создать на сервере (или внутри папки вашей темы).
Код автоматически подключает все файлы с расширением .jpg или .jpeg. Каждое изображение должно иметь связанный файл миниатюры, который может быть просто копией оригинального изображения, но с другим именем, оканчивающимся на "-thumbnail". Имя файла используется как описание в настройках внешнего вида шапки, при этом подчёркивания автоматически заменяются пробелами. (например: My_Header_Image_A.jpg и My_Header_Image_A-thumbnail.jpg будут автоматически представлены с описанием "My Header Image 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 );
}

Отображение информации для авторизованных пользователей
if ( is_user_logged_in() ) {
}
не работает в файле functions.php. Вы можете использовать этот код:
if ( !function_exists('is_user_logged_in') ) :
function is_user_logged_in() {
$user = wp_get_current_user();
if ( $user->id == 0 ){
// Этот раздел выполняется, если пользователь не авторизован
} else {
// Этот раздел выполняется, если пользователь авторизован
}
}
endif;

if( !current_user_can('read') )
должен отлавливать гостей (т.е. неавторизованных пользователей) ..

Пользовательские логотипы для страницы входа и админки
/*-----------------------------------------------------------------------------------*/
/* Пользовательские логотипы
/*-----------------------------------------------------------------------------------*/
function custom_admin_logo() {
echo '
<style type="text/css">
#header-logo { background-image: url('.get_bloginfo('template_directory').'/path/to/images/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').'/path/to/images/login-logo.png) !important; }
</style>';
}
add_action('login_head', 'custom_login_logo');

Пожалуйста, ознакомьтесь с этим gist'ом. Там представлены даже лучшие варианты, чем показано в gist'е. Вы также можете попробовать поучаствовать в обсуждении тикета на trac (ссылка в заголовке плагина gist).

Удалить администратора (Пользователь #1) из списка пользователей
function your_pre_user_query($user_search) {
$user = wp_get_current_user();
if ($user->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);
}
}
add_action('pre_user_query','your_pre_user_query');

Еще раз: пользователь 1 может не быть администратором. Смотрите Роли и Возможности.

Это пример. Кроме того, в стандартных установках пользователь 1 является Администратором - первый созданный пользователь. Поэтому я и подчеркнул (Пользователь #1)

Это пример, показывающий, как не следует проверять административные возможности. Вы не должны использовать этот код на реальном сайте.

Именно. Этот код проверяет не возможности (capabilities), toscho, а конкретного пользователя. Этот код не имеет никакого отношения к возможностям, и я нигде не упоминал о возможностях. Я не вижу причин, почему это нельзя использовать на рабочих сайтах.

@Daniel Sachs Если вы ищете первого добавленного администратора, сначала проверьте роли всех пользователей, затем отсортируйте их по ID и возьмите первого. Как сказал @toscho: В текущем виде это "пример как не следует делать". Причины: а) настоящий администратор может не быть пользователем с наименьшим ID б) Если кто-то другой будет работать с этим, он/она не станет искать эту функциональность в теме.

Получение атрибутов заданной миниатюры
Используйте эту функцию в цикле для определения ширины, высоты и URL изображения-миниатюры. Очень полезно для назначения миниатюры в качестве фонового элемента через встроенный CSS.
/**
* ПОЛУЧЕНИЕ АТРИБУТОВ МИНИАТЮРЫ
*
* Получает ширину, высоту и URI миниатюры.
*
* @author Philip Downer <philip@manifestbozeman.com>
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version v1.0
*
* @param string $return Принимает 'path', 'width' или 'height'.
* @param string $size Размер миниатюры, соответствующий функции ядра WP {@link add_image_size()}.
* @return mixed Возвращает запрошенную информацию или 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

Вывод содержимого виджета за пределами сайдбара с использованием его ID. HTML-обёртка before/after не включается. Вам нужно знать конкретный ID виджета, который вам нужен (например, '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);
}
Вы можете посмотреть вывод функции wp_get_sidebars_widgets(), если не уверены в точном ID, который вам нужен.
Более полный пример, взятый из файла /wp-includes/widgets.php в функции 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);
}

Ох. Гораздо более простой способ — использовать the_widget()
http://codex.wordpress.org/Function_Reference/the_widget

Пользовательские смайлы (плагин)
/**
* Смайлы.
*/
function filter_smilies_src($img_src, $img, $siteurl) {
return plugins_url('', __FILE__) . '/img/smilies/' . $img;
}
add_filter('smilies_src', 'filter_smilies_src', 1, 10);
Пользовательские смайлы (тема)
/**
* Смайлы.
*/
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);

Перемещение WYSIWYG редактора с помощью JQUERY
Проверено на: WordPress 3.0.1
Этот код позволяет удалить определенные метабоксы, которые WordPress добавляет по умолчанию на экранах редактирования записей и страниц.
// ПЕРЕМЕЩЕНИЕ WYSIWYG РЕДАКТОРА С ПОМОЩЬЮ 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
}

Автоматическое закрытие отсутствующих тегов в визуальном редакторе
Проверено на: Wordpress 3.0.1
Этот код автоматически закрывает отсутствующие теги при использовании визуального редактора WYSIWYG.
// АВТОМАТИЧЕСКАЯ ОЧИСТКА HTML ИЗ ВИЗУАЛЬНОГО РЕДАКТОРА ПУТЕМ ЗАКРЫТИЯ ОТСУТСТВУЮЩИХ ТЕГОВ
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;
}

Хочу сообщить, что в самом WordPress есть возможность сделать это. Это может быть полезно, если нужно принудительно применить настройку для нескольких пользователей, независимо от их индивидуальных настроек. Однако я бы рекомендовал принудительно сохранять эту настройку.

Удаление атрибутов role="search"
для get_search_form()
// Функция для удаления атрибутов role из HTML-кода формы поиска
function remove_role_search($role)
{
$result = array();
// Находим все атрибуты role в HTML-коде
preg_match_all('|role="[^"]*"|U', $role, $result);
// Удаляем каждый найденный атрибут role
foreach ($result[0] as $role_tag) {
$role = str_replace($role_tag, '', $role);
}
return $role;
}
// Добавляем фильтр для функции get_search_form
add_filter('get_search_form', 'remove_role_search');

Добавление ссылки входа в wp_nav_menu
//ДОБАВЛЕНИЕ ССЫЛКИ ВХОДА/ВЫХОДА В МЕНЮ
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;
}

Изменение названия меню "Записи" в админке на любое другое (например, "Статьи")
// Подключаем фильтры перевода
add_filter('gettext','change_post_to_article');
add_filter('ngettext','change_post_to_article');
function change_post_to_article( $translated ) {
$translated = str_ireplace('Post','Article',$translated ); // ireplace работает только в PHP5
return $translated;
}
Автор: smashingmagazine.com

Удаление пункта меню "Ссылки"
Во многих моих установках WordPress пользователям не нужен доступ к пункту меню "Ссылки". Эта функция скрывает его из вида.
add_action( 'admin_menu', 'custom_admin_menu' );
function custom_admin_menu()
{
global $menu;
// var_dump($menu); // используйте это для определения ключа нужного пункта меню
unset( $menu[15] ); // ключ 15 - это ссылки
if ( !current_user_can('manage_options') ) { unset( $menu[75] ); } // ключ 75 - инструменты ... но только для неадминистраторов
}

Начиная с WP 3.1, вы также можете использовать remove_submenu_page
http://codex.wordpress.org/Function_Reference/remove_submenu_page

Отключение сообщения "Обновить сейчас" для пользователей без прав администратора
Честно говоря, я не большой поклонник использования этого кода. Вместо этого я предпочитаю позволять клиентам самостоятельно обновлять их WordPress. Это помогает поддерживать сайт в актуальном состоянии и заставляет меня писать более качественный код.
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;" ) );
}

Автоматическое добавление скрытого пользовательского поля и связанного значения к записи при публикации
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);
}
}

Использование bloginfo через шорткод...
function digwp_bloginfo_shortcode($atts) {
extract(shortcode_atts(array(
'key' => '',
), $atts));
return get_bloginfo($key);
}
add_shortcode('bloginfo', 'digwp_bloginfo_shortcode');
Использование:
[bloginfo key='name']

Добавление пользовательского класса к ссылкам "Следующая" и "Предыдущая"
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"';
}

Добавление пользовательских типов записей на страницу архивов
function namespace_add_custom_types( $query ) {
if( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
$query->set( 'post_type', array(
'post', 'your-custom-post-type-here' // замените на ваш пользовательский тип записи
));
return $query;
}
}
add_filter( 'pre_get_posts', 'namespace_add_custom_types' );
