Feat: template for WC product category and term archives #7

Merged
Andrei-10 merged 1 commits from 4497 into master 4 months ago
  1. 8
      wp-content/themes/cosmopet/composer.json
  2. 59
      wp-content/themes/cosmopet/composer.lock
  3. 175
      wp-content/themes/cosmopet/functions.php
  4. 19
      wp-content/themes/cosmopet/modules/layout/assets/css/gp-style-core.css
  5. 9
      wp-content/themes/cosmopet/modules/layout/assets/css/gp-style-full.css
  6. 6
      wp-content/themes/cosmopet/modules/layout/assets/css/gp-style-normalize.css
  7. 2
      wp-content/themes/cosmopet/templates/footer.twig
  8. 1
      wp-content/themes/cosmopet/templates/front-page/front-page.twig
  9. 4
      wp-content/themes/cosmopet/templates/header.twig
  10. 4
      wp-content/themes/cosmopet/templates/layout.twig
  11. 100
      wp-content/themes/cosmopet/woocommerce/archive-product.php
  12. 70
      wp-content/themes/cosmopet/woocommerce/archive-product/archive-product.twig

@ -1,5 +1,11 @@
{
"require": {
"timber/timber": "^2.1"
"timber/timber": "^2.1",
"mindkomm/timber-integration-woocommerce": "^1.0"
},
"config": {
"allow-plugins": {
"composer/installers": true
}
}
}

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "6da1f9205429be4e1609181ef22acad2",
"content-hash": "361ab752c076e0fc5ea94a3756fab8a1",
"packages": [
{
"name": "composer/installers",
@ -152,6 +152,55 @@
],
"time": "2024-06-24T20:46:46+00:00"
},
{
"name": "mindkomm/timber-integration-woocommerce",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/mindkomm/timber-integration-woocommerce.git",
"reference": "bddcccba2fe7d58d53e81fc8f5d293fdc6e25b57"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mindkomm/timber-integration-woocommerce/zipball/bddcccba2fe7d58d53e81fc8f5d293fdc6e25b57",
"reference": "bddcccba2fe7d58d53e81fc8f5d293fdc6e25b57",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0",
"timber/timber": "^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Timber\\Integrations\\WooCommerce\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lukas Gächter",
"email": "lukas.gaechter@mind.ch",
"homepage": "https://www.mind.ch"
}
],
"description": "WooCommerce integration for Timber.",
"keywords": [
"integration",
"timber",
"twig",
"woocommerce"
],
"support": {
"docs": "https://github.com/mindkomm/timber-integration-woocommerce#documentation",
"issues": "https://github.com/mindkomm/timber-integration-woocommerce/issues",
"source": "https://github.com/mindkomm/timber-integration-woocommerce"
},
"time": "2024-05-08T09:54:00+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.0.2",
@ -716,10 +765,10 @@
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.1.0"
"platform": {},
"platform-dev": {},
"plugin-api-version": "2.6.0"
}

