Статьи

Создание списка товаров с бесконечными категориями с использованием пользовательских типов записей

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


Во-первых, нам нужно создать наш тип поста. Откройте файл functions.php и добавьте следующую строку в начало файла после открывающего тега PHP:

1
require_once (‘functions/products.php’);

Если у вас его еще нет, создайте каталог с именем functions в папке вашей темы и файл с именем products.php внутри этого каталога. В нашем products.php мы зарегистрируем наш пользовательский тип записи:

1
add_action( ‘init’, ‘product_register’ );

Первая строка — это ловушка, которая при инициализации WP admin вызовет нашу функцию ‘products_register’. В рамках нашей функции мы создали два массива. Первый — это ярлыки, которые будут использоваться на нашей панели управления WordPress. В рамках нашей функции мы создаем список аргументов, большинство из которых говорят сами за себя. Наш последний аргумент «поддерживает» позволяет использовать, чтобы указать, что мы хотим отображать на странице записи / редактирования сообщения. Обратите внимание, что мы добавили поддержку атрибутов страницы, чтобы указать порядок наших продуктов в категории (изображение панели). Затем мы передаем функцию register_post_type имя нашего пользовательского типа записи и аргументы.

Панель заказов

Давайте добавим настраиваемое поле для хранения цены наших продуктов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
add_action(«admin_init», «price_meta»);
 function price_meta(){
  add_meta_box(«price», «Price», «Price», «products», «normal», «low»);
}
 
 function price(){
  global $post;
  $custom = get_post_custom($post->ID);
  $price = $custom[«price»][0];
  ?>
  <label>Price:</label>
  <input id=»price» name=»price» type=»text» value=»<?php echo $price; ?>» />
  <?php
}
  
add_action(‘save_post’, ‘save_meta’);
function save_meta(){
  global $post;
  update_post_meta($post->ID, price, $_POST[«price»]);
}
?>

Снова, когда WP admin инициализируется, вызывается наша функция price_meta, которая отображает наше настраиваемое поле. Затем мы создаем функцию с именем price, которая создаст поле формы для нашего пользовательского типа записи. мы также захватили его текущее значение с помощью get_post_custom, чтобы мы могли отображать его при редактировании поста, если было установлено значение. Наша последняя функция сохраняет значение, присвоенное нашему настраиваемому полю, используя update_post_meta () . Мы передаем функции идентификатор нашего сообщения, имя обновляемого поля и значение, которое мы храним.


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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
$labels = array(
    ‘name’ => _x( ‘Product Categories’, ‘taxonomy general name’ ),
    ‘singular_name’ => _x( ‘Product Category’, ‘taxonomy singular name’ ),
    ‘search_items’ => __( ‘Search Product Categories’ ),
    ‘all_items’ => __( ‘All Product Categories’ ),
    ‘parent_item’ => __( ‘Parent Category’ ),
    ‘parent_item_colon’ => __( ‘Parent Category:’ ),
    ‘edit_item’ => __( ‘Edit Product Category’ ),
    ‘update_item’ => __( ‘Update Product Category’ ),
    ‘add_new_item’ => __( ‘Add Product Category’ ),
    ‘new_item_name’ => __( ‘New Product Category’ ),
    ‘menu_name’ => __( ‘Product Categories’ )
  );
 
register_taxonomy(‘product_categories’,array(‘products’), array(
    ‘hierarchical’ => true,
    ‘labels’ => $labels,
    ‘query_var’ => true,
    ‘show_ui’ => true
 ));

Опять мы определяем наши ярлыки. Далее мы вызываем функцию register_taxonomy . Мы сообщаем функции имя нашей таксономии, которая называется product_categories (обратите внимание на отсутствие пробелов и заглавных букв), тип (типы) записей, с которыми нужно связать таксономию, и передаем ей несколько аргументов. Важно отметить, что мы устанавливаем иерархическое значение true для поддержки вложенных таксономий или в нашем случае подкатегорий продуктов.


