# 经典主题开发手册

---

**注意:** 本文档面向经典主题的开发。请查看此[其他文档](docs/theming/block-theme-development/theming-woo-blocks)，了解块主题的开发。

---

从版本 3.3 开始，WooCommerce 与所有 WordPress 主题兼容，即使这些主题不是专门为 WooCommerce 设计的，并且没有正式声明支持。模板会嵌入到内容中，这使得您的网站看起来更加自然。

默认情况下，非 WooCommerce 主题也包含以下功能：

- 启用缩放功能：允许用户放大/缩小产品图片。
- 启用灯箱功能：产品画廊图片会弹出，以便用户更仔细地查看。
- 启用评论功能，而不是评价：访客/买家可以留下评论，而不是产品评分或评价。

如果您希望对 WooCommerce 元素的布局进行更多控制，或者需要完整的评价支持，您的主题需要与 WooCommerce 集成。有几种不同的方法可以实现这一点，下面将详细介绍。

## 主题集成

有三种可能的将 WooCommerce 与主题集成的方案。如果您使用的是 WooCommerce 3.2 或更早版本（**强烈不建议**），则需要使用以下一种方法，以确保 WooCommerce 商店和产品页面在您的主题中正确显示。如果您使用的是 WooCommerce 3.3 或更高版本，则只有在自动集成无法满足您的需求时，才需要进行主题集成。

### 使用 `woocommerce_content()`

此解决方案允许您在主题中创建一个新的模板页面，该页面用于**所有 WooCommerce 分类和帖子类型显示**。虽然这是一种简单的通用解决方案，但它有一个缺点，即此模板用于**所有 WooCommerce 分类**（产品分类等）和**帖子类型**（产品归档、单个产品页面）。建议开发者使用以下钩子（hooks）来实现更精细的控制。

要设置此模板页面：

