WordPress主题开发:如何基于`Full Site Editing (FSE)`和`block.json`构建无代码主题,并利用Theme.json进行全局控制?

WordPress 无代码 FSE 主题开发:基于 block.jsontheme.json

大家好,今天我们来聊聊如何基于 WordPress 的 Full Site Editing (FSE)block.json 构建一个真正的“无代码”主题,并利用 theme.json 文件进行全局样式控制。很多人可能觉得“无代码”只是个噱头,但在 FSE 的语境下,通过合理利用 WordPress 提供的机制,我们可以最大限度地减少甚至避免编写 PHP 代码,从而专注于设计和内容。

1. 理解 FSE 和 Block Themes 的基础

在深入实践之前,我们需要明确几个核心概念:

  • Full Site Editing (FSE): FSE 是 WordPress 的一项重大革新,它允许我们使用区块编辑器来构建网站的任何部分,包括头部、页脚、侧边栏等,而不再局限于文章内容区域。这意味着整个网站都可以像构建一篇博客文章一样,通过拖拽和配置区块来完成。

  • Block Themes: 采用 FSE 的主题被称为 Block Themes。与传统主题不同,Block Themes 不依赖于 PHP 模板文件来定义页面结构,而是使用 HTML 模板和区块的组合。

  • block.json: 每个区块都有一个 block.json 文件,用于定义区块的元数据,例如区块的名称、描述、属性、支持的功能、编辑界面和渲染逻辑。它决定了区块在编辑器中的行为和外观。

  • theme.json: theme.json 文件是 Block Theme 的核心配置文件。它定义了主题的全局样式和设置,包括颜色、排版、间距、边框等。通过修改 theme.json,我们可以统一控制整个网站的外观,而无需修改单个区块的代码。

2. 构建 Block Theme 的基本步骤

一个最基本的 Block Theme 至少需要以下几个文件:

  1. style.css: 主题的样式表,用于提供主题的基本信息和引入必要的 CSS 样式。

  2. theme.json: 主题的全局配置文件,定义主题的样式、设置和模板。

  3. index.php: 主题的入口文件,主要负责加载区块模板。在无代码主题中,这个文件可以非常简单。

  4. templates/ 目录: 存放 HTML 模板文件,定义网站的页面结构。例如 index.htmlsingle.htmlpage.html 等。

  5. parts/ 目录: 存放可重用的模板片段,例如头部、页脚等。

下面我们逐步创建一个简单的 Block Theme。

2.1 创建主题目录和 style.css

首先,在 wp-content/themes/ 目录下创建一个新的主题目录,例如 nocode-theme

然后,在这个目录下创建一个 style.css 文件,内容如下:

/*
Theme Name:   No-Code Theme
Theme URI:    https://example.com/nocode-theme
Author:       Your Name
Author URI:    https://example.com
Description:  A simple no-code block theme.
Version:      1.0
Requires at least: 5.9
Tested up to: 6.4
Requires PHP: 7.0
License:      GNU General Public License v2 or later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  nocode-theme
*/

这个文件提供了主题的基本信息,WordPress 可以识别并激活这个主题。

2.2 创建 theme.json 文件

这是 Block Theme 的核心文件。在主题目录下创建一个 theme.json 文件,并添加一些基本的样式设置。

{
  "version": 2,
  "settings": {
    "appearanceTools": true,
    "color": {
      "palette": [
        {
          "slug": "primary",
          "color": "#007bff",
          "name": "Primary"
        },
        {
          "slug": "secondary",
          "color": "#6c757d",
          "name": "Secondary"
        },
        {
          "slug": "light",
          "color": "#f8f9fa",
          "name": "Light"
        },
        {
          "slug": "dark",
          "color": "#343a40",
          "name": "Dark"
        }
      ],
      "gradients": [
        {
          "slug": "vivid-cyan-blue-to-vivid-purple",
          "gradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)",
          "name": "Vivid Cyan Blue to Vivid Purple"
        }
      ],
      "link": true
    },
    "typography": {
      "fontFamilies": [
        {
          "fontFamily": "-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif",
          "name": "System Font",
          "slug": "system-font"
        }
      ],
      "fontSizes": [
        {
          "size": "16px",
          "slug": "small",
          "name": "Small"
        },
        {
          "size": "20px",
          "slug": "normal",
          "name": "Normal"
        },
        {
          "size": "24px",
          "slug": "large",
          "name": "Large"
        },
        {
          "size": "32px",
          "slug": "x-large",
          "name": "X-Large"
        }
      ]
    },
    "layout": {
      "contentSize": "800px",
      "wideSize": "1200px"
    }
  },
  "styles": {
    "elements": {
      "link": {
        "color": {
          "text": "var(--wp--preset--color--primary)"
        }
      }
    }
  }
}

