WordPress как на ладони
wordpress jino

Элемент произвольной таксономии по умолчанию для записи, если элемент не установлен

Добрый день подскажите пожалуйста как реализовать автоматическое присвоение кастомного терма, созданного для произвольной таксономии для произвольного типа записи?

Т.е. у стандартной категории можно выбрать основную рубрику! А как сделать так что бы у пользовательской таксономии можно было сделать так же!

Кастомная таксономия и кастомный тип поста у меня уже есть. А вот автоматом присваивать им терм пока не получается. Мне нужен механизм тот же что и в стандартный постах, когда им присваивается категория uncategorized по умолчанию.

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

Спасибо.

3
Гость 2.9 года назад
  • 1
    Kama4659

    Можно при сохранении записи проверять присвоен ли термин, если нет то присвоить.

    Для этого используем хук save_post, функцию wp_set_object_terms() и функцию has_term():

    ## Устанавливаем элемент таксономии по умолчанию, если для записи элемент не установлен
    if( is_admin() ){
    	add_action( 'save_post', 'set_faq_default_cat', 11, 2 );
    	function set_faq_default_cat( $post_id, $post ) {
    		$post_type = 'faq'; // наш тип поста
    		$tax       = 'faqcat';       // наша пользовательская таксономия
    		//$def_term  = 5;  // ID термина который нужно установить по умолчанию.
    
    		// выходим, если это не нужный нам тип поста.
    		if ( $post_type != $post->post_type ) return;
    
    		// Проверяем и обновляем термин если нужно
    		if( ! has_term('', $tax, $post ) ){
    			// Получим дефолтный термин динамически: термин с меньшим ID в таксономии (первый созданный термин).
    			if( ! ($def_term = get_option("default_$tax")) || ! get_term($def_term) ){
    				$terms = get_terms( $tax, 'orderby=id&order=ASC');
    				$def_term = array_shift( $terms )->term_id;
    			}
    
    			wp_set_object_terms( $post->ID, $def_term, $tax );
    		}
    	}
    }

    Добавлять этот хук нужно в файл темы functions.php или в файл плагина или как-либо еще.

    Другой способ через опции WP:

    Есть способ установить дефолтный элемент таксономии, который НЕвозможно будет удалить через админ-панель.

    В классе WP_Terms_List_Table есть такая строка

    get_option( 'default_' . $this->screen->taxonomy )

    Поэтому, если у вас есть таксономия "genre", вам нужно установить опцию default_genre со значением ID дефолтного элемента таксономии. Такой элемент будет защищен от удаления его через админ-панель.

    Весь код, который создает опцию и хук для добавления записи в таку, если для нее не указана ни одна такса:

    ## Устанавливаем элемент таксономии по умолчанию, создаем опцию
    if( is_admin() ){
    
    	add_action( 'wp_loaded', function(){
    		$taxonomy = 'product_cat';
    
    		$term_id = get_option( "default_{$taxonomy}" );
    
    		if ( ! $term_id ){
    			$term = get_term_by( 'name', 'Без рубрики', $taxonomy );
    			$term_id = $term ? $term->term_id : 0;
    			update_option( "default_{$taxonomy}", $term_id );
    		}
    
    	} );
    
    }
    
    ## Устанавливаем элемент таксономии по умолчанию если для записи не указан ни один элемент таксы
    add_action( 'save_post', 'set_default_product_cat', 11, 2 );
    function set_default_product_cat( $post_id, $post ) {
    	$taxonomy  = 'product_cat';
    	$post_type = 'product';
    
    	// выходим, если это не нужный нам тип поста.
    	if( $post_type != $post->post_type ) return;
    
    	$def_term_id = get_option( "default_$taxonomy" );
    	if( ! $def_term_id ) return;
    
    	// Проверяем и обновляем термин если нужно
    	if( ! has_term('', $taxonomy, $post ) ){
    		// убедимся что термин существует
    		if( $def_term = get_term( $def_term_id ) ){
    			wp_set_object_terms( $post->ID, intval($def_term_id), $taxonomy );
    		}
    	}
    }
    Анна 2.8 года назад

    Огромное спасибо за Ваш ответ!

    Правда так как мне было нужно он в чистом виде корректно не отрабатывал. А именно функция get_id_of_first_term возвращала пустое значение и соответственно предполагаемый дефолтный терм не присваивался (это в условиях отсутствия постов кастомного типа и одного созданного мной в отдельной функции терма, который предполагалось использовать в качестве дефолтного ).

    Зато после первого присвоения предполагаемого дефолтного терма посту кастомного типа в ручном режиме - создавался новый терм с номером id, следующим по счету, после созданного мною в отдельной функции, а название и слаг для нового терма брались из моего существущего терма (предполагаемого дефолтного). И всем следующим создающимся постам присваивался по умолчанию этот новый терм. Плюс к этому на экране создания первого поста кастомного типа (т.е. еще нет присвоения терма к посту) выводилось предупреждающее сообщение след. текстовки: Notice: Trying to get property of non-object in ....(адрес в моему файлу на ПК и номер вот этой строки $term_id = $fterm->term_idwink.

    В связи с этим пришлось немного изменить код и вот что в итоге работает отлично(может кому-то пригодится такая вариация на тему):

    add_action( 'save_post', 'my_set_default_term', 11, 2 );
    function my_set_default_term( $post_id, $post ) {
    	$post_type = 'my_post_type';
    	$tax       = 'my_tax';
    	$def_term  = 'standart';
    	if ( $post_type != $post->post_type ) return; // выходим, если это не нужный нам тип поста.
    	if( ! has_term( '', $tax, $post ) ) { // Проверяем и обновляем термин если нужно
    		wp_set_object_terms( $post->ID, $def_term, $tax );
    	}
    }
    Анна 2.8 года назад

    Добрый вечер! Сейчас возникла необходимость создавать дефолтный терм именно по id. Т.к. Вы и предлагали. Но когда я указываю значение для переменной $def_term='standart', функция отрабатывает, а если пишу $def_term=5 - не работает. Дефолтный терм не создается и соответственно не присваивается. Подскажите пожалуйста как это исправить? Спасибо!

    Kama 2.8 года назад

    Создавать термин по ID, это как?

    Можно задавать по id или создавать указывая название. Как бы то ни было, ищите ответ в описании wp_set_object_terms()

    Анна 2.8 года назад

    так как в четвертой строке Вашего кода. Вы ведь там пишите значение id для дефолтного терма.
    Спасибо за ссылку. Но я ее уже изучала. Поскольку в вордпресе новичок, то ответа не нашла.

    Kama 2.8 года назад
    //$def_term  = 5;  // ID термина который нужно установить по умолчанию. 
    	$def_term  = get_id_of_first_term( $tax ); // Получим дефолтный термин динамически: термин с меньшим ID в таксономии (первый созданный термин).

    Тут в $def_term = 5; значит что у вас уже существует термин с ID 5
    А в $def_term = get_id_of_first_term( $tax ); термин получается автоматически: термин с наименьшим ID, обычно это первый созданный термин.

    анна 2.8 года назад

    Спасибо Вам за Ваше участие. Все понятно.

    анна 2.8 года назад

    Пожалуйста помогите еще в одной проблеме. Мне нужно чтобы этот дефолтный терм, который был присвоен всем постам, нельзя было удалить. Как рубрику uncategoriezed в постах. Я вот такой код использую, но он не рабочий. Не могу понять, что делаю не так(пробовала еще и другие хуки из функции wp_delete_term):

    function abc($term_id) {    
    	if($term_id == 56){     
    		return 0;       
    	}   
    }
    add_action( 'pre_delete_term', 'abc');
    Kama 2.8 года назад

    return 0; просто ничего не делает, вам нужно оборвать скрипт:

    function abc($term_id) {
    	if( $term_id == 56 )
    		wp_die('cant delete');
    }
    add_action( 'pre_delete_term', 'abc');

    Вот еще ссылки по теме нашел: http://wordpress.stackexchange.com/questions/70758/multisite-protect-categories-from-deletion (англ)

    И вот еще, как указать элемент таксономии по умолчанию, который нельзя удалить (тоже англ): http://wordpress.stackexchange.com/questions/158784/creating-a-non-removable-taxonomy-term

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Регистрация. Вход.