Наши продукты будут использовать избранные изображения, поэтому мы должны убедиться, что наша тема поддерживает это. Проверьте файл functions.php вашей темы и посмотрите, поддерживает ли он уже миниатюры сообщений, если нет, то добавьте эту строку в верхнюю часть файла под тем местом, где нам требовался наш пользовательский тип сообщения.

1
2
3
if ( function_exists( ‘add_theme_support’ ) ) {
add_theme_support( ‘post-thumbnails’ );
}

Мы хотели бы присвоить каждой из наших категорий продуктов изображение. На данный момент нет встроенного способа сделать это, поэтому нам нужно установить фантастический плагин Taxonomy Images от Michael Fields . После того, как плагин установлен и активирован, мы переходим на его страницу настроек и сообщаем плагину добавить поддержку изображений в нашу таксономию категорий продуктов.

Страница настроек плагина таксономических изображений

Затем мы добавим поддержку динамического изменения размера изображения для нашей категории продукта и изображения продукта с помощью Timthumb , сценария изменения размера изображения PHP. Timbhumb — это радость работы и легкая реализация в темах WordPress. Мы скоро начнем использовать его в наших файлах тем, но сейчас мы просто настроим его. Давайте загрузим Timthumb и разместим скрипт с нашими файлами тем. Нам также необходимо создать каталог кэша в каталоге нашей темы и предоставить ему 777 разрешений.


Чтобы перечислить наши категории продуктов верхнего уровня, мы собираемся создать собственный шаблон страницы и назвать его «Продукты».

1
2
3
4
5
6
<?php
/**
 Template Name: Products
 */
 
get_header();

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

1
2
3
4
$args=array(
    ‘hide_empty’ => 0,
    ‘parent’ => 0,
    ‘taxonomy’ => ‘product_categories’);

Здесь мы настроили три аргумента для передачи в функцию get_categories . Каждый аргумент необходим для получения категорий продуктов верхнего уровня.

  • Hide_empty => 0 Позволяет нам отображать категории, которые не содержат сообщений
  • Parent => 0 Определяя родителя, мы ограничили возвращаемые таксономии только таксономиями, у которых есть родитель с идентификатором 0. Установив ID родителя в 0, это означает, что мы будем возвращать таксономии верхнего уровня, так как они не имеют родитель
  • Таксономия => «product_categories» здесь мы определяем таксономию для запроса, по умолчанию она установлена ​​в «категорию», поэтому мы должны сказать WordPress, что мы хотим запросить нашу собственную таксономию вместо

Далее мы передаем аргументы get_categories, который возвращает массив совпадающих таксономий. Мы запускаем цикл foreach и устанавливаем пару переменных.

Первое — это изображение категории продукта, которое мы получили с помощью get_option и передав ему имя опции, которую мы хотим получить. В данном случае это изображение, установленное плагином таксономических изображений. Следующая переменная — это URL архива таксономии. мы использовали функцию get_term_link для достижения этой цели, передав ей слаг таксономии и имя таксономии. Затем мы начинаем выводить соответствующие категории продуктов.

01
02
03
04
05
06
07
08
09
10
11
12
$categories=get_categories($args);
         
foreach($categories as $category) {
    echo ‘<div class=»product-cat»>’;
 
    $thumb_url = get_option(‘taxonomy_image_plugin’);
    $product_cat_url = get_term_link( $category->slug, ‘product_categories’ );
                 
    echo ‘<a href=»‘.$product_cat_url.'»><img src=»‘.get_template_directory_uri().’/timthumb.php?src=’.wp_get_attachment_url( $thumb_url[$category->term_taxonomy_id]).’&h=200&w=200″ /></a>’;
    echo ‘<a class=»cat-title» href=»‘ . $product_cat_url .'»>’ .
    echo ‘</div> <!—end product cat—>’;
}

Давайте посмотрим, как миниатюры генерируются с помощью timthumb. Нам нужно указать исходный путь к нашей копии скрипта в каталоге нашей темы. Затем нам нужно дать сценарию источник для изображения и установить его ширину и высоту. Просто не так ли? Я также настроил оператор if, чтобы убедиться, что у нас есть запасной вариант, если с категорией не связано изображение.

