Пользовательские правила местоположения

Введение

Правила местоположения используются для определения, какие группы полей отображаются на каком экране админки. Они задаются при редактировании группы полей и состоят из типа расположения, оператора сравнения и значения.

Одним из примеров правила местоположения будет «Тип записи == Запись».


Метабокс расположения группы полей
Метабокс расположения группы полей

Плагин Advanced Custom Fields включает разнообразный набор типов расположения, чтобы удовлетворить потребности большинства сайтов. Кроме того, можно определить дополнительные типы расположения, чтобы реализовать собственную логику размещения группы полей.

В этом руководстве мы пройдём через процесс создания и регистрации пользовательского типа расположения.

Требования

Класс ACF_Location, упомянутый в этом руководстве, требует версии 5.9.0 или выше. Если у вас ещё не установлена эта версия, обновитесь, чтобы воспользоваться этой замечательной возможностью!

Тем, кто использует предыдущую версию, вместо этого подойдёт это руководство.

Начало работы

Чтобы создать пользовательский тип расположения, достаточно расширить класс ACF_Location и некоторые его методы. Затем зарегистрируйте его с помощью функции acf_register_location_type().

Ниже приведён упрощённый пример пользовательского типа расположения, который при выборе будет случайным образом показывать группу полей в 50% случаев.

class My_Location extends ACF_Location {
    function initialize() {
        $this->name = '50_50';
        $this->label = __( 'Пятьдесят на пятьдесят' );
    }
    function match() {
        return rand( 0, 1 );
    }
}
acf_register_location_type( 'My_Location' );

ACF_Location

Класс ACF_Location содержит несколько свойств и методов, и не все из них нужно настраивать. Прежде чем переходить к рабочему примеру, ознакомьтесь с доступными свойствами и методами ниже.

Свойства

  • name
    (String) Уникальное имя, которое идентифицирует тип расположения. Например, ‘post_author’.
    Имя типа расположения может содержать только строчные буквенно-цифровые символы и подчёркивания.

    $this->name = 'post_author';
  • label
    (String) Отображаемая метка для вашего типа расположения, которая показывается при редактировании группы полей. Например, ‘Автор записи’.

    $this->label = __('Автор записи');
  • category
    (String) (Необязательно) Группа, в которой этот тип расположения отображается в выпадающем списке типов расположения.
    Принимает «post», «page», «user», «forms» или пользовательскую метку. По умолчанию — «post».

    $this->category = 'post';
  • public
    (Bool) (Необязательно) Доступно ли правило местоположения для публичного выбора. По умолчанию — true.

    $this->public = true;
  • object_type
    (String) (Необязательно) Тип объекта, связанный с этим расположением.
    Принимает тип объекта, определяемый с помощью acf_get_object_type(), например «post», «user», «block» и т. д. Если задать это свойство, ACF сможет показывать значок в колонке таблицы групп полей в админке. По умолчанию используется пустая строка, обозначающая «Разное».

    $this->object_type = 'post';

Методы

  • initialize
    Вызывается во время регистрации для инициализации свойств.

    public function initialize() {
        $this->name = 'post_author';
        // Здесь определите все остальные свойства.
    }
  • match
    Сравнивает переданное правило местоположения с аргументами текущего экрана и возвращает true при совпадении.
    Если вернуть true, группа полей будет отображаться на текущем экране. Если вернуть false, группа полей не будет отображаться на текущем экране.

    public function match( $rule, $screen, $field_group ) {
        return false;
    }
  • get_operators
    (Необязательно) Возвращает массив операторов, из которых можно выбрать при редактировании правила.
    Если этот метод не указан, будут использоваться операторы по умолчанию — «равно» и «не равно».

    public function get_operators( $rule ) {
        return array(
            '==' => __( "равно" ),
            '!=' => __( "не равно" )
        );
    }
  • get_values
    (Необязательно) Возвращает массив возможных значений, из которых можно выбрать при редактировании правила.

    public function get_values( $rule ) {
        return array(
            'foo' => 'Foo',
            'bar' => 'Bar'
        );
    }
  • get_object_subtype
    (Необязательно) Подобно свойству object_type, этот метод позволяет ACF показывать более точный значок в столбце таблицы групп полей в админке.
    Возвращает один или несколько подтипов, связанных с этим расположением.
    Допустимые подтипы объектов включают типы записей и таксономии. По умолчанию — пустая строка.

    public function get_object_subtype( $rule ) {
        return 'category';
    }

Пример

Давайте на практике используем эти свойства и методы и создадим пользовательский тип расположения под названием «Автор записи». Этот тип расположения позволит группе полей отображаться при редактировании записи на основе атрибута автора записи.

1. Настройка

Наша первая задача — определить новый класс ACF_Location, используя метод initialize() для настройки свойств типа расположения. В этом примере мы будем работать в файле темы includes/class-my-acf-location-post-author.php.

includes/class-my-acf-location-post-author.php

<?php 

if( ! defined( 'ABSPATH' ) ) exit;

class My_ACF_Location_Post_Author extends ACF_Location {

    public function initialize() {
        $this->name = 'post_author';
        $this->label = __( "Автор записи", 'acf' );
        $this->category = 'post';
        $this->object_type = 'post';
    }
}

Далее подключим и зарегистрируем этот тип расположения из файла functions.php.

functions.php

add_action('acf/init', 'my_acf_init_location_types');
function my_acf_init_location_types() {

    // Проверяем, существует ли функция, затем подключаем и регистрируем класс пользовательского типа расположения.
    if( function_exists('acf_register_location_type') ) {
        include_once( 'includes/class-my-acf-location-post-author.php' );
        acf_register_location_type( 'My_ACF_Location_Post_Author' );
    }
}

Готово 🎉. Теперь можно редактировать группу полей и выбрать новый тип расположения.


