Пользовательские таксономии и как оставаться в них, когда в сообщениях выбрано несколько терминов? - PullRequest
0 голосов
/ 02 мая 2020

Хотите знать, может ли кто-нибудь помочь мне разобраться в этом?

Пока я был в закрытом состоянии, я составлял простой сайт для организации моей коллекции ретро-игровых объявлений, охватывающих системы от Atari 2600 до на N64. У меня еще есть несколько тысяч, чтобы добавить на сайт (занимает много времени), но я столкнулся с проблемой, я не уверен, как внедрить исправление для.

Вы можете просматривать объявления по системе через отдельные страницы сообщений, но если объявление охватывает несколько систем, оно испортит ссылку на предыдущую и следующую публикацию и переведет вас в другую систему.

Например: если вы используете ссылки на следующую и предыдущую публикацию для go через раздел "Мега драйв / генезис", когда вы попадете в "Battletoads and Double Dragon", когда вы нажимаете стрелку следующего поста, на этот раз вы внезапно просматриваете рекламу, помеченную как NES, из-за того, что это первый термин связан с ним.

См .: https://www.retrogameads.com/system/mega-drive/ и нажмите на первое объявление, затем продолжайте нажимать следующую стрелку, и вы поймете, что я имею в виду.

I думаю, я мог бы публиковать каждое объявление несколько раз для каждой системы, но мне не нравится идея этого.

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

Имейте в виду, что этот сайт находится в стадии разработки, так что дизайн - это просто что-то базовое c, пока я не найду лучший способ организовать вещи.

Дайте мне знать ваши мысли.

Обновление: Текущий способ получения предыдущих сообщений ...

<?php
$terms = get_the_terms( $post->ID, 'system' ); 
$i = 0;
$systems = array();
foreach ( $terms as $term ) {
    $systems[$i] = $term->slug;
    $i++;
}
$postlist_args = array(
    'posts_per_page'  => -1,
    'post_type'       => 'portfolio',
    'system'          => $systems[0],
    'order'          => 'ASC',
    'orderby'        => 'title'
); 
$postlist = get_posts( $postlist_args );
$ids = array();
foreach ($postlist as $thepost) {
    $ids[] = $thepost->ID;
}
$thisindex = array_search($post->ID, $ids);
$previd = $ids[$thisindex-1];
$nextid = $ids[$thisindex+1];
?>
<div class="prev_next">
<?php
if ( !empty($previd) ) {
    echo '<div class="older"><a rel="prev" href="' . get_permalink($previd). '">&lsaquo;</a></div>';
}
if ( !empty($nextid) ) {
    echo '<div class="newer"><a rel="next" href="' . get_permalink($nextid). '">&rsaquo;</a></div>';
}
?>

1 Ответ

0 голосов
/ 02 мая 2020

Когда вы нажимаете на объявление, вы, по сути, посещаете одну страницу для этого объявления. В этот момент WP не знает / не помнит, что пользователь хочет видеть рекламу только из той системы, на которую вы нажали.

Как вы отображаете предыдущие / следующие ссылки прямо сейчас?

Одна из возможных Решением может быть добавление параметра к URL-адресу, а затем принять это во внимание в коде PHP при рендеринге предыдущих / следующих ссылок. (/portfolio/advert-name/?system=mega-drive например)

Редактировать: Конечно, URL также можно сделать красивее ... если вы хотите добавить дополнительную работу, вы можете зарегистрировать постоянную ссылку в форме /portfolio/mega-drive/advert-name/ например. Но это потребует немного больше работы.

Будет ли это работать? Я думаю, что это было бы лучшим решением с учетом альтернатив.

Обновление: Для фактической реализации фильтры get_next_post_where и get_previous_post_where могут оказаться очень полезными. Вы можете сделать так, чтобы он учитывал системный параметр для предыдущих / следующих ссылок.

Другой вариант: Вы также можете настроить PHP сеанс и запомнить текущую систему таким образом, но тогда вам потребуется сеанс PHP, что не очень хорошо, и это также не позволит вам использовать полное кэширование страниц (оптимизация производительности).

Еще один вариант - запомнить текущая система на стороне клиента через повара ie. Но в этом случае у вас снова возникают проблемы с кэшированием, если вы не загрузите предыдущие / следующие ссылки через AJAX.


После прочтения обновления по вашему вопросу у меня появятся следующие заметки:

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

Так как мы можем улучшить это?

Простой: используйте функции get_previous_post и get_next_post на $post. Он принимает три аргумента. Вот пример для get_next_post (но get_previous_post в основном то же самое):

get_next_post( bool $in_same_term = false, array|string $excluded_terms = '', string $taxonomy = 'category' )

Теперь, если вы установите $in_same_term в true, то следующий пост будет сообщением, которое разделяет хотя бы один термин таксономии (в нашем случае система).

Вы также должны установить $taxonomy на system, потому что это пользовательская таксономия.

А другой параметр - $excluded_terms. Жаль, что нет $included_terms, иначе мы могли бы просто поместить туда систему, которую хотим. Но мы можем сделать это по-другому ... Мы можем отфильтровать текущую систему (в параметре system GET в нашем URL) и оставить все остальные системы в качестве систем для исключения.

Итак, давайте создадим то, что нам нужно сейчас.

global $post;

// What system did we come from?
$system = $_GET['system'] ?? null; // Set to null if nothing was specified (uses PHP's null coalescing operator available since PHP 7

// Exclude nothing by default
$excluded_term_ids = [];

// If we came here by clicking on a system, then exclude all other systems so the previous/next links will be of the same system only
if ($system) {
  // Retrieve system terms for this post
  $terms = get_the_terms( $post, 'system' );

  // Filter the list of terms to remove the system we came from
  // This way we can create a list of terms to exclude
  $excluded_terms = array_filter( $terms, function ( $term ) use ( $system ) {
      return $term->slug != $system;
  } );

  // The get_previous_post and get_next_post functions expect $excluded_terms to be an array of term IDs, so we must map the WP_Term objects into IDs
  $excluded_term_ids = array_map( function ( $term ) {
      return $term->term_id;
  }, $excluded_terms );
}

// Retrieve previous and next post
$previous_post = $post->get_previous_post( true, $excluded_term_ids, 'system' );
$previous_post = $post->get_next_post( true, $excluded_term_ids, 'system' );

// Echo out the page links
// And don't forget to re-add the ?system= parameter to the URL
$url_suffix = $system ? ('?system=' . $system) : '';
if ( $previous_post ) {
    echo '<div class="older"><a rel="prev" href="' . get_permalink($previous_post) . $url_suffix . '">&lsaquo;</a></div>';
}
if ( $next_post ) {
    echo '<div class="newer"><a rel="next" href="' . get_permalink($next_post) . $url_suffix . '">&rsaquo;</a></div>';
}

ПРИМЕЧАНИЕ: непроверенный код .. Итак, где-то может быть небольшая ошибка .. Дайте мне знать, если у вас возникнут проблемы с этим кодом ..

Важно: На странице системы теперь необходимо также добавить «? System = current-system» к отображаемым URL-адресам. Вероятно, что-то вроде: echo get_permalink($advert) . '?system=' . $post->post_name (может отличаться в зависимости от того, как ваш код на этом экране ..)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...