Как разрешить запятые в названиях меток?
Как разрешить запятые в названиях меток? Например, "привет, мир"
или "портленд, или"
, но WordPress продолжает их разделять. Я могу сделать это со страницы категорий:
image http://img839.imageshack.us/img839/6869/picturepp.png
И она отображается корректно. Но любые метки, добавленные через боковую панель записи, отображаются некорректно:
image http://img52.imageshack.us/img52/4950/picture1oax.png
Есть обсуждение этой проблемы здесь: http://core.trac.wordpress.org/ticket/14691, но похоже, что решение не появится в ближайшее время.
Пока я ищу более простое решение, чем добавление категорий через страницу категорий.
Я пытался найти подходящие плагины, но не нашел ничего полезного. Есть несколько плагинов, которые заменяют запятые другими символами при отображении списка категорий или меток, но я не нашел плагинов, позволяющих заменить разделитель по умолчанию.
Мне не важно, придется ли патчить ядро самостоятельно. В идеале я бы хотел написать плагин, но после просмотра кода я не могу понять, где это обрабатывается.
У кого-нибудь есть решение или подсказки, с каких функций и javascript начать? Я не знаю, где искать в коде.

Взламывать ядро не нужно — спасибо хукам (HOOKS).
Хуки позволяют решить проблему с помощью элегантного сочетания:
- фильтра, заменяющего "--" на ", " перед выводом,
- блока "if", чтобы убедиться, что фильтрация не применяется в интерфейсе администратора :)
- и, наконец, сохранения всех ваших тегов с запятой в формате "Fox--Peter" вместо "Fox, Peter".
Вот код:
// фильтр для тегов с запятой
// заменяем '--' на ', ' при выводе — так можно использовать теги с запятыми
// например, сохраняем тег как "Fox--Peter", но благодаря фильтрам выводим как "Fox, Peter"
if(!is_admin()){ // убеждаемся, что фильтры работают только на фронтенде
function comma_tag_filter($tag_arr){
$tag_arr_new = $tag_arr;
if($tag_arr->taxonomy == 'post_tag' && strpos($tag_arr->name, '--')){
$tag_arr_new->name = str_replace('--',', ',$tag_arr->name);
}
return $tag_arr_new;
}
add_filter('get_post_tag', 'comma_tag_filter');
function comma_tags_filter($tags_arr){
$tags_arr_new = array();
foreach($tags_arr as $tag_arr){
$tags_arr_new[] = comma_tag_filter($tag_arr);
}
return $tags_arr_new;
}
add_filter('get_terms', 'comma_tags_filter');
add_filter('get_the_terms', 'comma_tags_filter');
}
Возможно, дополнительные детали в моей записи блога по этой теме также помогут... http://blog.foobored.com/all/wordpress-tags-with-commas/
С уважением, Анди

Это сломается. Запятая не является фиксированной строкой, она может быть переведена. Используйте _x( ',', 'tag delimiter' )
, чтобы получить реальный разделитель.

Запятые в названиях тегов не будут работать корректно, потому что при добавлении тега к записи WordPress разобьёт его на несколько ключевых слов по запятой.
Простое решение:
Используйте ,
(HTML-код для запятой) вместо обычной запятой.
Тогда:
,
будет отображаться как обычная запятая внутри записей, заголовков страниц тегов и во многих других местах.- Он будет отображаться в исходном виде, как
,
, в интерфейсе администратора при вводе названия тега.
Кстати, использование HTML-сущности ,
не работает.

