WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

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

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

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

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

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

Спасибо.

3
Гость
4.1 года назад
  • 2
    Kama7294

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

    Для этого используем хук 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 );
    		}
    	}
    }
    Анна 4 года назад

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

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

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

    Kama 4 года назад

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

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

    Анна 4 года назад

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

    Kama 4 года назад
    //$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, обычно это первый созданный термин.

    анна 4 года назад

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

    анна 4 года назад

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

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

    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

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