Продолжаем наш разговор про Woocommerce. Тема создания электронной коммерции на базе так хорошо всем знакомого WordPress становится все более популярной. И во многом это произошло благодаря Woocommerce. Есть, конечно, и другие решения, например, cart66 или wp-e-commerce. Я не буду тут устраивать баттл, какой плагин круче, просто замечу такую вещь: обновления для Woocommerce выходят последнее время несколько раз в месяц, что говорит о повышенном внимании разработчиков к этому продукту.
Поэтому и мы, следуя тренду, будем писать статьи, полезные всем, кто разрабатывает сайты с использованием woocommerce.
В прошлой статье был описан способ скрыть продукты из определенных категорий на главной странице магазина. А сегодня поговорим об одной особенности шаблонов Woocommerce, из-за которой иногда слетает верстка, особенно при использовании шаблонов, изначально не заточенных под этот плагин. Проблема, обычно, проявляется в том, что некоторые страницы магазина — страница списка товаров, или страница отдельного товара, или страница списка категорий — отображаются некорректно, а именно: расползаются на всю ширину листа, выходя за пределы страницы.
На примере решения данной проблемы мы с вами очень подробно, практически детально разберем механизм работы шаблонов Woocommerce. Я ставлю своей задачей не просто впихнуть в вас готовое решение, а помочь вам понять сам принцип, зная который, вы сможете в дальнейшем самостоятельно решать аналогичные задачи. Поехали!
Как известно, Woocommerce для страниц магазина использует свои собственные шаблоны, которые подгружает автоматически. Они находятся в папке templates, в директории плагина. В данном случае, нас интересуют два файла — archive-product.php (отвечает за вывод списка продуктов) и single-product.php (вывод отдельной карточки продукта). В каждом из них мы найдем вот такой код:
/** * woocommerce_before_main_content hook * * @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content) * @hooked woocommerce_breadcrumb - 20 */ do_action('woocommerce_before_main_content'); ?>
Это в начале, а в конце такой:
/** * woocommerce_after_main_content hook * * @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content) */ do_action('woocommerce_after_main_content');
Английский нам в помощь, в комментариях к этим сниппетам указано, что они просто начинают и закрывают контейнер, внутри которого и находится вывод элементов магазина. Естественно, что если класс или id этого контейнера не описан у вас в файле стилей, то верстка будет ломаться.
Давайте рассмотрим немного принцип работы шаблонов Woocommerce.
- Woocommerce имеет собственные шаблоны для вывода контента магазина, эти шаблоны находятся в папке templates, расположенной в директории плагина. Любой файл этой папки, для удобства работы с ним, может быть скопирован в папку вашего шаблона WordPress, где этот файл можно менять как угодно, и все эти изменения сохранятся после обновления Woocommerce. Для этого в папке вашего шаблона создаете папку Woocommerce и в нее копируете те файлы (с учетом структуры подпапок), которые собираетесь менять.
- Шаблоны Woocommerce построены с помощью хуков на основе функции do_action. Это очень удобно, потому что позволяет переписать любой участок шаблона на свой лад, создавая свои хуки в файле functions.php и затем подключая их в скопированные файлы. Практически все функции шаблонов и хуки к ним описаны в файлах woocommerce-hooks.php и woocommerce-template.php, которые находятся в корневой папке плагина.
Эти две особенности и помогут нам решить проблему с версткой, а, если вы поймете сам принцип работы шаблонов Woocommerce, то сможете писать и свои хуки и делать с вашей e-коммерцией вообще все, что захотите.
Для начала найдем вывод хука woocommerce_before_main_content, он встречается в файле хуков шаблона два раза. Я не буду здесь описывать механизм работы функций do_action и add_action (вы можете о них прочитать в кодексе WordPress), но можно понять, что один хук позволяет подключать сразу несколько функций. В данном случае, подключается открывающие теги контейнера и хлебные крошки. А хук woocommerce_after_main_content подключает только закрывающий тег.
Если говорить конкретнее, то подключаются следующие функции — woocommerce_output_content_wrapper и woocommerce_output_content_wrapper_end. Они описаны в файле woocommerce-template.php:
if ( ! function_exists( 'woocommerce_output_content_wrapper' ) ) { /** * Output the start of the page wrapper. * * @access public * @return void */ function woocommerce_output_content_wrapper() { woocommerce_get_template( 'shop/wrapper-start.php' ); } } if ( ! function_exists( 'woocommerce_output_content_wrapper_end' ) ) { /** * Output the end of the page wrapper. * * @access public * @return void */ function woocommerce_output_content_wrapper_end() { woocommerce_get_template( 'shop/wrapper-end.php' ); } }
То есть, мягко говоря, система нас футболит от файла к файлу. Ну что ж, посмотрим, что же находится в файлах shop/wrapper-start.php и shop/wrapper-end.php, которые расположены, как указывает функция, в папке с шаблонами.
Просто, как я и писал выше, подключается два дива с классами container и main, внутри которых уже и выводится содержимое страниц магазина. Естественно, что если эти дивы не описаны в вашей таблице стилей (в файле style.css шаблона), то ничего удивительного, что верстка летит.
Я думаю, что на данном этапе у вас должно возникнуть два вопроса:
- Почему шаблоны Woocommerce так запутаны? Неужели нельзя было все описать в одном файле, а надо было раскидать подключение двух дивов аж по 5 файлам?
- Что нам делать дальше?
На первый вопрос — это называется разделение представления и объектов. Все объекты описаны отдельно, все представление объектов описано отдельно. Это дает нам что-то вроде конструктора — есть отдельные, описанные отдельно друг от друга готовые блоки. Вы можете брать их, комбинировать в нужном вам порядке и даже редактировать некоторые из них без опасения, что это как-то затронет другие блоки. На самом деле, это просто классно! Вы можете полностью переписать весь код магазина, просто используя уже готовые функции, предоставленные разработчиками. Таким образом, даже особо не разбираясь в программировании, вы можете стать программистом. По крайней мере в глазах заказчиков)) Достаточно научиться понимать некоторые ключевые функции WordPress (вроде do_action)
Cо вторым вопросом, как вы догадываетесь, может быть несколько вариантов. Самый простой — раз классы не описаны, значит, надо их написать. Плюс — сделать это достаточно быстро. Минус — зачем нам лишний код?
Второй вариант — переписать хуки и исключить вообще данный код из шаблона. Минус — больше возни, чем в первом способе. Плюс — все правильно, аккуратно. Кроме того, вы получаете непосредственный опыт работы с кодом. Поэтому, второй способ и будем разбирать.
- Первым делом, копируем в свежесозданную папку Woocommerce в папке вашего шаблона файлы archive-product.php и single-product.php.
- Код, который отвечает за вывод закрывающего тега, мы полностью вырезаем, а первый код немного подправим — уберем оттуда открывающий тег и оставим хлебные крошки.
- Для этого создадим новый хук в файле funcions.php. Назовем его my_super_hook и через него выведем функцию хлебных крошек Woocommerce.
add_action( 'my_super_hook', 'woocommerce_breadcrumb');
- Вставим новый хук вместо первого кода с открывающими дивами.
do_action( 'my_super_hook');
После этого лишние дивы пропадут, при этом, хлебные крошки сохранятся, но верстка все равно лучше не станет. Как думаете, почему?
Правильно! Контейнер Woocommerce мы снесли, а теперь нужно подключить родной контейнер вашего шаблона.
Откройте любой файл шаблона, который отвечает за вывод контента — index.php, single.php, page.php, archive.php, — и возьмите оттуда открывающий и закрывающий теги контейнера (или контейнеров, если их у вас несколько) основного контента (без боковой колонки) и добавьте их в те места скопированных шаблонов Woocommerce, где мы вырезали код их контейнера.
Вот и все! Если у вас остались какие-то вопросы, вам что-то неясно по работе с функциями или у вас есть свой способ решения данной проблемы — пишите в комментариях.