Intereting Posts
Я хочу создать виджет сообщений и иметь возможность выбирать категории Отображение пользовательских типов сообщений по категориям отображать категорию список год мудрый в wordpress Удалить тег короткой ссылки с определенной страницы Отобразить список страниц, содержащих определенную строку в пуле Пользователи не могут публиковать сообщения, когда редактор или администратор на нескольких сайтах на нескольких сайтах Разбивка страниц: держите предыдущую и следующую ссылку даже на первой / последней странице Доступ к многопользовательскому входному файлу WordPress Исключать изображения из «вставленных в сообщение» при попытке получить вложения Добавьте новую страницу подтверждения перед сохранением Такая структура постоянной позиции для всех типов сообщений? Используйте отдельный шаблон только для домашней страницы. Элегантный способ включения только опубликованных сообщений с get_objects_in_term ()? Пользовательская форма входа для пользователя-пользователя, а также администратора Проверить post_date в pre_get_posts

Мастер-сайт для конкретной таксономии в MultiSite

Я хочу создать таксономию «города» на всех сайтах MultiSite. Но я хочу показать один и тот же список в каждом блоге, и я хочу отредактировать его только с мастер-сайта и не позволять другим владельцам блога редактировать его. Я думаю, что только решение для этого – установка мастер-сайта для конкретной таксономии в MultiSite. Поэтому, когда кто-то пытается использовать таксономию «города» из других блогов, он увидит список городов-хозяев. Как я могу это сделать?

<?php $master_site = 1; ...when city taxonomy need: switch_to_blog( $master_site ); ...use list of "city" taxonomy"... restore_current_blog(); 

Solutions Collecting From Web of "Мастер-сайт для конкретной таксономии в MultiSite"

Сначала, когда вы регистрируете свою пользовательскую таксономию, используйте аргумент возможностей и определите свои пользовательские возможности:

 'capabilities' => array( 'manage_terms' => 'manage_cities', 'edit_terms' => 'edit_cities', 'delete_terms' => 'delete_cities', 'assign_terms' => 'assign_cities' ), 

и только предоставить вашим пользователям assign_terms таким образом, они не смогут создавать новые термины, только ВЫ.

Затем используйте хорошее решение, которое вы указали в комментарии, измените массив $taxonomies_to_sync соответствии с вашей таксономией, и все будет в порядке.

(отказ от ответственности: это связано с основным взломом WP, протекторам)

У меня есть сеть Multisite, где я хотел, чтобы основной блог (id == 1) устанавливал таксономию activity_type для всех других сайтов в сети.