@ -1,6 +1,6 @@
<?php
// requere once вместо include использовать!
// require once вместо include использовать!
// доделать example module и component
require_once __DIR__ . '/vendor/autoload.php';
@ -14,6 +14,26 @@ Timber::$dirname = [
],
];
use Timber\PostCollection;
use Timber\Integrations\WooCommerce\Product as TimberProduct;
add_filter( 'timber/integrations', function ( array $integrations ): array {
$integrations[] = new \Timber\Integrations\WooCommerce\WooCommerceIntegration();
return $integrations;
} );
add_action('timber/init', function() {
// Инициализируем WooCommerce интеграцию
if (class_exists('Timber\Integrations\WooCommerce\WooCommerce')) {
Timber\Integrations\WooCommerce\WooCommerce::init();
}
});
function theme_add_woocommerce_support()
{
add_theme_support('woocommerce');
@ -398,3 +418,156 @@ require_once('modules/forms/module-ajax-controller.php');
include_module('forms');
include_module('layout');
class WooProduct extends Timber\Post {
protected $wc_product;
public function __construct ($pid = null) {
parent::__construct($pid);
$this->wc_product = wc_get_product($this->ID);
}
public function price() {
return $this->wc_product->get_price();
}
public function get_price_html() {
return $this->wc_product->get_price_html();
}
public function get_attr() {
return $this->wc_product->get_attribute('pa_compound');
}
public function get_test() {
return 'test';
}
};
add_filter('timber/post/classmap', function ($classmap) {
$custom_classmap = [
'product' => WooProduct::class,
];
return array_merge($classmap, $custom_classmap);
});
//Ajax подгрузка товаров в архиве
add_action( 'wp_ajax_nopriv_get_products', 'get_products' );
add_action( 'wp_ajax_get_products', 'get_products' );
function get_products() {
global $post;
if (function_exists('WC')) {
WC();
}
// Потом Timber
$context = Timber::context();
$context['get_page'] = empty($_POST['get_page']) ? 1 : $_POST['get_page'];
$context['criteria_for_new_product'] = date('Y-m-d', strtotime('-30 days'));
$context['get_category'] = isset($_POST['get_category']) ? $_POST['get_category'] : NULL;
$context['get_category_type'] = isset($_POST['get_category_type']) ? $_POST['get_category_type'] : NULL;
// Задаем количество постов для подзагрузки Ajax
$posts_per_page = 1;
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => $posts_per_page,
'paged' => $context['get_page'],
'has_password' => FALSE
);
$count_args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'has_password' => FALSE
);
if ($context['get_category'] != NULL) {
$categories = [
'tax_query' => array(
array(
'taxonomy' => $context['get_category_type'],
'field' => 'term_id',
'terms' => array($context['get_category']),
'operator' => 'IN'
),
array(
'taxonomy' => 'product_visibility',
'field' => 'slug',
'terms' => 'exclude-from-catalog',
'operator' => 'NOT IN'
)
)
];
$args = array_merge($args, $categories);
$count_args = array_merge($count_args, $categories);
}
$products = new WP_Query($args);
$products = new Timber\PostQuery($products, 'Timber\Integrations\WooCommerce\Product');
$context['posts'] = $products;
$context['count'] = count(Timber::get_posts($count_args));
if ($context['count'] <= $context['get_page'] * 1) $context['ended'] = true;
Timber::render( 'woocommerce/archive-product/archive-product-ajaxload.twig', $context );
die();
}
function get_product_info ($id, $type) {
$product = wc_get_product( $id );
if ($type == 'price') {
return $product->get_price();
} elseif ($type == 'weight') {
return $product->get_weight() . ' кг';
}
}
function get_add_to_cart_button ($id) {
$product = wc_get_product( $id );
return '<a href="'. $product->add_to_cart_url(). '" value="'. esc_attr( $product->get_id() ) .'"
class="ajax_add_to_cart add_to_cart_button button button--gradient button--base button--100-perc" data-product_id="'. $id .'">'. pll__('Добавить в корзину') .'</a>';
}
function get_collection_siblings ($term) {
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'order' => 'ASC',
'order_by' => 'name',
'tax_query' => [
[
'taxonomy' => 'pa_collection',
'terms' => $term,
'field' => 'id',
]
],
);
$siblings = get_posts($args);
$sibl_arr = [];
foreach( $siblings as $sibling ) {
$sibl_arr [] = $sibling;
}
return $sibl_arr;
}

