Добавление пользовательских архивов типов записей в меню WordPress

10

Есть ли способ (помимо добавления пользовательской ссылки) добавить пользовательский архив записей в меню в WordPress? Если он добавлен с использованием пользовательской ссылки (например, / cpt-archive-slug /), WordPress не применяет классы, подобные current-menu-itemэлементу списка, что создает проблемы при стилизации меню.

Если пользовательская ссылка содержит полный URL-адрес (например, http://site.com/cpt-archive-slug/ ), эти классы добавляются. Тем не менее, это, вероятно, не «лучшая практика».

Трэвис Норткатт
источник

Ответы:

5

лучше всего использовать пользовательскую ссылку с полным URL-адресом, так как пользовательские архивы типов записей представляют собой различные архивы на основе таксономии (категории, теги, любые пользовательские таксономии) и архивы на основе дат, в которых есть собственный архив.

Bainternet
источник
6

Я знаю, что это старо, но у меня тоже есть эта проблема, и я нашел довольно чистый способ справиться с этим - использовать пользовательское меню.

class KB_Custom_Menu_Walker extends Walker_Nav_Menu {

  protected static $custom_post_types = array();

  public function start_el(&$output, $item, $depth=0, $args=array(), $id=0) {
    if (isset( self::$custom_post_types[ $item->url ] )) {
      $item->url = get_post_type_archive_link( self::$custom_post_types[$item->url] );
    }
    parent::start_el($output, $item, $depth, $args, $id);
  }

  public static function custom_post_types($type=null) {
    if ($type) {
      self::$custom_post_types[ '#post_type_'.$type ] = $type;
    }
    return self::$custom_post_types;
  }
}

Имея пользовательский элемент меню ссылки с URL #post_type_album, вы можете использовать его следующим образом:

# Where you defined your custom post type (could be anywhere anyway)
KB_Custom_Menu_Walker::custom_post_types('album');

# And display the menu
wp_nav_menu(array(
  'theme_location' => 'primary-nav',
  'walker' => new KB_Custom_Menu_Walker(),
));

Примечание. Предполагается, что слаг и название вашего поста совпадают.

tungd
источник
+1 за поздний качественный ответ. Это хорошо для сообщества!
Брайан Фегтер
2

Я немного расширил ответ tungd, чтобы обеспечить более общий подход к этому подходу. Эта реализация позволяет добавлять произвольные отображения между «макросами» меню и внутренними URL-адресами Wordpress, о которых знает только серверная часть.

Я также решил использовать !в качестве префикса для этих макросов, чтобы они не конфликтовали с именованными якорями - это включает накладные расходы на удаление http: // из URL ссылки (так как Wordpress попытается нормализовать эти странные ссылки) , Если эта реализация вас беспокоит, вы всегда можете удалить preg_replace()вызов и использовать в #качестве префикса ссылки, как и раньше.

class Extendable_Menu_Walker extends Walker_Nav_Menu
{
    protected static $custom_urls = array();

    public static function setupUrls()
    {
        // calls to self::mapPostType($postTypeName) and 
        // self::createMapping($wildcard, $url) go here...
    }

    public function start_el(&$output, $item, $depth=0, $args=array(), $id=0)
    {
        $url = preg_replace('@^https?://@', '', $item->url);
        if (isset( self::$custom_urls[ $url ] )) {
            $item->url = self::$custom_urls[ $url ];
        }
        parent::start_el($output, $item, $depth, $args, $id);
    }

    public static function createMapping($urlKey, $realUrl)
    {
        self::$custom_urls['!' . $urlKey] = $realUrl;
    }

    public static function mapPostType($type)
    {
        self::createMapping('post_type_' . $type, get_post_type_archive_link($type));
    }
}

add_action('init', array('Extendable_Menu_Walker', 'setupUrls'));
pospi
источник
1

Вы можете создать страницу, а затем применить к ней пользовательский шаблон архива. Я создаю и использую archive- {post-type} .php для имени шаблона так же, как вы делаете это для архива по умолчанию, я просто вручную применяю его к странице.

Если вы сделаете это, я бы порекомендовал установить для вашего CPT значение has_archive = 'false', чтобы избежать коллизий с постоянными ссылками, независимо от того, просто убедитесь, что ваша страница имеет другой постоянный ссылочный порог, чем установленный для вашего архивного слаг CPT.

jb510
источник
0

Я думаю, что мне нужно будет создать новый «родительский» тип записи, поэтому пользовательский тип публикации, который я хочу показать, станет «дочерним», и этот родитель будет отображаться в меню.

Это должно быть вариантом. Создание фиктивного родителя только для того, чтобы перечислить его в меню - это слишком много работы.

Я хотел бы сделать это из шаблона или функций, поэтому мне не нужно делать это в настройках каждого меню для каждого сайта в моей многоузловой установке.

Серджио
источник
1
Я имел в виду, что посты пользовательского пост-типа, которые я хотел показать в меню, будут единственным подтипом вновь созданного родителя, и я надеюсь, что он будет указан под родителем в настройках меню.
Серхио
0

Вместо добавления ссылки я создаю пустую страницу. На этой странице я добавляю что-то вроде «Контент, сгенерированный из cpt-name» в редакторе, чтобы мой клиент знал, откуда все эти материалы.

Затем я добавляю эту страницу в меню и, следуя следующему коду, гарантирую, что она подсвечивается при запуске archives-cpt или single-cpt.

/**
 * Fix to add Custom post types to nav menu
 * If you custom post is called "concepts"
 * create a new empty page called concepts and add this
 */
 function additional_active_item_classes($classes = array(), $menu_item = false){
    global $wp_query;


    if(in_array('current-menu-item', $menu_item->classes)){
        $classes[] = 'current-menu-item';
    }

    if ( $menu_item->title == 'PAGE TITLE' && is_post_type_archive('cpt-slug') ) {
        $classes[] = 'current-menu-item';
    }

    if ( $menu_item->title == 'PAGE TITLE' && is_singular('cpt-slug') ) {
        $classes[] = 'current-menu-item';
    }


    return $classes;
}
add_filter( 'nav_menu_css_class', 'additional_active_item_classes', 10, 2 );

Это проверит заголовок меню / страницы и, если мы действительно видим архив или отдельную страницу пользовательского типа поста. Если это правда, он добавит класс current-menu-item.

chifliiiii
источник