Как сделать портфолио на WordPress. Полное руководство

Портфолио является важной частью сайтов компании. Во многих шаблонах WordPress по умолчанию отсутствует возможность создавать портфолио на сайте. В этой статье подробно рассмотрим как сделать портфолио на сайте WordPress.

Несколько слов о реализации

Возможности WordPress позволяют реализовать портфолио различными способами исходя из потребностей. Простая реализация заключает в добавлении на определенную страницу дополнительных произвольных полей (post meta) с последующим выводом их на странице сайта. Таким образом можно сделать портфолио, состоящее только из картинок или текста.

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

В качестве примера буду создавать портфолио для транспортной компании. Каждая работа портфолио будет содержать галерею изображений, описание, дату перевозки, маршрут перевозки. Все работы будут разбиты на категории (промышленные грузы, негабарит, перевозка продуктов). На основе категорий сделаем фильтрацию портфолио. Рассмотрим создание отдельной страницы для вывода всех работ портфолио, одиночной страницы каждой работы и выведем несколько работ на главной странице.

Думаю, что рассмотренная реализации наиболее универсальна и подойдет для любой сферы деятельности.

Шаг 0.

Структура файлов

Перед тем, как приступить к созданию портфолио, давайте реализуем структуру файлов. Для больших функциональных модулей я всегда создаю отдельную директорию в папке шаблона и все файлы размещаю там. В данном случае создадим папку modules/portfolio. Внутри директории создадим файл portfolio.php, в нем будет размещаться весь php код, в файле portfolio-block.php будет размещен весь html код блока портфолио. Тут же создаем файлы style.css и scripts.js для стилей и JavaScript кода. Должно получиться так

📂 название-темы
   📂...
   📂 modules
      📂 portfolio
         📄 portfolio.php
         📄 portfolio-block.php
         📄 style.css
         📄 scripts.js
   📂...
   📂...
   📄 index.php
   📄 functions.php
   📄 ...

Шаг 1.

Подключение файлов

Когда все файлы созданы, их надо подключить, чтобы они заработали на сайте. Прежде всего подключим файлы стилей и скриптов. Откройте файл portfolio.php и добавьте в самом начале следующий код

<?php

add_action('wp_enqueue_scripts', 'portfolio_enqueue_scripts');

function portfolio_enqueue_scripts()
{
    wp_enqueue_style(
        'portfolio',
        get_template_directory_uri() . '/modules/portfolio/style.css',
        [],
        filemtime(get_template_directory() . '/modules/portfolio/style.css')
    );

    wp_enqueue_script(
        'portfolio',
        get_template_directory_uri() . '/modules/portfolio/scripts.js',
        ['jquery', 'swiper'],
        filemtime(get_template_directory() . '/modules/portfolio/scripts.js'),
        [
            'in_footer' => true
        ]
    );

    // Для галереи
    wp_enqueue_script(
        'swiper',
        'https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.js'
    );

    wp_enqueue_style(
        'swiper',
        'https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.css'
    );
}

Теперь подключим наш модуль к функционалу темы. Для этого откройте functions.php и в самом конце добавьте код

include get_template_directory() . '/modules/portfolio/portfolio.php';
  • Готово! Все файлы подключены, можно приступать непосредственно к реализации портфолио.

Шаг 2.

Создание нового типа записи

Тип записи – это функциональная единица WordPress. По умолчанию в WordPress есть несколько типов записей: записи (post), страницы (page), медиафайлы (attachment), ревизии (revision). Для портфолио мы создадим новый тип portfolio.

Код регистрации нового типа записи размещаем в файле modules/portfolio/portfolio.php

// Регистрация типа записи portfolio
add_action('init', 'portfolio_post_type_register');