@ -56,6 +56,20 @@
/* Fonts */
--font-craftwork: 'Craftwork Grotest', sans-serif;
--font-abel: 'Abel', serif;
--text-dark: #2b2b3b;
--text-red: #fa0505;
--text-green: #2ED15D;
--text-0: #000;
--background-white: #fff;
--background-black: #121212;
--background-grey: #f2f2f2;
--background-green: #2ED15D;
--background-green-white: #f4fff0;
--background-9: #999;
--gradient-blue: radial-gradient(346.57% 244.17% at 149.73% -58.39%, rgb(15, 88, 129) 0%, rgb(30, 164, 156) 51.21689438819885%, rgb(118, 206, 117) 80.70731163024902%, rgb(236, 243, 159) 91.14583134651184%);
--gradient-turquoise: radial-gradient(346.57% 244.17% at 149.73% -58.39%, rgb(117, 196, 240) 0%, rgb(126, 231, 225) 51.21689438819885%, rgb(181, 228, 180) 80.70731163024902%, rgb(237, 244, 164) 91.14583134651184%);
--gradient-red: linear-gradient(22deg, #f44242 0%, #569ef0 100%);
}
body {
@ -189,4 +203,9 @@ textarea{
height: 29px;
padding: 7px;
}
}
.wrapper {
margin: 0 auto;
max-width: 1600px;
}

@ -74,11 +74,6 @@ address {
font-style: normal;
}
.wrapper {
width: 100%;
overflow: hidden;
min-height: 100svh;
}
ul,
ol,
@ -144,6 +139,10 @@ body {
font-weight: 500;
}
body.bg-white {
background: var(--main_white);
}
.container {
max-width: 1232px;
margin: 0 auto;

@ -44,12 +44,6 @@ address {
font-style: normal;
}
.wrapper {
width: 100%;
overflow: hidden;
min-height: 100svh;
}
ul,
ol,
dl {

@ -1,6 +1,6 @@
{% set current_path = template_path ~ '/modules/footer' %}
<footer class="footer">
<div class="container">
<div class="wrapper">
<div class="footer-top">
<div class="footer-content__wrap">
<div class="footer-content">

@ -1,4 +1,5 @@
{% set bodyClass = 'main-np' %}
{% set headerClass = 'white' %}
{% extends 'layout.twig' %}

@ -8,7 +8,7 @@
{% set blog_url = '/' %}
{% endif %}
<header class="header white">
<header class="header {{headerClass}}">
<div class="header__menu-block">
<div class="header__pc-menu">
<div class="header-pc-menu__content">
@ -127,7 +127,7 @@
</div>
</div>
</div>
<div class="header__content container">
<div class="header__content wrapper">
<button class="header__open-menu" id="phone-menu">
</button>

@ -8,12 +8,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<body class="{{bodyClass}}">
{% include 'header.twig' %}
<main>
<main class="{{ mainClass }}">
{% block content %}
{% endblock %}
</main>

@ -1,39 +1,75 @@
<?php
// function get_blog_posts_data() {
// // $args = array(
// // 'post_type' => 'post',
// // 'posts_per_page' => 6,
// // );
// // $posts = new WP_Query($args);
// $formatted_posts = array();
// if (have_posts()) {
// while (have_posts()) {
// the_post();
// $formatted_post = array(
// 'title' => get_the_title(),
// 'link' => get_permalink(),
// 'excerpt' => get_the_excerpt(),
// 'thumbnail' => has_post_thumbnail()
// ? get_the_post_thumbnail_url(get_the_ID(), 'full')
// : get_template_directory_uri() . "/static/front-page/img/blog_card-img.jpg"
// );
// $formatted_posts[] = $formatted_post;
// }
// wp_reset_postdata();
// }
// return $formatted_posts;
// }
$context = Timber::get_context();
$context['posts'] = Timber::get_posts();
wp_enqueue_script( 'shop_scripts', get_template_directory_uri() . '/woocommerce/assets/js/gp-main.js', 'jquery', '', true);
wp_enqueue_style( 'shop_styles_core', get_template_directory_uri() . '/woocommerce/assets/css/gp-style-core.css');
wp_enqueue_style( 'shop_styles_desktop', get_template_directory_uri() . '/woocommerce/assets/css/gp-style-desktop.css');
wp_enqueue_style( 'shop_styles_mobile', get_template_directory_uri() . '/woocommerce/assets/css/gp-style-mobile.css');
wp_enqueue_style( 'shop_styles_tablet', get_template_directory_uri() . '/woocommerce/assets/css/gp-style-tablet.css');
wp_enqueue_style( 'shop_styles_order', get_template_directory_uri() . '/woocommerce/assets/css/gp-style-order.css');
wp_enqueue_style( 'shop_styles_ultra', get_template_directory_uri() . '/woocommerce/assets/css/gp-style-ultra.css');
$context = Timber::context();
//$context['posts'] = Timber::get_posts();
$context['criteria_for_new_product'] = date('Y-m-d', strtotime('-30 days'));
// Задаем количество постов для подзагрузки Ajax
$context['posts_per_page'] = 1;
$queried_object = get_queried_object();
if (is_product_category() || is_tax()) {
$term_id = $queried_object->term_id;
$context['category_type'] = 'product_cat';
$context['category_id'] = $term_id;
$context['category'] = get_term($term_id, 'product_cat');
$context['category_link'] = get_term_link($term_id, 'product_cat');
$context['category_title'] = single_term_title('', false);
}
if (is_tax()) {
$context['category_type'] = $queried_object->taxonomy;
$context['category'] = get_term($term_id, $context['category_type']);
$context['category_link'] = get_term_link($term_id, $context['category_type']);
$context['category_title'] = single_term_title('', false);
}
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => $context['posts_per_page'],
'paged' => 1,
'has_password' => FALSE
);
$count_args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'has_password' => FALSE
);
if ($context['category_id'] != NULL) {
$categories = [
'tax_query' => array(
array(
'taxonomy' => $context['category_type'],
'terms' => $context['category_id'],
'operator' => 'IN'
),
array(
'taxonomy' => 'product_visibility',
'field' => 'slug',
'terms' => 'exclude-from-catalog',
'operator' => 'NOT IN'
)
)
];
$args = array_merge($args, $categories);
$count_args = array_merge($count_args, $categories);
}
$context['posts'] = Timber::get_posts($args);
$context['count'] = count(Timber::get_posts($count_args));
Timber::render('archive-product/archive-product.twig', $context);