Скриншот выбора типа правила местоположения «Автор записи»
Выбор типа правила местоположения «Автор записи»

2. Настройка выпадающих списков

Теперь, когда наш пользовательский тип расположения зарегистрирован, мы можем заняться настройкой выпадающих списков operator и value — двух параметров, которые отображаются рядом с выбранным типом расположения.

В этом примере мы оставим выпадающий список operator без изменений: он будет показывать значения по умолчанию — «равно» (==) и «не равно» (!=). А вот выпадающий список value мы настроим так, чтобы он отображал список всех возможных пользователей.

Функция WordPress get_users() делает эту задачу довольно простой. Следующий фрагмент заполнит массив вариантов, используя ID пользователя в качестве значения опции и отображаемое имя пользователя в качестве метки опции.

includes/class-my-acf-location-post-author.php

public function get_values( $rule ) {
    $choices = array();

    // Загружаем всех пользователей, перебираем их и добавляем в choices.
    $users = get_users();
    if( $users ) {
        foreach( $users as $user ) {
            $choices[ $user->ID ] = $user->display_name;
        }
    }
    return $choices;
}

Наш пользовательский тип расположения начинает обретать форму! Теперь можно создать правило местоположения «Автор записи == Эллиот» 🙌.


Скриншот выбора значения правила местоположения «Автор записи»
Выбор значения правила местоположения «Автор записи»

Наконец, нам нужно определить логику, которая сравнивает правило, например «Автор записи == Эллиот», с текущим экраном.

3. Расчёт совпадения

При просмотре экрана редактирования WordPress Advanced Custom Fields вычисляет, какие группы полей отображаются, на основе их правил местоположения. Для каждого типа правила местоположения проверяется, совпадает ли правило с аргументами текущего экрана.

Логика такого «сопоставления» задаётся в методе match(). Этот метод принимает 3 параметра: условия правила, аргументы текущего экрана, а также группу полей, чья видимость вычисляется. Всё, что требуется от этого метода, — вернуть логическое значение, отражающее результат сопоставления.

В этом примере мы сравним выбранное значение правила (ID пользователя) с атрибутом автора записи. Также нужно помнить, что этот тип расположения имеет значение только при редактировании записи, а не пользователя, термина, виджета и т. д.

includes/class-my-acf-location-post-author.php

public function match( $rule, $screen, $field_group ) {

    // Проверяем аргументы экрана на наличие «post_id», который будет присутствовать при редактировании записи.
    // Для всех остальных экранов редактирования возвращаем false.
    if( isset($screen['post_id']) ) {
        $post_id = $screen['post_id'];
    } else {
        return false;
    }

    // Загружаем объект записи для этого экрана редактирования.
    $post = get_post( $post_id );
    if( !$post ) {
        return false;
    }

    // Сравниваем атрибут автора записи со значением правила.
    $result = ( $post->post_author == $rule['value'] );

    // Возвращаем результат с учётом типа оператора.
    if( $rule['operator'] == '!=' ) {
        return !$result;
    }
    return $result;
}

Поздравляем 🎉 Тип расположения «Автор записи» теперь полностью готов! Группа полей, использующая этот тип расположения, будет отображаться только при редактировании записи, у которой автор — «Эллиот».


Тип расположения «Автор записи» корректно совпадает с правилом «Автор записи == Эллиот»
Тип расположения «Автор записи» корректно совпадает с правилом «Автор записи == Эллиот»

Полный код

Для справки ниже приведён полный код, написанный для пользовательского типа расположения «Автор записи».

includes/class-my-acf-location-post-author.php

<?php 

if( ! defined( 'ABSPATH' ) ) exit;

class My_ACF_Location_Post_Author extends ACF_Location {

    public function initialize() {
        $this->name = 'post_author';
        $this->label = __( "Автор записи", 'acf' );
        $this->category = 'post';
        $this->object_type = 'post';
    }

    public function get_values( $rule ) {
        $choices = array();

        // Загружаем всех пользователей, перебираем их и добавляем в choices.
        $users = get_users();
        if( $users ) {
            foreach( $users as $user ) {
                $choices[ $user->ID ] = $user->display_name;
            }
        }
        return $choices;
    }

    public function match( $rule, $screen, $field_group ) {

        // Проверяем аргументы экрана на наличие «post_id», который будет присутствовать при редактировании записи.
        // Для всех остальных экранов редактирования возвращаем false.
        if( isset($screen['post_id']) ) {
            $post_id = $screen['post_id'];
        } else {
            return false;
        }

        // Загружаем объект записи для этого экрана редактирования.
        $post = get_post( $post_id );
        if( !$post ) {
            return false;
        }

        // Сравниваем атрибут автора записи со значением правила.
        $result = ( $post->post_author == $rule['value'] );

        // Возвращаем результат с учётом типа оператора.
        if( $rule['operator'] == '!=' ) {
            return !$result;
        }
        return $result;
    }
}

functions.php

add_action('acf/init', 'my_acf_init_location_types');
function my_acf_init_location_types() {

    // Проверяем, существует ли функция, затем подключаем и регистрируем класс пользовательского типа расположения.
    if( function_exists('acf_register_location_type') ) {
        include_once( 'includes/class-my-acf-location-post-author.php' );
        acf_register_location_type( 'My_ACF_Location_Post_Author' );
    }
}

Итоги

Класс ACF_Location значительно упрощает создание пользовательских правил местоположения. Всего за несколько строк кода мы смогли:

  • зарегистрировать новый тип расположения, который можно выбрать в правилах местоположения группы полей;
  • настроить значения, отображаемые в выпадающем списке value для правила местоположения;
  • определить, совпадает ли правило с текущим экраном редактирования.

Обновлено: 01.06.2026