function portfolio_post_type_register()
{
    register_post_type(
        'portfolio',
        [
            'labels'             => [
                'name'               => 'Портфолио',
                'singular_name'      => 'Портфолио',
                'add_new'            => 'Добавить работу',
                'add_new_item'       => 'Добавить работу',
                'edit_item'          => 'Редактировать',
                'new_item'           => 'Новая работа',
                'view_item'          => 'Посмотреть работу',
                'search_items'       => 'Найти',
                'not_found'          => 'Работы не найдено',
                'not_found_in_trash' => 'В корзине не найдено',
                'parent_item_colon'  => '',
                'menu_name'          => 'Портфолио'

            ],
            'public'             => true,
            'rewrite'            => true,
            'has_archive'        => true,
            'hierarchical'       => true,
            'show_in_rest'       => false,
            'menu_position'      => 36,
            'menu_icon'          => 'dashicons-portfolio',
            'supports'           => ['title', 'editor', 'thumbnail', 'page-attributes']
        ]
    );
}

После добавления кода обязательно обновите настройки постоянных ссылок: Настройки > Постоянные ссылки > Сохранить изменения.

Обратите внимание на параметры public и has_archive.

Параметр public отвечает за создание отдельной страницы для каждой работы портфолио. Если вам не нужны отдельные страницы, то укажите значение false.

Параметр has_archive активирует архивную страницу портфолио, на которой будут выведены все работы. Страница портфолио будет доступна по адресу site.ru/portfolio/.

Данные параметры могут повлиять на seo. После добавления работ в портфолио, при public = true автоматически будут созданы страницы каждой работы. Если сразу не проработать эту страницу, в индекс поисковых систем могут попасть «мусорные» страницы.

Шаг 3.

Регистрация категорий для портфолио

С помощью категорий можно разгруппировать все работы. Это позволит создать отдельные страницы для каждой категории (если нужно) и сделать удобную фильтрация портфолио.

// Регистрация категорий для портфолио
add_action( 'init', 'portfolio_type_taxonomy_register', 5 );

function portfolio_type_taxonomy_register() {
    
    // Регистрация таксономии
    register_taxonomy(
        'type',
        ['portfolio'],
        [
            'label' => 'Категория',
            'labels' => [
                'name'              => 'Категории',
                'singular_name'     => 'Категории',
                'search_items'      => 'Найти категории',
                'all_items'         => 'Все категории',
                'view_item'         => 'Посмотреть категорию',
                'parent_item'       => 'Родительская категория',
                'parent_item_colon' => 'Родитель:',
                'edit_item'         => 'Изменить категорию',
                'update_item'       => 'Обновить категорию',
                'add_new_item'      => 'Добавить новую категорию',
                'new_item_name'     => 'Новая категория',
                'menu_name'         => 'Категории',
                'back_to_items'     => '← Назад в категорию'
            ],
            'public' => true,
            'publicly_queryable' => false,
            'hierarchical' => true,
            'rewrite' => true
        ]
    );
}

Этот код так же добавляем в файл modules/portfolio/portfolio.php.

Так же обратите внимание на параметр publicly_queryable. При значении true будут автоматически созданы страницы для каждой категории. Если вам такие страницы не нужны, установите значение false.

После добавления кода обязательно обновите настройки постоянных ссылок: Настройки > Постоянные ссылки > Сохранить изменения.

Шаг 4.

Добавление настроек для работ в портфолио

Итак, мы зарегистрировали новый тип записи portfolio и категории к нему. В админке сайта появился новый раздел Портфолио. Тут же появились и категории.

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

Давайте попробуем создать новую работу в портфолио. Нажмите кнопку Добавить работу.

Сейчас страница создания выглядит так

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

Дополнительные настройки задаются с помощью специальных плагинов для создания произвольных полей WordPress. Есть отличный плагин ACF, который легко и быстро справится с этой задачей, но он платный. В этом примере рассмотрим плагин Carbon Fields.

Пройдите по ссылке и скачайте последнюю версию плагина. Установите его через интерфейс загрузки файла в админке.

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

Продолжаем работать в файле portfolio.php. Добавьте в него новый код.

// Добавление новых полей для портфолио
add_action( 'carbon_fields_register_fields', 'portfolio_register_options' );