@ -1,12 +1,72 @@
{% set bodyClass = 'main-np' %}
{% set bodyClass = 'bg-white' %}
{% set mainClass = 'wrapper' %}
{% extends 'layout.twig' %}
{% block content %}
{% for post in posts %}
{{ post.title }}
{#% do action('woocommerce_before_main_content') %}#}
<div class="breadcrumbs">
<a href="/" class="breadcrumbs__item">
{{ function('pll_e', 'Главная') }}
</a>
<a href="/shop" class="breadcrumbs__item">
{{ function('pll_e', 'Продукция') }}
</a>
{% if category %}
<a href="{{ category_link }}" class="breadcrumbs__item">
{{ category_title }}
</a>
{% endif %}
</div>
{#<div class="before-shop-loop"">
{% do action('woocommerce_before_shop_loop') %}
</div>#}
<div class="product">
<div class="product__header">
<p class="product__title">
{% if category %}
{{ category.name }}
{% else %}
{{ function('pll_e', 'Продукция') }}
{% endif %}
</p>
<button class="button button--gradient button--high button--icon button--filter">
{{ function('pll_e', 'Фильтры') }}
</button>
</div>
<!--<div class="product__tag">
<button class="product-tag__item">
<div class="product-tag-item__content">
<p class="product-tag-item__text">Для собак</p>
<div class="product-tag-iteИ m__button">
</div>
</div>
</button>
</div>-->
<div class="product__main">
{% for post in posts %}
{% include '/woocommerce/archive-product/archive-product-tease.twig' with {post: post} %}
{% endfor %}
</div>
<div class="product__footer product__footer--error">
{% if posts_per_page < count %}
<button class="button button--white" id="load-more-products" data-category_id="{{ category_id }}" data-category_type="{{ category_type }}">
{{ function('pll_e', 'Загрузить еще') }}
</button>
{% endif %}
</div>
</div>
{% endfor %}
{#{% do action('woocommerce_after_shop_loop') %}
{% do action('woocommerce_after_main_content') %}#}
{% include '/woocommerce/archive-product/archive-product-modal.twig' %}
{% endblock %}
Loading…
Cancel
Save