Затем мы должны добавить некоторые базовые стили, чтобы все обрело форму. мы только что разместили div и абсолютно поместили заголовки в div.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
.product, .product-cat{
    border:10px solid #dfdfdf;
    float:left;
    margin:0 40px 20px 0;
    outline:1px solid #bfbfbf;
    position:relative;
}
    .product img, .product-cat img{
        max-width:100%;
    }
    .product-title, .cat-title{
        background:rgba(0,0,0,.8);
        color:#FFF;
        display:block;
        position:absolute;
        bottom:0;
        left:0;
        padding:10px 0;
        text-align:center;
        width:100%;
    }

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


Создайте файл с именем taxonomy-products_categories.php. Если вы посмотрите на иерархию шаблонов, то увидите, что этот шаблон нам нужен для создания архива таксономии. Это позволяет нам создавать различные архивы для любой пользовательской таксономии.

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

01
02
03
04
05
06
07
08
09
10
$slug = get_query_var( ‘term’ );
$term = get_term_by( ‘slug’, $slug , ‘product_categories’ );
$term_id = $term->term_id;
 
$args=array(
        ‘hide_empty’ => 0,
        ‘parent’ => $term_id,
        ‘taxonomy’ => ‘product_categories’);
                         
$categories=get_categories($args);

Сначала мы взяли слаг текущего таксономии с помощью get_query_var () . Затем мы получаем все данные терминов с помощью get_term_by () , передавая ему поле, которое мы предоставляем, значение поля и название таксономии. При этом мы можем получить текущий идентификатор таксономии, используя get_term_by, который нам нужен для массива аргументов для родительского параметра. Наконец, мы передали наши аргументы в функцию get_categories и определили переменную для возвращаемого массива под названием категории.

Давайте быстро посмотрим на структуру, которой мы будем следовать сейчас:

Теперь мы идем по маршруту, если массив пуст. Если это так, то мы находимся на самом низком уровне категории продуктов и должны выводить текущие категории продуктов. Давайте сначала настроим наши аргументы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
if(!$categories){
         
    //get the product category name
    echo «<h1 class=’entry-title’>».$term->name.»</h1>»;
 
    $args = array(
    ‘posts_per_page’ => 2, //remember posts per page should be less or more that what’s set in general settings
    ‘paged’ => $paged,
    ‘meta_key’ => ‘price’,
    ‘orderby’ => ‘meta_value_num’,
    ‘order’ => ‘ASC’,
    ‘tax_query’ => array(
                array(
                ‘taxonomy’ => ‘product_categories’,
                ‘field’ => ‘slug’,
                ‘terms’ => $slug)
        )
    );

Давайте посмотрим на аргументы, которые мы создали. Первые два аргумента включают нумерацию страниц. Следующие три аргумента обрабатывают порядок продуктов. Мы упорядочиваем их по цене мета-ключа, а также по их цене, от самой низкой до самой высокой. Если вы хотите заказать продукты, установив их порядок при создании продукта, используйте вместо этого следующий аргумент:

1
‘orderby’ => ‘menu_order’

Последний массив аргументов определяет таксономию, к которой мы обращаемся, и какую категорию продукта мы запрашиваем. Мы определяем категорию продукта, передавая термин «термин» текущую категорию продукта.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?php
$products_query = new WP_Query($args);
    if (have_posts()) :
    while($products_query->have_posts()) : $products_query->the_post();
 
        $post_thumbnail_id = get_post_thumbnail_id();
        $post_thumbnail_url = wp_get_attachment_url($post_thumbnail_id);
?>
        <div class=»product»>
            <a class=»product-title» href=»<?php the_permalink(); ?>»><?php the_title();
            <a href=»<?php the_permalink(); ?>»>
                <img src=»<?php echo get_template_directory_uri(); ?>/timthumb.php?src=<?php if($post_thumbnail_url){ echo $post_thumbnail_url; } else { echo get_template_directory_uri().»/images/fallback.png»; } ?>&h=200&w=200″ alt=»<?php the_title(); ?>» />
            </a>
        </div>

Мы извлекли URL-адрес миниатюры поста, чтобы использовать его с timthumb, получив его идентификатор, а затем используя wp_get_attachment_url и передав ему идентификатор.

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

1
2
3
4
<?php endwhile;
    <p>Sorry no products were found.</p>
<?php endif;
<?php wp_reset_query();

Наконец, мы включим наши ссылки на страницы:

1
2
3
4
<div class=»pagination»>
    <?php next_posts_link(‘« More Products’, $products_query->max_num_pages) ?>
    <?php previous_posts_link(‘Previous Products »’) ?>
</div>

Теперь мы пойдем по другому маршруту, если категория содержит подкатегории:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<?php
else{
         
    //output current category name
    echo ‘<h1 class=»entry-title»>’.$term->name.'</h1>’;
    foreach($categories as $category) {
        echo ‘<div class=»product-cat»>’;
 
        $thumb_url = get_option(‘taxonomy_image_plugin’);
        $thumb_url = wp_get_attachment_url( $thumb_url[$category->term_taxonomy_id]);
        $product_cat_url = get_term_link( $category->slug, ‘product_categories’ );
?>
         
        <a href=»<?php echo $product_cat_url; ?>»>
            <img src=»<?php echo get_template_directory_uri(); ?>/timthumb.php?src=<?php if($thumb_url){ echo $thumb_url; } else{ echo get_template_directory_uri().»/images/fallback.png»; } ?>&h=200&w=200″ alt=»<?php the_title(); ?>» />
        </a>
        <a class=»cat-title» href=»<?php echo $product_cat_url ; ?>»><?php echo $category->name;
        </div> <!—end product cat—>
                 
<?php } ?>

Мы уже рассмотрели то, что происходит в приведенном выше коде на четвертом шаге, поэтому давайте перейдем к последней части учебника.


Если вы работали с пользовательскими типами постов, прежде чем знаете, что будет дальше. Мы собираемся создать единый product.php. По аналогии с нашей таксономией-product_categories.php, которую мы использовали для таксономии категорий товаров, мы можем создать собственный шаблон одного сообщения, уникальный для нашего пользовательского типа сообщения. В этом файле мы собираемся поместить:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php get_header();
 
    <?php if ( have_posts() ) while ( have_posts() ) : the_post();
         
        <?php
            //get post thumbnail url
            $post_thumbnail_id = get_post_thumbnail_id();
            $post_thumbnail_url = wp_get_attachment_url($post_thumbnail_id);
        ?>
        <img id=»product-img» src=»<?php echo get_template_directory_uri(); ?>/timthumb.php?src=<?php if(!empty($post_thumbnail_url)){ echo $post_thumbnail_url; } else { echo get_template_directory_uri().»/images/fallback.png»; } ?>&h=300&w=300″ alt=»<?php the_title(); ?>» />
         
        <div id=»product-desc»>
            <h1 class=»entry-title»><?php the_title();
        <?php the_content();
             
        <?php if( get_post_meta($post->ID, ‘price’, true)): ?>
            Price: <?php echo get_post_meta($post->ID, ‘price’, true);
        <?php endif;
             
        <div>
          
    <?php endwhile;
 
<?php get_footer();

Вы должны быть знакомы с большинством тегов шаблонов, используемых здесь, но давайте взглянем на использование get_post_meta, которое возвращает наше настраиваемое поле цены, которое мы установили на первом шаге. Мы создали оператор if, чтобы проверить, была ли установлена ​​цена, если она есть, мы выводим цену. Мы делаем это, передавая функцию идентификатор сообщения, метаключ, который мы хотим получить, и то, хотим ли мы получить один результат. Мы делаем, поэтому мы установили это на истину.

Снова давайте добавим несколько основных стилей для оформления наших продуктов:

1
2
3
4
5
6
7
8
#prouct-img{
    float:left;
    width:100%;
}
#product-desc{
    float:right;
    width:50%;
}

Мы немного рассмотрели здесь, но, надеюсь, теперь вы должны были изучить некоторые новые методы и получить представление о силе пользовательских типов записей, таксономий и пользовательских запросов. Есть вопросы или идеи по улучшению? Давайте обсудим их в комментариях.