function portfolio_register_options() {
    \Carbon_Fields\Container::make( 'post_meta', 'Настройки портфолио' )
    ->where( 'post_type', '=', 'portfolio' )
    ->add_fields([
        \Carbon_Fields\Field::make( 'date', 'portfolio_date', 'Дата перевозки' )
        ->set_storage_format( 'd-F-Y' )
        ->set_input_format( 'd-F-Y', 'd-F-Y' ),
        \Carbon_Fields\Field::make( 'text', 'portfolio_route', 'Маршрут перевозки' ),
        \Carbon_Fields\Field::make( 'media_gallery', 'portfolio_gallery', 'Галерея изображений' )
    ]);
}

Теперь зайдите на страницу добавления работы в портфолио. Появился новый блок с дополнительными настройками.

Заполняем все поля на странице, устанавливаем изображение портфолио, выбираем категорию из списка и сохраняем.

  • Готово!

Шаг 5.

Добавление работ в портфолио

Теперь можно наполнить раздел портфолио необходимым количеством работ. В этом примере я добавлю 4 работы из 3 разных категорий.

Кстати, на счет категорий. Вы можете их добавить через раздел Портфолио > Категории.

А можете добавлять прямо на странице создания работы портфолио.

Шаг 6.

Вывод портфолио на сайт

Когда все работы добавлены в портфолио, их можно вывести на сайте. Создадим шорткод, чтобы с помощью одной строки выводить блок с портфолио в различных местах сайта.

Чтобы получить все работы портфолио из базы данных будем использовать объект WP_Query. Это универсальный инструмент для получения любого типа записи из БД.

Создаем новый шорткод [portfolio]

// Шорткод портфолио 
add_shortcode( 'portfolio', 'portfolio_shortcode_output' );

function portfolio_shortcode_output() {
    $args = [];

    $args['query'] = new WP_Query([
        'post_type' => 'portfolio',
        'posts_per_page' => 10,
        'fields' => 'ids',
        'no_found_rows' => true,
        'update_post_meta_cache' => false,
        'update_post_term_cache' => false
    ]);

    ob_start();
    get_template_part( 'modules/portfolio/portfolio-block', null, $args );
    return ob_get_clean();
}

Получаем работы из БД, записываем объект WP_Query в массив параметров и с помощью функции get_template_part() подключаем файл modules/portfolio/portfolio-block.php . В функцию передаем массив параметров $args. Вся html-разметка блока портфолио будет находится в файле portfolio-block.php.

Обратите внимание на параметр posts_per_page – это количество работ, которые будут получены из базы.

Теперь откройте файл portfolio-block.php и добавьте в него код

<section class="portfolio">
    <div class="portfolio__wrapper">
        <div class="portfolio__title">Наше портфолио</div>
        <?php if ($args['query']->have_posts()) : ?>
            <div class="portfolio__list">
                <?php while ($args['query']->have_posts()) : ?>
                    <?php $args['query']->the_post() ?>
                    <a href="<?php echo get_the_permalink() ?>" class="portfolio__item">
                        <div class="portfolio__image">
                            <?php if (has_post_thumbnail()) : ?>
                                <?php echo get_the_post_thumbnail(get_the_ID(), 'large') ?>
                            <?php endif; ?>
                        </div>
                        <div class="portfolio__name"><?php echo get_the_title() ?></div>
                        <div class="portfolio__route">Маршрут: <?php echo carbon_get_post_meta(get_the_ID(), 'portfolio_route') ?></div>
                        <div class="portfolio__date">Дата перевозки: <?php echo wp_date('j F Y', strtotime(carbon_get_post_meta(get_the_ID(), 'portfolio_date'))) ?></div>
                    </a>
                <?php endwhile; ?>
            </div>
        <?php else : ?>
            <div class="portfolio__empty">Работ в портфолио нет.</div>
        <?php endif; ?>
    </div>
</section>

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

