
Локальный аватар WordPress через ACF: единое фото автора без Gravatar
Как добавить выбор фотографии в профиль через ACF, хранить аватар в медиатеке и использовать его в статьях, постах и комментариях через стандартный API WordPress.

В WordPress фотография автора часто приходит из Gravatar, а в боковой панели может быть выбрана вручную. В результате у одного человека на сайте появляются разные изображения: одно в статье, другое в комментариях, третье в блоке «Об авторе».
Покажу, как хранить аватар в собственной медиатеке, выбирать его в профиле через ACF и передавать стандартному механизму аватаров WordPress. Настройка фотографии останется в админке, а небольшой PHP-модуль — в дочерней теме. Отдельный плагин для аватаров и CSS для подмены картинки не понадобятся.
Локальный Gravatar и собственный аватар — разные задачи
В Blocksy есть настройка Внешний вид → Настроить → Производительность → Локальные Gravatar’ы. Она кэширует изображения Gravatar на сервере сайта. Это полезная функция, но она не добавляет в профиль выбор произвольной фотографии из медиатеки. Подробности есть в документации Blocksy по производительности.
В нашем варианте пользователь выбирает локальное изображение сам. WordPress получает его URL через свой API аватаров. Поэтому темы и плагины, которые пользуются этим API, смогут показывать выбранную фотографию без отдельной правки каждого шаблона.
Что понадобится
- Установленный ACF. Для поля «Изображение» не требуются возможности ACF Pro.
- Активная дочерняя тема и доступ к её файлам. В примере используется Blocksy Child.
- Фотография в медиатеке. Для небольшого аватара обычно достаточно квадратного изображения 512 × 512 px; это практический размер для примера, а не требование WordPress.
- Резервная копия изменяемых файлов перед подключением PHP-модуля.
Родительскую тему редактировать не нужно: её обновление может перезаписать изменения. Название папки дочерней темы на другом сайте может отличаться от blocksy-child.
Шаг 1. Создайте файл user-avatar.php
Внутри дочерней темы создайте папку inc, если её ещё нет. В ней создайте файл user-avatar.php. Полный путь в этом примере:
wp-content/themes/blocksy-child/inc/user-avatar.php Вставьте в файл следующий код. Первая часть регистрирует поле ACF в профиле пользователя. Вторая определяет владельца аватара и возвращает выбранное изображение стандартному API WordPress.
<?php
/**
* Локальный аватар пользователя: поле ACF и стандартный API аватаров WordPress.
* Изображение выбирается в профиле из медиатеки, без Gravatar и отдельных сниппетов.
*/
if ( ! defined( 'ABSPATH' ) ) { exit; }
add_action( 'acf/init', function () {
if ( ! function_exists( 'acf_add_local_field_group' ) ) { return; }
acf_add_local_field_group( array(
'key' => 'group_wml_local_avatar',
'title' => 'Локальный аватар',
'fields' => array( array(
'key' => 'field_wml_local_avatar',
'label' => 'Аватар на сайте',
'name' => 'wml_local_avatar',
'type' => 'image',
'instructions' => 'Единое изображение профиля для статей, постов, кейсов и комментариев. Выберите файл из медиатеки. Если удалить выбор, вернётся стандартный аватар.',
'return_format' => 'id',
'preview_size' => 'thumbnail',
'library' => 'all',
'mime_types' => 'jpg,jpeg,png,gif,webp',
'required' => 0,
) ),
'location' => array( array( array(
'param' => 'user_form',
'operator' => '==',
'value' => 'all',
) ) ),
'active' => true,
) );
} );
/** Resolve only recognised WordPress avatar identities, preserving other users. */
function wml_local_avatar_user_id( $identity ) {
if ( $identity instanceof WP_User ) {
return (int) $identity->ID;
}
if ( $identity instanceof WP_Post ) {
return (int) $identity->post_author;
}
if ( $identity instanceof WP_Comment ) {
if ( $identity->user_id ) { return (int) $identity->user_id; }
$identity = $identity->comment_author_email;
}
if ( is_int( $identity ) || ( is_string( $identity ) && ctype_digit( $identity ) ) ) {
return absint( $identity );
}
if ( is_string( $identity ) && is_email( $identity ) ) {
$user = get_user_by( 'email', $identity );
return $user ? (int) $user->ID : 0;
}
return 0;
}
/* The early hook avoids an unnecessary Gravatar request for a local image.
* Reading the stored attachment ID also works if ACF is temporarily inactive. */
add_filter( 'pre_get_avatar_data', function ( $args, $identity ) {
$user_id = wml_local_avatar_user_id( $identity );
if ( ! $user_id || ! empty( $args['force_default'] ) ) { return $args; }
$image_id = absint( get_user_meta( $user_id, 'wml_local_avatar', true ) );
if ( ! $image_id || ! wp_attachment_is_image( $image_id ) ) { return $args; }
$url = wp_get_attachment_image_url( $image_id, 'full' );
if ( ! $url ) { return $args; }
$args['url'] = $url;
$args['found_avatar'] = true;
return $args;
}, 10, 2 );
Поле хранит ID вложения, а не вручную записанный адрес файла. URL берётся из медиатеки. Если изображение не выбрано, удалено или не является картинкой, модуль возвращает управление обычному механизму аватаров. Другим пользователям он не назначает вашу фотографию.
Обработка учитывает ID пользователя, объект пользователя, автора записи, объект комментария и email зарегистрированного пользователя. Это важно: разные части WordPress передают владельца аватара в разных форматах. Хеш email в этом примере не сопоставляется с пользователем.
Шаг 2. Подключите файл в functions.php
Откройте functions.php активной дочерней темы и добавьте подключение после открывающего <?php, вне других функций. Если PHP-файл уже открыт, повторно вставлять тег <?php не нужно.
require_once get_stylesheet_directory() . '/inc/user-avatar.php'; Модуль должен существовать до добавления этой строки. Не заменяйте весь functions.php примером: в нём могут находиться другие функции сайта. require_once подключит модуль один раз.
Шаг 3. Выберите фотографию в профиле
- Откройте Пользователи → Профиль. Для другого автора откройте редактирование его пользователя, имея соответствующие права.
- Найдите группу «Локальный аватар» и поле «Аватар на сайте».
- Нажмите «Добавить изображение» и выберите файл в медиатеке.
- Нажмите «Обновить профиль».
Если медиатека разбита на папки, проверьте выбранную папку перед поиском. Например, фотография может находиться в «Мои фото», а диалог открытия изображения помнить папку «Мои лого». Переключение на «Все файлы» поможет найти уже загруженный оригинал.
Не загружайте ту же фотографию заново, если она уже есть в библиотеке. Одинаковые названия сами по себе ещё не доказывают, что это один файл: сравните изображения и их использование перед удалением лишнего вложения.
Где редактировать поле и где хранится его значение
Фотографию меняем в профиле пользователя. Определение поля находится в inc/user-avatar.php. Поскольку группа зарегистрирована через PHP, она не редактируется как обычная группа в разделе ACF → Группы полей. Для изменения названия или инструкции откройте модуль. Не создавайте параллельно такую же группу с теми же ключами.
ACF сохраняет выбранное вложение в пользовательских метаданных wml_local_avatar. При выводе модуль читает ID стандартной функцией get_user_meta(). Поэтому сохранённая фотография продолжит выводиться при временном отключении ACF, пока активна дочерняя тема и доступно вложение. Само поле выбора при отключённом ACF исчезнет.
Почему используется pre_get_avatar_data
Фильтр pre_get_avatar_data позволяет вернуть URL изображения до стандартного определения адреса Gravatar. Мы устанавливаем url и признак found_avatar. WordPress продолжает формировать HTML аватара своими средствами.
Это функциональная подмена источника фотографии, а не маскировка старой картинки через CSS. Здесь нет привязки к конкретному номеру пользователя или ID изображения: каждый пользователь получает собственное сохранённое значение. Параметр force_default намеренно сохраняет стандартное поведение, если вызывающий код явно просит изображение по умолчанию.
Что проверить после настройки
- Метаданные статьи и поста: выбранная фотография должна появиться рядом с именем автора, если тема выводит аватар.
- Блок автора и страницу автора.
- Существующие комментарии этого пользователя, если комментарии показывают аватары. Тестовый комментарий публиковать ради проверки необязательно.
- Административную панель и другие места, использующие стандартные аватары WordPress.
- Телефон, планшет, светлую и тёмную тему: пропорции картинки и её контейнер должны остаться прежними.
Откройте сайт также как гость. Если используется HTML-кэш, старая фотография может оставаться в уже сохранённых страницах. После изменения очистите затронутый кэш и проверьте свежую страницу.
Если в сайдбаре осталась другая фотография
Модуль действует на стандартные функции аватаров WordPress. Обычный блок «Изображение» с вручную выбранной фотографией не станет динамическим автоматически. То же относится к внешним сервисам и плагинам, которые используют собственный механизм фотографий.
В Blocksy блок About Me поддерживает динамическую информацию пользователя и отдельный произвольный профиль. Для единого источника выберите динамического пользователя. Если сохраняете вручную собранный блок, назначьте ему тот же файл и учитывайте, что при следующей смене фотографии такой блок нужно обновить отдельно.
Как отменить изменение
Чтобы вернуть обычный аватар одному пользователю, удалите выбор в поле «Аватар на сайте» и обновите профиль. Сам файл из медиатеки для этого удалять не нужно.
Чтобы полностью убрать модуль, сначала удалите строку подключения из functions.php, затем удалите inc/user-avatar.php. Обратный порядок приведёт к ошибке подключения отсутствующего файла. Сохранённые пользовательские данные при этом автоматически не удаляются.
Документация