这个 theme.json 文件定义了:

  • version: theme.json 文件的版本号,当前版本是 2。
  • settings: 主题的设置,包括颜色、排版、布局等。
    • appearanceTools: 启用外观工具,允许用户在编辑器中自定义区块的样式。
    • color: 定义颜色调色板和渐变色。
    • typography: 定义字体族和字体大小。
    • layout: 定义内容区域和宽内容区域的宽度。
  • styles: 定义全局样式,例如链接的颜色。

通过修改 theme.json 文件,我们可以轻松地改变整个网站的外观,而无需编写任何 CSS 代码。

2.3 创建 index.php 文件

在主题目录下创建一个 index.php 文件,内容如下:

<?php
/**
 * The main template file
 *
 * This is the most generic template file in a WordPress theme
 * and one of the two required files for a theme (the other being style.css).
 * It is used to display a page when nothing more specific matches a query.
 * E.g., it puts together the home page when no home.php file exists.
 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package nocode-theme
 */

get_template_part( 'template-parts/header' );

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();
        get_template_part( 'template-parts/content', get_post_type() );
    }
} else {
    get_template_part( 'template-parts/content', 'none' );
}

get_template_part( 'template-parts/footer' );

虽然我们目标是无代码,index.php 仍然是必要的。这个文件负责加载模板片段,例如头部、内容和页脚。 在 FSE 的世界里,index.php 的作用有所减弱,主要负责加载模板文件,而模板文件本身则使用 HTML 和区块构建。 注意这里仍然保留了 get_template_part,稍后我们会创建 template-parts 目录,并在其中放置 header.phpfooter.phpcontent.php

2.4 创建模板文件和模板片段

在主题目录下创建 templates 目录和 parts 目录。

  • templates/index.html:

    <!-- wp:template-part {"slug":"header","tagName":"header"} /-->
    
    <!-- wp:query -->
    <div class="wp-block-query">
        <!-- wp:post-template -->
            <!-- wp:post-title {"level":3,"isLink":true} /-->
            <!-- wp:post-excerpt /-->
        <!-- /wp:post-template -->
    </div>
    <!-- /wp:query -->
    
    <!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

    这个文件定义了主页的结构。它包含了头部、文章列表和页脚。 <!-- wp:query --> 区块用于显示文章列表。 <!-- wp:post-template --> 区块定义了每篇文章的显示方式。

  • parts/header.html:

    <!-- wp:group {"layout":{"type":"constrained"}} -->
    <header class="wp-block-group">
        <!-- wp:site-title /-->
        <!-- wp:navigation /-->
    </header>
    <!-- /wp:group -->

    这个文件定义了网站的头部。它包含了网站标题和导航菜单。

  • parts/footer.html:

    <!-- wp:group {"layout":{"type":"constrained"}} -->
    <footer class="wp-block-group">
        <!-- wp:paragraph -->
        <p>Copyright &copy; <?php echo date('Y'); ?>. All rights reserved.</p>
        <!-- /wp:paragraph -->
    </footer>
    <!-- /wp:group -->

    这个文件定义了网站的页脚。它包含了版权信息。

  • template-parts/header.php:

<header>
    <?php wp_nav_menu( array( 'theme_location' => 'primary' ) ); ?>
</header>
  • template-parts/footer.php:
<footer>
    <p>&copy; <?php echo date("Y"); ?> My Theme</p>
</footer>
  • template-parts/content.php:
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
        <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
    </header><!-- .entry-header -->

    <div class="entry-content">
        <?php
        the_content();

        wp_link_pages(
            array(
                'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'my-theme' ),
                'after'  => '</div>',
            )
        );
        ?>
    </div><!-- .entry-content -->

    <footer class="entry-footer">
        <?php
        if ( 'post' === get_post_type() ) {
            ?>
            <div class="entry-meta">
                <?php
                my_theme_posted_on();
                my_theme_posted_by();
                ?>
            </div><!-- .entry-meta -->
            <?php
        }
        ?>
    </footer><!-- .entry-footer -->