Когда шорткод создан, его нужно добавить в код страницы, где будет выводится блок с портфолио.

Например, открываем файл front-page.php, который отвечает за разметку главной страницы и добавляем в нужном месте

<?php echo do_shortcode( '[portfolio]' ) ?>

Чтобы портфолио выглядело прилично, добавляем стили в файл style.css

.portfolio{
    margin: 60px 0;
}

.portfolio__title{
    font-size: 32px;
    text-align: center;
}

.portfolio__list{
    margin-top: 32px;
    display: grid;
    grid-template-columns: 1fr;
    grid-gap: 48px 0;
}

@media (min-width: 768px) {
    .portfolio__list{
        grid-template-columns: repeat(2, 1fr);
        grid-gap: 48px 24px;
    }
}

.portfolio__image{
    height: 280px;
    width: 100%;
}

.portfolio__image img{
    height: 100%;
    width: 100%;
    object-fit: cover;
}

.portfolio__name{
    font-size: 18px;
    font-weight: 500;
    margin-top: 12px;
    line-height: 1.35;
}

.portfolio__date{
    margin-top: 4px;
}

.portfolio__route{
    margin-top: 10px;
}

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

Если вы владеете навыками верстки, то можете оформить вывод работ по вашему вкусу.

Шаг 7.

Добавление фильтрации портфолио

Фильтрация будет интерактивная без перезагрузки страницы. По клику на категорию будут отображать все работы из этой категории.

Нам нужно добавить изменения в код шорткода. Дополнительно в файл portfolio-block.php нужно передать массив с категориями.

Чтобы получить категории используем функцию get_terms(). В параметрах указываем название type, которое мы указывали при регистрации категории. С помощью параметра hide_empty исключаем категории, в которых нет работ.

Теперь код шорткода выглядит так

// Шорткод портфолио 
add_shortcode( 'portfolio', 'portfolio_shortcode_output' );

function portfolio_shortcode_output() {
    $args = [];

    $args['query'] = new WP_Query([
        'post_type' => 'portfolio',
        'posts_per_page' => 10,
        'fields' => 'ids',
        'no_found_rows' => true,
        'update_post_meta_cache' => false,
        'update_post_term_cache' => false
    ]);

    $args['filter'] = get_terms([
        'taxonomy' => 'type',
        'hide_empty' => true
    ]);

    ob_start();
    get_template_part( 'modules/portfolio/portfolio-block', null, $args );
    return ob_get_clean();
}

Новый код в строках 16:19

Изменения коснутся и файла portfolio-block.php. Во-первых, добавится вывод элементов фильтра [4:11], во-вторых, для каждой работы добавили data-параметр [16].

<section class="portfolio">
    <div class="portfolio__wrapper">
        <div class="portfolio__title">Наше портфолио</div>
        <?php if (! empty($args['filter'])) : ?>
            <div class="portfolio__filter">
                <div class="portfolio__filter-item active" data-filter="0">Все работы</div>
                <?php foreach ($args['filter'] as $term) : ?>
                    <div class="portfolio__filter-item" data-filter="<?php echo esc_attr( $term->term_id ) ?>"><?php echo esc_html( $term->name ) ?></div>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>
        <?php if ($args['query']->have_posts()) : ?>
            <div class="portfolio__list">
                <?php while ($args['query']->have_posts()) : ?>
                    <?php $args['query']->the_post() ?>
                    <a href="<?php echo get_the_permalink() ?>" class="portfolio__item" data-portfolio-filter="<?php echo esc_attr( implode( ',', wp_get_post_terms( get_the_ID(), 'type', [ 'fields' => 'ids' ] ) ) ) ?>">
                        <div class="portfolio__image">
                            <?php if (has_post_thumbnail()) : ?>
                                <?php echo get_the_post_thumbnail(get_the_ID(), 'large') ?>
                            <?php endif; ?>
                        </div>
                        <div class="portfolio__name"><?php echo get_the_title() ?></div>
                        <div class="portfolio__route">Маршрут: <?php echo carbon_get_post_meta(get_the_ID(), 'portfolio_route') ?></div>
                        <div class="portfolio__date">Дата перевозки: <?php echo wp_date('j F Y', strtotime(carbon_get_post_meta(get_the_ID(), 'portfolio_date'))) ?></div>
                    </a>
                <?php endwhile; ?>
            </div>
        <?php else : ?>
            <div class="portfolio__empty">Работ в портфолио нет.</div>
        <?php endif; ?>
    </div>