Я использовал приведенный ниже код для включения перехватов при создании, редактировании или удалении терминов в этой пользовательской таксономии, которая затем имитирует эту задачу на всех дочерних элементах. То, что здесь не рассматривается, – это ограничение пользователей на других сайтах от добавления / редактирования / удаления терминов. Я использовал комбинацию функций jQuery, CSS и remove_action чтобы скрыть эти элементы пользовательского интерфейса от моих подсайтов.

 //When an activity type is added to the primary site, also add it to the sub-sites function as_act_type_add ($term_id, $tt_id, $taxonomy){ $new_act_type = get_term($term_id, 'activity_type', ARRAY_A); //get parent data if necessary $parent_term = get_term_by('term_id', $new_act_type['parent'], 'activity_type', ARRAY_A); $sites = as_network_ids(); foreach($sites as $site){ switch_to_blog($site); $exist_check = term_exists($new_act_type['name'], 'activity_type'); //check if the created term exists on the subsite already $site_parent = term_exists( $parent_term['name'], 'activity_type' ); //check if the parent term exists $parent_term_id = $site_parent['term_id']; // get numeric term id if(is_array($exist_check)){ //do nothing - in the future, we want this to update the existing term but punt for now } else { wp_insert_term( $new_act_type['name'], // the term 'activity_type', // the taxonomy array( 'description'=> $new_act_type['description'], 'slug' => $new_act_type['slug'], 'parent' => $parent_term_id ) ); //since we might have added children, you have to delete the cache, or else they wont display right away delete_option("activity_type_children"); } //end term_exists restore_current_blog(); } //end foreach //and delete cache for main site delete_option("activity_type_children"); } //triggered whenever a term is added add_action("create_activity_type", "as_act_type_add", 10, 3); function as_act_type_update($term_id, $tt_id, $taxonomy){ //the term hasnt been changed yet, but we want to get it anyway in case the name has been changed $legacy_term = get_term($term_id, 'activity_type', ARRAY_A); $edited_act_type = $_POST; if($edited_act_type['parent']){ $parent_term = get_term_by('term_id', $edited_act_type["parent"], 'activity_type', ARRAY_A); } $sites = as_network_ids(); foreach($sites as $site){ switch_to_blog($site); //cehck to see if the updated term exists on the site $exist_check = term_exists($legacy_term['name'], 'activity_type'); if($parent_term){ //check to make sure we have the parent $site_parent_term = term_exists($parent_term['name'], 'activity_type'); } //if so, update it if(is_array($exist_check)){ //since wp_update_term calls the edit_term hook, we need to unhook to avoid an infinite loop remove_action("edit_activity_type", "as_act_type_update", 10, 3); //update that fool wp_update_term( $exist_check['term_id'], // the term id 'activity_type', // the taxonomy array( 'name' => $edited_act_type['name'], 'description' => $edited_act_type['description'], 'slug' => $edited_act_type['slug'], 'parent' => $site_parent_term['term_id'] //if this doesnt exist, WP will default to 0, or no parent ) ); } //end is_array check restore_current_blog(); } //end foreach } //end update term func add_action("edit_activity_type", "as_act_type_update", 10, 3); function as_act_type_delete($term_id, $tt_id, $taxonomy){ //somehow this also works with bulk delete- I didnt think it would but apprarently it does. sacrificial goat must have worked. $deleted_act_type = get_site_transient( 'as_last_activity_type_delete' ); //temp transient set in wp-includes/taxonomy.php to store deleted term data if ( false === ( $deleted_act_type)) { //do nothing if no transient available } else { //we have the deleted term data fromt he transient, so use it here $sites = as_network_ids(); foreach($sites as $site){ switch_to_blog($site); $exist_check = term_exists($deleted_act_type->name, 'activity_type'); if(is_array($exist_check)){ //unhook action to avoid infinite loop remove_action("delete_activity_type", "as_act_type_delete", 10, 3); wp_delete_term($exist_check['term_id'], 'activity_type'); //add_action("delete_activity_type", "as_act_type_delete", 10, 3); } //end exist check restore_current_blog(); } //end foreach //now clear the data from the transient delete_site_transient( 'as_last_activity_type_delete' ); } //end false check for transient } //end update term add_action("delete_activity_type", "as_act_type_delete", 9, 3); 

Это также требует взлома ядра WP (да, остерегайтесь этого каринального греха, потому что это ужасная трансгрессия). В wp-includes/taxonomy.php найдите строку 1767 или $term = (int) $term; линии в функции wp_delete_term . Там поместите эту строку:

 set_site_transient('as_last_activity_type_delete',get_term($term,'activity_type')); 

Я также могу оставить комментарий здесь, а также татуировать напоминание об этом изменении где-нибудь, потому что вам придется вручную обновлять taxonomy.php каждый раз, когда вы обновляете WordPress . Это отстой, но причина, по которой мы устанавливаем этот переходный процесс, заключается в том, что мы можем искать удаленный термин по его slug, а не по его идентификатору. delete_{tax_type} action delete_{tax_type} дает нам term_id для удаленного термина, но мы не можем быть уверены, что это будет одинаково на всех наших сетевых сайтах, поэтому мы должны получить термин slug до его удаления … таким образом основной взлом. Мне это не нравится, я не горжусь этим, но он работает. Если вы только заботитесь о том, чтобы нажимать термины на свои сетевые сайты и не заботитесь об их удалении с вашего основного сайта, вы могли бы фактически пропустить это и не взломать ядро ​​- мне нужно было создать и удалить с одного сайта, и это было единственный способ, которым я нашел.

Вы также заметите строку в моем коде, где это произойдет $sites = as_network_ids(); , Это просто вспомогательная функция, которую я создал в другом месте, которая возвращает список всех идентификаторов сетевого блога наряду с некоторыми дополнительными данными, которые я использую для множества других функций. Вы можете получить список блогов с помощью этой функции (предупреждение: оно официально устарело, но еще не было заменено) или написанием собственного SQL.