</article><!-- #post-<?php the_ID(); ?> -->

虽然我们尽量避免 PHP 代码,但一些动态内容,比如版权年份,仍然需要 PHP 来实现。

2.5 激活主题并自定义

现在,你可以激活这个主题,并在 WordPress 编辑器中自定义网站的外观。你可以修改 theme.json 文件来改变全局样式,或者修改 HTML 模板文件来改变页面结构。

3. 高级技巧:利用 block.json 创建自定义区块样式

虽然我们主要关注无代码主题,但了解如何利用 block.json 文件创建自定义区块样式也是非常有用的。这可以让你在不编写 CSS 代码的情况下,为区块添加特定的样式变体。

假设我们想要为“按钮”区块添加一个“primary”样式变体。

  1. 创建区块样式定义:

    theme.json 文件中,添加以下代码到 styles 部分:

    {
      "blocks": {
        "core/button": {
          "styles": [
            {
              "name": "Primary",
              "label": "Primary",
              "isDefault": false,
              "style": {
                "backgroundColor": "var(--wp--preset--color--primary)",
                "color": "#fff"
              }
            }
          ]
        }
      }
    }

    这段代码定义了一个名为 "Primary" 的按钮样式。它设置了背景颜色为主题的 "primary" 颜色,文本颜色为白色。

  2. 在编辑器中使用样式:

    现在,当你编辑一个按钮区块时,你会在区块设置中看到一个 "Styles" 面板。在这个面板中,你可以选择 "Primary" 样式。

通过这种方式,你可以为任何区块创建自定义样式变体,而无需编写任何 CSS 代码。

4. 更进一步:使用区块模板约束页面结构

WordPress允许你预定义文章和页面的内容结构,也就是区块模板。 这通过theme.json中的templatePartstemplate部分实现。 假设你想让每一篇新的文章都包含一个固定的标题和一个Call to Action按钮。

{
  "version": 2,
  "settings": {
    "appearanceTools": true
  },
  "templateParts": [
    {
      "name": "cta",
      "title": "Call to Action",
      "area": "uncategorized"
    }
  ],
  "template": [
    {
      "name": "core/heading",
      "attributes": {
        "level": 2,
        "content": "Default Heading"
      }
    },
    {
      "name": "core/paragraph",
      "content": "Default Paragraph"
    },
    {
      "name": "core/button",
      "attributes": {
        "text": "Learn More",
        "url": "#"
      }
    }
  ]
}

这段代码定义了一个简单的区块模板,包含一个H2标题,一段文字和一个按钮。每当你创建一个新的文章或页面时,这些区块会预先填充到编辑器中。

5. 使用 block.json 增强现有区块

虽然我们主要使用 theme.json 和 HTML 模板,但有时我们可能需要修改现有区块的行为。 这可以通过创建一个自定义区块变体来实现。 假设你想为 "core/image" 区块添加一个 "rounded" 变体。

  1. 创建 JavaScript 文件:

    在你的主题目录下创建一个 js 目录,并在其中创建一个 image-variations.js 文件,内容如下:

wp.blocks.registerBlockVariation(
    'core/image',
    {
        name: 'rounded',
        title: 'Rounded',
        description: 'Display image with rounded corners',
        attributes: {
            className: 'is-style-rounded',
        },
        isDefault: false,
    }
);
  1. Enqueue JavaScript 文件:

    在你的主题的 functions.php 文件(如果存在)中,添加以下代码来注册和加载 JavaScript 文件:

function my_theme_enqueue_block_editor_assets() {
    wp_enqueue_script(
        'my-theme-image-variations',
        get_template_directory_uri() . '/js/image-variations.js',
        [ 'wp-blocks', 'wp-element' ]
    );
}
add_action( 'enqueue_block_editor_assets', 'my_theme_enqueue_block_editor_assets' );
  1. 添加 CSS 样式:

    在你的 style.css 文件中,添加以下 CSS 样式:

.wp-block-image.is-style-rounded img {
    border-radius: 50%;
}

现在,当你编辑一个图片区块时,你会在区块设置中看到一个 "Styles" 面板。在这个面板中,你可以选择 "Rounded" 样式,图片将以圆形显示。

代码片段汇总

文件 内容

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注