</section>

И еще добавим дополнительные стили для фильтра в файл style.css.

.portfolio__filter{
    display: flex;
    grid-gap: 0 16px;
    margin-top: 24px;
    overflow-x: auto;
}

.portfolio__filter-item{
    padding: 2px 12px;
    border-radius: 4px;
    cursor: pointer;
    white-space: nowrap;
}

.portfolio__filter-item.active{
    background-color: #212121;
    color: #fff;
}

.portfolio__filter-item:not(.active):hover{
    background-color: #eee;
}

Вот так выглядит портфолио вместе с фильтрами.

Откройте файл scripts.js и добавьте код для фильтрации портфолио.

(function ($) {
    $('[data-filter]').on('click', function () {
        var id = $(this).data('filter').toString(),
            $items = $('.portfolio__item');

        // Добавляем класс активному фильтру
        $(this).addClass('active').siblings().removeClass('active');

        // Показываем все работы
        if (id == '0') {
            $items.show();
            return;
        }

        // Фильтруем портфолио
        $items.each(function () {
            let terms = $(this).data('portfolio-filter').toString().split(',');

            if (terms.indexOf(id) != -1) {
                $(this).show();
            } else {
                $(this).hide();
            }
        })
    })
})(jQuery);

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

 

  • Готово! Мы полностью реализовали блок портфолио с фильтрацией работ по категориям. Далее рассмотрим как сделать отдельную страницу для вывода всех работ портфолио и создадим страницу для подробного описания каждой работы.

Шаг 8.

Отдельная страница всех работ портфолио

При регистрации нового типа записи мы указали в параметрах, что нужно создать отдельную страницу для вывода всех работ портфолио. Страница портфолио будет доступна по ссылке site.ru/portfolio. Если вы откроете эту ссылку, то сейчас будет отображаться список всех работ, но в виде обычных записей.

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

За отображения архива любых постов отвечает файл archive.php. Если мы изменим его, то поменяется стиль вообще всех постов сайта. В WordPress существует иерархия файлов шаблона, которые могут переопределять друг друга. Чтобы изменить вывод только портфолио, в корневой папке темы нужно создать новый файл archive-portfolio.php. Скопируйте в него все содержимое из файла archive.php, но в основное содержимое страницы нужно добавить вывод шорткода portfolio. Должно получиться примерно так (в зависимости от шаблона, код может немного отличаться)

<?php get_header() ?>

	<main id="primary" class="site-main">
		<?php echo do_shortcode( '[portfolio]' ) ?>
	</main>

<?php get_footer() ?>

Теперь, если вы зайдете на страницу site.ru/portfolio, то увидите оформление, которые мы делали ранее.

Важный момент. В параметрах шорткода мы указали вывод только 10 работ. Чтобы вывести все работы только на архивной странице портфолио, нужно изменить параметр posts_per_page для WP_Query.

'posts_per_page' => is_post_type_archive( 'portfolio' ) ? -1 : 10

Шаг 9.

Отдельная страница для работы портфолио

Ну и наконец рассмотрим создание отдельной страницы для работы портфолио. За вывод содержимого поста отвечает файл single.php. Чтобы изменить страницу работы портфолио нужно создать файл single-portfolio.php в папке темы.

Содержимое файла можно скопировать из single.php, а потом внести изменения. Важно, чтобы на странице был вывод заголовка the_title() и вывод контента the_content().

На страницу так же добавим дополнительную информацию: дата перевозки, маршрут перевозки и галерея фото.

