Intereting Posts
Получить заголовок и URL-адрес вложенного родительского сообщения Показывать категории, в которых текущая должность имеет Использование jquery migrate для плагинов, несовместимых с jquery 1.10.2 Что создать новый пост с помощью wp_insert_post, но он повторяет сообщение бесконечно Определить, является ли текущая страница главной страницей в пользовательском запросе Как использовать wp_enqueue_script, когда требуется Как я могу условно выделить таблицы стилей или сценарии в настройках настройки тем? Можно ли использовать Категории для взлома мультисайтовой установки с одним MySql db? Переместить метатекст отрезка в редактор содержимого Шаблон пользовательского шаблона сообщения – Архив Переведенные слова, не показывающие дочернюю тему Амортизированный вызов -> Функция wpdb :: escape () Какой плагин позволит мне перенаправить 404 ошибки на определенную страницу? Удаление текста + короткий код из всех сообщений Пользователи не могут загружать изображения на интерфейсе, если у них нет доступа к wp-серверу

Мастер-сайт для конкретной таксономии в 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.