Вот ваше решение. Обратите внимание на строку 2614:
/**
2588 * Обновляет кеш для ID терминов.
2589 *
2590 * Будет обновлять кеш только для терминов, которые еще не закешированы.
2591 *
2592 * Ожидается, что $object_ids будет содержать ID, разделенные запятыми, если это строка.
2593 *
2594 * Стоит отметить, что update_object_term_cache() очень ресурсоемкая функция.
2595 * Рекомендуется не вызывать её слишком часто или хотя бы не для большого
2596 * количества терминов, которые существуют во многих таксономиях. Время выполнения
2597 * увеличивается для каждого термина и для каждой таксономии, к которой принадлежит термин.
2598 *
2599 * @package WordPress
2600 * @subpackage Taxonomy
2601 * @since 2.3.0
2602 * @uses wp_get_object_terms() Используется для получения терминов из базы данных для обновления
2603 *
2604 * @param string|array $object_ids Одиночный или список ID объектов терминов
2605 * @param array|string $object_type Тип объекта таксономии
2606 * @return null|bool Возвращает null при пустом $object_ids. False в случае ошибки
2607 */
2608 function update_object_term_cache($object_ids, $object_type) {
2609 if ( empty($object_ids) )
2610 return;
2611
2612 if ( !is_array($object_ids) )
2613 $object_ids = explode(',', $object_ids);
2614
2615 $object_ids = array_map('intval', $object_ids);
2616
2617 $taxonomies = get_object_taxonomies($object_type);
2618
2619 $ids = array();
2620 foreach ( (array) $object_ids as $id ) {
2621 foreach ( $taxonomies as $taxonomy ) {
2622 if ( false === wp_cache_get($id, "{$taxonomy}_relationships") ) {
2623 $ids[] = $id;
2624 break;
2625 }
2626 }
2627 }
2628
2629 if ( empty( $ids ) )
2630 return false;
2631
2632 $terms = wp_get_object_terms($ids, $taxonomies, array('fields' => 'all_with_object_id'));
2633
2634 $object_terms = array();
2635 foreach ( (array) $terms as $term )
2636 $object_terms[$term->object_id][$term->taxonomy][$term->term_id] = $term;
2637
2638 foreach ( $ids as $id ) {
2639 foreach ( $taxonomies as $taxonomy ) {
2640 if ( ! isset($object_terms[$id][$taxonomy]) ) {
2641 if ( !isset($object_terms[$id]) )
2642 $object_terms[$id] = array();
2643 $object_terms[$id][$taxonomy] = array();
2644 }
2645 }
2646 }
2647
2648 foreach ( $object_terms as $id => $value ) {
2649 foreach ( $value as $taxonomy => $terms ) {
2650 wp_cache_set($id, $terms, "{$taxonomy}_relationships");
2651 }
2652 }
2653 }
2654
В файле wp-includes/taxonomy.php. Удачи в изменении кода. Тут нет хуков. Это жестко закодировано... Извините. Думаю, что изменение кода - ваш единственный вариант на данный момент.

+1 - В моем оригинальном сообщении я упомянул, что в данном случае вмешательство в ядро допустимо. Я даже не мог найти, где именно нужно внести изменения в ядро, чтобы это заработало. По крайней мере, теперь, зная что это возможно, я могу работать над созданием плагина или подать официальный тикет с запросом на добавление хука или фильтра в сообществе WP. Так что спасибо @AsafChertkoff, хотя я сам еще не проверял это решение.

Можно и очень легко программно сохранять теги с запятыми.
При вызове wp_set_post_terms( $post_id, $terms, $taxonomy )
, если передать строку, она будет разделена на массив. Если передать $terms
как массив, каждый элемент массива будет сохранён как отдельный термин без разделения на несколько терминов.
// Пример термина с запятой.
$terms = 'Фамилия, Имя';
// Создаёт и/или назначает несколько терминов, разделённых запятой.
wp_set_post_terms( $post_id, $terms, $taxonomy );
// Создаёт и/или назначает один термин с запятой.
wp_set_post_terms( $post_id, (array) $terms, $taxonomy );
И wp_insert_post
, и затем wp_update_post
используют wp_set_post_terms
, когда установлен аргумент $arg
tax_input
.
// Убедитесь, что $terms — массив.
$args['tax_input'][$taxonomy] = (array) $terms;
$post_id = wp_insert_post( $args );
Лучший способ создавать термины "на лету" через интерфейс WordPress Dashboard может потребовать создания собственного метабокса, который отправляет любую строку, включая запятые, как один термин. Некоторые плагины, такие как ACF Pro, делают это по умолчанию, когда вы создаёте произвольное поле для сохранения таксономии и выбираете также загружать и назначать термины при сохранении.
/* Пример JSON-конфигурации для экспорта/импорта ACF Pro. */
/* Наиболее вероятная конфигурация для большинства ситуаций: "allow_null" */
/* и "field_type" могут потребовать корректировки в зависимости от ситуации. */
{
"type": "taxonomy",
"field_type": "multi_select",
"allow_null": 1,
"add_term": 1,
"save_terms": 1,
"load_terms": 1
}
Даже если термин сохранён с запятой, его части могут отображаться отдельно при редактировании записи. В этом случае лучше отключить стандартный интерфейс и полагаться на пользовательские метабоксы. Это можно сделать через "Настройки экрана" при редактировании типа записи. Пользовательские таксономии также можно скрыть из раздела быстрого редактирования при их регистрации.
// Аргументы регистрации пользовательской таксономии — отключение стандартного UI в быстром редактировании.
$args['show_in_quick_edit'] = false;
register_taxonomy( $taxonomy, (array) $post_types, $args );

Только что придумал грязный фикс (сам ещё не тестировал), но можно добавить фильтр, который всегда будет санировать термины, преобразовывая их в массив. add_filter( 'pre_tax_input', function( $tax_input ) { return (array) $tax_input; } );
Однако это позволит отправлять только один термин за раз.

Вы можете использовать фильтр.
Например, если вы хотите добавить запятую после каждого тега в облаке тегов, вы можете добавить следующий код в ваш файл functions.php
function myfunc_filter_tag_cloud($args) {
$args['smallest'] = 18;
$args['largest'] = 32;
$args['unit'] = 'px';
$args['separator']= ', ';
return $args;
}
add_filter ( 'widget_tag_cloud_args', 'myfunc_filter_tag_cloud');