Получилась такая html-разметка файла single-portfolio.php

<?php get_header() ?>

<main id="primary" class="site-main">
    <?php if (have_posts()) : ?>
        <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
            <header class="entry-header">
                <?php the_title('<h1 class="entry-title">', '</h1>'); ?>
                <div class="post-portfolio-props">
                    <div class="post-portfolio-prop"><strong>Маршрут перевозки:</strong> <?php echo esc_html(carbon_get_post_meta(get_the_ID(), 'portfolio_route')) ?></div>
                    <div class="post-portfolio-prop"><strong>Дата перевозки:</strong> <?php echo wp_date('j F Y', strtotime(carbon_get_post_meta(get_the_ID(), 'portfolio_date'))) ?></div>
                </div>
            </header>
            <div class="entry-content">
                <?php if (! empty(carbon_get_post_meta(get_the_ID(), 'portfolio_gallery'))) : ?>
                    <div class="post-portfolio-gallery">
                        <div class="swiper">
                            <div class="swiper-wrapper">
                                <?php foreach( carbon_get_post_meta(get_the_ID(), 'portfolio_gallery') as $image ) : ?>
                                <div class="swiper-slide"><?php echo wp_get_attachment_image( $image, 'full' ) ?></div>
                                <?php endforeach; ?>
                            </div>
                        </div>
                    </div>
                    <div class="post-portfolio-thumbs">
                        <div class="swiper">
                            <div class="swiper-wrapper">
                                <?php foreach( carbon_get_post_meta(get_the_ID(), 'portfolio_gallery') as $image ) : ?>
                                <div class="swiper-slide"><?php echo wp_get_attachment_image( $image, 'medium' ) ?></div>
                                <?php endforeach; ?>
                            </div>
                        </div>
                    </div>
                <?php endif; ?>
                <?php the_content(); ?>
            </div>
        </article>
    <?php endif ?>
</main>

<?php get_footer() ?>

Под заголовком выводится информация о маршруте и дате перевозки. Ниже отображается галерея фото, которые мы добавляли для каждой работы, а потом идет текстовое описание.

В style.css добавим новые стили для отдельной страницы работы.

.post-portfolio-props{
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    grid-gap: 12px 24px;
    font-size: 16px;
    margin-top: 24px;
}

.post-portfolio-gallery{
    max-width: 840px;
    margin: 48px auto 0;
}

.post-portfolio-gallery .swiper{
    height: 580px;
}

.post-portfolio-gallery .swiper-slide{
    height: auto;
    width: 100%;
}

.post-portfolio-gallery img{
    height: 100%;
    width: 100%;
    object-fit: cover;
}

.post-portfolio-thumbs{
    margin-top: 16px;
}

.post-portfolio-thumbs .swiper-wrapper{
    justify-content: center;
}

.post-portfolio-thumbs .swiper-slide{
    width: 120px;
    cursor: pointer;
    opacity: 0.6;
    height: auto;
    transform: 180ms ease;
}

.post-portfolio-thumbs .swiper-slide img{
    height: 100%;
    width: 100%;
    object-fit: cover;
}

.post-portfolio-thumbs .swiper-slide-thumb-active{
    opacity: 1;
}

А в scripts.js добавим код инициализации галереи, которая реализована на Swiper.

var thumbs = new Swiper( '.post-portfolio-thumbs .swiper', {
    slidesPerView: 'auto',
    spaceBetween: 16
} );

var slider = new Swiper( '.post-portfolio-gallery .swiper', {
    slidesPerView: 1,
    thumbs: {
        swiper: thumbs
    }
} );

И можно проверять, как это все работает на сайте.

 

  • Отдельная страница для работы портфолио готова!

Заключение

Статья получилась большая, но мы полностью рассмотрели самые важные моменты создания портфолио на сайте WordPress. Опираясь на данную инструкцию вы сможете создавать функциональные портфолио для своих проектов. Удачи 🙂