1. **复制 `page.php`:** 复制您主题的 `page.php` 文件，并将其重命名为 `woocommerce.php`。该文件的路径应遵循以下模式：`wp-content/themes/YOURTHEME/woocommerce.php`。
2. **编辑您的页面 (woocommerce.php)**：使用文本编辑器打开您新创建的 `woocommerce.php` 文件。
3. **替换循环 (loop)**：接下来，您需要找到循环（loop）（请参阅 [The_Loop](https://codex.wordpress.org/The_Loop)）。循环通常以类似这样的代码开始：

```php
<?php if ( have_posts() ) :
```

它通常以类似这样的代码结束：

```php
<?php endif; ?>
```

不同主题的循环结构可能有所不同。找到循环后，**将其删除**。然后，在此处插入以下代码：

```php
<?php woocommerce_content(); ?>
```

这将使用**WooCommerce 的循环**。保存文件。完成。

**注意:** 当您在主题文件夹中创建 `woocommerce.php` 时，您将无法覆盖 `woocommerce/archive-product.php` 自定义模板，因为 `woocommerce.php` 的优先级高于 `archive-product.php`。这是为了防止显示问题。

### 使用钩子

钩子方法涉及的步骤更多，但它也更灵活。这类似于我们在创建主题时使用的方法。这也是我们与 WordPress 默认主题集成的方法。

在您主题的 `functions.php` 文件中插入几行代码。

首先，取消 WooCommerce 的包装函数：

```php
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10);
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10);
```

然后，添加您自己的函数来显示您的主题所需的包装：

```php
add_action('woocommerce_before_main_content', 'my_theme_wrapper_start', 10);
add_action('woocommerce_after_main_content', 'my_theme_wrapper_end', 10);

function my_theme_wrapper_start() {
    echo '<section id="main">';
}

function my_theme_wrapper_end() {
    echo '</section>';
}
```

请确保标记与您的主题相匹配。如果您不确定应该使用哪些类或 ID，请查看您主题的 `page.php` 文件以获取指导。

**尽可能使用钩子来添加或移除内容。 这种方法比覆盖模板更健壮。** 如果您覆盖了一个模板，则每次文件更改时都必须更新该模板。 如果您使用的是钩子，则只有在钩子发生更改时才需要更新，而这种情况发生的频率要低得多。

### 使用模板覆盖

有关如何使用您自己的自定义模板覆盖 WooCommerce 模板的**信息**，请参阅下面的**模板结构**部分。 这种方法需要比基于钩子的方法更多的维护，因为模板需要保持与 WooCommerce 核心模板的同步。

## 声明 WooCommerce 支持

如果您在主题中使用自定义的 WooCommerce 模板覆盖，则需要使用 `add_theme_support` 函数来声明 WooCommerce 支持。 只有声明了 WooCommerce 支持的主题才能启用 WooCommerce 模板覆盖。 如果您在主题中未声明 WooCommerce 支持，WooCommerce 会假定该主题未针对 WooCommerce **兼容性**进行设计，并将使用基于短代码的、不受支持的主题**渲染**方式来**显示**商店。

声明 WooCommerce 支持非常简单，只需在您主题的 `functions.php` 文件中添加一个函数。

### 基本用法

```php
function mytheme_add_woocommerce_support() {
    add_theme_support( 'woocommerce' );
}

add_action( 'after_setup_theme', 'mytheme_add_woocommerce_support' );
```

请确保您使用的是 `after_setup_theme` 钩子，而不是 `init` 钩子。 更多关于此的信息，请参阅 [关于 `add_theme_support` 的**文档**](https://developer.wordpress.org/reference/functions/add_theme_support/)。

### 使用 `Settings`

```php
function mytheme_add_woocommerce_support() {
    add_theme_support( 'woocommerce', array(
        'thumbnail_image_width' => 150,
        'single_image_width'    => 300,

        'product_grid'          => array(
            'default_rows'    => 3,
            'min_rows'        => 2,
            'max_rows'        => 8,
            'default_columns' => 4,
            'min_columns'     => 2,
            'max_columns'     => 5,
        ),
    ) );
}

add_action( 'after_setup_theme', 'mytheme_add_woocommerce_support' );
```

这些是可选的 `主题` 设置，您可以在声明 WooCommerce 支持时进行设置。

`thumbnail_image_width` 和 `single_image_width` 将设置商店的 `图片尺寸`。 如果在添加 `主题` 支持时未声明这些设置，用户可以在自定义工具栏的 **WooCommerce > 产品图像** `部分` 中设置 `图片尺寸`。

`product_grid` 设置允许 `开发者` 设置商店的默认、最小和最大 `列` 和行设置。 用户可以在自定义工具栏的 **WooCommerce > 产品目录** `部分` 中设置行和 `列`。

### 产品画廊功能（缩放、滑动、灯箱）

3.0.0 版本引入的产品画廊 ([更多信息请阅读此处](https://developer.woocommerce.com/2016/10/19/new-product-gallery-merged-in-to-core-for-2-7/)) 使用 Flexslider、Photoswipe 和 jQuery Zoom 插件，提供滑动、`灯箱` 和其他实用功能。

在 `版本` 3.0、3.1 和 3.2 中，新的画廊默认情况下是禁用的，需要使用代码片段（如下所示）或使用兼容的 `主题` 启用。 这是因为 `主题` 经常会禁用 WooCommerce 画廊，并用自己的 `脚本` 替换它。

在 `版本` 3.3+ 中，对于 WooCommerce 兼容的 `主题` 来说，画廊默认情况下是禁用的，除非它们声明支持它（如下所示）。 没有 WooCommerce 支持的第三方 `主题` 默认情况下会启用画廊。

要启用您 `主题` 中的画廊，您可以像这样声明支持：

```php
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
```

您不必支持画廊的所有三个 `部分`；您可以选择您需要的特性。 如果某个特性未启用，则不会加载相应的 `脚本`，并且画廊代码将不会在产品页面上执行。

如果启用了画廊功能（例如，您有一个启用了它们的 `主题`，或者您正在使用一个与 WooCommerce 不兼容的 `主题`），您可以使用 `remove_theme_support` 禁用它们：

```php
remove_theme_support( 'wc-product-gallery-zoom' );
remove_theme_support( 'wc-product-gallery-lightbox' );
remove_theme_support( 'wc-product-gallery-slider' );
```

您可以禁用任何 `部分`；您不必禁用所有功能。

## 模板结构

WooCommerce 模板文件包含 **标记** 和 **模板结构**，用于您商店的 **前端** 以及 **HTML 邮件**。 如果需要在 HTML 中进行某些结构性更改，您应该覆盖一个模板。

打开这些文件时，您会发现它们都包含 **钩子**，允许您添加或移动内容，而无需直接编辑模板文件本身。 这种方法可以防止升级问题，因为模板文件可以完全保持不变。

模板文件位于 `**/woocommerce/templates/**` 目录中。

### 如何编辑文件

使用 *覆盖* 以一种 **安全升级** 的方式编辑文件。 将它们复制到您主题中的一个名为 `/woocommerce` 的目录中，保持相同的目录结构，但删除 `/templates/` 子目录。

例如：要覆盖管理订单通知，请将 `wp-content/plugins/woocommerce/templates/emails/admin-new-order.php` 复制到 `wp-content/themes/yourtheme/woocommerce/emails/admin-new-order.php`。

复制的文件现在将覆盖 WooCommerce 的默认模板文件。

**警告：** 在覆盖模板时，请勿删除任何 WooCommerce 钩子。 否则，插件将无法挂载以添加内容。

**警告：** 请勿在核心插件本身中编辑这些文件，因为在升级过程中，它们会被覆盖，并且所有自定义内容都将丢失。

## CSS 结构

在 `assets/css/` 目录中，您将找到负责默认 WooCommerce 布局样式的样式表。

需要关注的文件是 `woocommerce.scss` 和 `woocommerce.css`。

- `woocommerce.css` 是压缩的样式表，它不包含任何空格、缩进等。 这使得该文件加载速度非常快。 插件会引用此文件，并声明所有 WooCommerce 样式。
- `woocommerce.scss` 不直接由插件使用，而是由开发 WooCommerce 的团队使用的。 我们使用 [SASS](http://sass-lang.com/) 在此文件中生成第一个文件中的 CSS。

CSS 的编写方式是使其与尽可能多的主题兼容，通过为所有布局样式使用基于百分比的宽度。 但是，您可能希望进行自己的调整。

### 修改

为了避免升级问题，我们建议不要编辑这些文件，而是将它们用作参考。

如果您只想进行更改，我们建议将一些覆盖样式添加到您的主题样式表中。 例如，将以下代码添加到您的主题样式表中，以将 WooCommerce 按钮的颜色更改为黑色，而不是默认颜色：

```css
a.button, 
button.button, 
input.button, 
#review_form #submit {
    background:black; 
}
```

WooCommerce 还将主题名称（以及其他有用的信息，例如正在查看的页面类型）作为类添加到 `body` 标签中，这对于覆盖样式非常有用。

### 禁用 WooCommerce 样式

如果您计划进行重大更改，或者从头开始创建一个主题，那么您可能更喜欢您的主题完全不引用 WooCommerce 的样式表。 您可以通过将以下代码添加到您主题的 `functions.php` 文件中，来告诉 WooCommerce 不要使用默认的 `woocommerce.css` 文件：

```php
add_filter( 'woocommerce_enqueue_styles', '__return_false' );
```

通过这个定义，您的主题将不再使用 WooCommerce 的样式表，而是为您提供一个空白的画布，您可以在此基础上构建您自己的布局和样式。

第一次从头开始为 WooCommerce 主题进行样式设置是一项艰巨的任务。 有许多不同的网页和元素需要进行样式设置，如果您是 WooCommerce 的新手，您可能不熟悉其中的许多元素。 可以在此 [WooCommerce 主题测试清单](https://developer.files.wordpress.com/2017/12/woocommerce-theme-testing-checklist.pdf) 中找到 WooCommerce 元素的非完整列表。