WordPress源码深度解析之:古腾堡的`Block Template`:如何使用`theme.json`定义块布局。

诸位代码界的探险家们,晚上好!

欢迎来到“WordPress源码深度解析”系列讲座,今晚咱们要聊聊古腾堡(Gutenberg)里的“Block Template”和它背后的“theme.json”配置文件。 这俩家伙组合起来,简直就是定义WordPress块布局的超级搭档。 别怕名字听着唬人,其实原理简单得很,只要掌握了窍门,你也能轻松玩转WordPress主题的块布局。

第一幕:Block Template,布局的蓝图

什么是Block Template? 简单来说,它就是你网站页面布局的蓝图。 想象一下,你盖房子之前总得有个设计图吧? Block Template就是这个设计图,它定义了哪些块(Blocks)应该出现在你的页面上,以及它们应该如何排列。

以前,我们定义页面布局可能得写一堆PHP代码,搞得代码又臭又长。 现在有了Block Template,只需要用JSON格式的文件描述布局,WordPress就能自动帮你生成页面。 方便不?

Block Template通常是放在主题目录下的templates文件夹里,文件名以.html结尾。 比如,一个简单的首页Block Template可能长这样:

<!-- wp:group {"tagName":"main","layout":{"inherit":true}} -->
<main class="wp-block-group">
  <!-- wp:cover {"url":"your-image.jpg","dimRatio":50,"isDark":false,"tagName":"section","style":{"spacing":{"padding":{"top":"100px","bottom":"100px"}}}} -->
  <section class="wp-block-cover is-light" style="padding-top:100px;padding-bottom:100px"><span aria-hidden="true" class="wp-block-cover__background has-background-dim"></span><img class="wp-block-cover__image wp-image-123" alt="" src="your-image.jpg" data-object-fit="cover"/><div class="wp-block-cover__inner-container">
    <!-- wp:heading {"level":1,"textAlign":"center"} -->
    <h1 class="has-text-align-center">欢迎来到我的网站</h1>
    <!-- /wp:heading -->

    <!-- wp:paragraph {"align":"center"} -->
    <p class="has-text-align-center">这里是关于我的博客,分享技术和生活。</p>
    <!-- /wp:paragraph -->
  </div></section>
  <!-- /wp:cover -->

  <!-- wp:group {"layout":{"type":"constrained"}} -->
  <div class="wp-block-group">
    <!-- wp:columns -->
    <div class="wp-block-columns">
      <!-- wp:column -->
      <div class="wp-block-column">
        <!-- wp:heading {"level":2"} -->
        <h2>最新文章</h2>
        <!-- /wp:heading -->

        <!-- wp:latest-posts /-->
      </div>
      <!-- /wp:column -->

      <!-- wp:column -->
      <div class="wp-block-column">
        <!-- wp:heading {"level":2"} -->
        <h2>关于我</h2>
        <!-- /wp:heading -->

        <!-- wp:paragraph -->
        <p>我是个程序员,热爱技术,喜欢分享。</p>
        <!-- /wp:paragraph -->
      </div>
      <!-- /wp:column -->
    </div>
    <!-- /wp:columns -->
  </div>
  <!-- /wp:group -->
</main>
<!-- /wp:group -->

别被这一堆HTML注释吓到,它们其实就是古腾堡块的标记。 每一个<!-- wp:xxx -->就是一个块,比如<!-- wp:heading -->就是一个标题块。

这个例子里,我们定义了一个包含封面(Cover)、标题(Heading)、段落(Paragraph)、最新文章(Latest Posts)和列(Columns)的页面布局。

第二幕:theme.json,布局的调色盘

光有蓝图还不够,我们还需要调色盘来给房子上色。 theme.json就是这个调色盘,它定义了主题的全局样式和设置。 比如,你可以用theme.json来设置网站的字体、颜色、间距等等。

theme.json文件放在主题的根目录下。 一个简单的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"
        }
      ]
    },
    "typography": {
      "fontFamilies": [
        {
          "fontFamily": "-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif",
          "name": "System Font",
          "slug": "system-font"
        }
      ]
    },
    "layout": {
      "contentSize": "800px",
      "wideSize": "1200px"
    }
  },
  "styles": {
    "elements": {
      "link": {
        "color": {
          "text": "var(--wp--preset--color--primary)"
        }
      }
    }
  }
}

这个theme.json定义了:

  • version: theme.json的版本号,目前推荐使用2
  • settings: 全局设置,包括颜色、字体、布局等。
    • appearanceTools: 是否启用外观工具,启用后可以在编辑器中调整块的样式。
    • color: 颜色设置,包括颜色调色板和渐变色。
      • palette: 颜色调色板,定义了一组常用的颜色。
      • gradients: 渐变色,定义了一组渐变色。
    • typography: 字体设置,包括字体家族。
      • fontFamilies: 字体家族,定义了一组可用的字体。
    • layout: 布局设置,包括内容区域和宽内容区域的宽度。
      • contentSize: 内容区域的宽度。
      • wideSize: 宽内容区域的宽度。
  • styles: 全局样式,用于设置元素的默认样式。
    • elements: 元素样式,可以设置链接、按钮等元素的样式。
      • link: 链接样式,设置链接的颜色。

第三幕:Block Template + theme.json,完美搭档

现在,我们有了蓝图(Block Template)和调色盘(theme.json),就可以开始搭建我们的网站了。

Block Template定义了页面的结构,theme.json定义了页面的样式。 它们是如何协同工作的呢?

  • Block Template使用<!-- wp:xxx -->标记来定义块。 这些标记告诉WordPress应该插入哪些块。
  • theme.json定义了全局样式和设置。 当WordPress渲染页面时,它会读取theme.json,并将其中定义的样式应用到相应的块上。

举个例子,假设你在theme.json里定义了一个名为primary的颜色:

{
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "slug": "primary",
          "color": "#007bff",
          "name": "Primary"
        }
      ]
    }
  }
}

然后在你的Block Template里,你可以使用这个颜色来设置某个块的颜色:

<!-- wp:heading {"level":1,"style":{"color":{"text":"var(--wp--preset--color--primary)"}}} -->
<h1 style="color:var(--wp--preset--color--primary)">我的标题</h1>
<!-- /wp:heading -->

注意style":{"color":{"text":"var(--wp--preset--color--primary)"}}} 这段代码。 它告诉WordPress,这个标题的文本颜色应该使用theme.json里定义的primary颜色。 var(--wp--preset--color--primary)就是一个CSS变量,它引用了theme.json里定义的颜色。

第四幕:实战演练,打造一个简单的首页

为了让大家更好地理解Block Template和theme.json的用法,我们来做一个简单的首页。

1. 创建一个templates/index.html文件:

<!-- wp:group {"tagName":"main","layout":{"inherit":true}} -->
<main class="wp-block-group">
  <!-- wp:cover {"url":"your-image.jpg","dimRatio":50,"isDark":false,"tagName":"section","style":{"spacing":{"padding":{"top":"100px","bottom":"100px"}}}} -->
  <section class="wp-block-cover is-light" style="padding-top:100px;padding-bottom:100px"><span aria-hidden="true" class="wp-block-cover__background has-background-dim"></span><img class="wp-block-cover__image wp-image-123" alt="" src="your-image.jpg" data-object-fit="cover"/><div class="wp-block-cover__inner-container">
    <!-- wp:heading {"level":1,"textAlign":"center"} -->
    <h1 class="has-text-align-center">欢迎来到我的网站</h1>
    <!-- /wp:heading -->

    <!-- wp:paragraph {"align":"center"} -->
    <p class="has-text-align-center">这里是关于我的博客,分享技术和生活。</p>
    <!-- /wp:paragraph -->
  </div></section>
  <!-- /wp:cover -->

  <!-- wp:group {"layout":{"type":"constrained"}} -->
  <div class="wp-block-group">
    <!-- wp:columns -->
    <div class="wp-block-columns">
      <!-- wp:column -->
      <div class="wp-block-column">
        <!-- wp:heading {"level":2"} -->
        <h2>最新文章</h2>
        <!-- /wp:heading -->

        <!-- wp:latest-posts /-->
      </div>
      <!-- /wp:column -->

      <!-- wp:column -->
      <div class="wp-block-column">
        <!-- wp:heading {"level":2"} -->
        <h2>关于我</h2>
        <!-- /wp:heading -->

        <!-- wp:paragraph -->
        <p>我是个程序员,热爱技术,喜欢分享。</p>
        <!-- /wp:paragraph -->
      </div>
      <!-- /wp:column -->
    </div>
    <!-- /wp:columns -->
  </div>
  <!-- /wp:group -->
</main>
<!-- /wp:group -->

2. 创建一个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"
        }
      ]
    },
    "typography": {
      "fontFamilies": [
        {
          "fontFamily": "-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif",
          "name": "System Font",
          "slug": "system-font"
        }
      ]
    },
    "layout": {
      "contentSize": "800px",
      "wideSize": "1200px"
    }
  },
  "styles": {
    "elements": {
      "link": {
        "color": {
          "text": "var(--wp--preset--color--primary)"
        }
      }
    }
  }
}

3. 在你的WordPress主题的functions.php文件中,添加以下代码来注册Block Template:

<?php
function my_theme_register_block_template() {
  $post_type_object = get_post_type_object( 'page' );
  $post_type_object->template = array(
    array( 'core/group', array(
      'tagName' => 'main',
      'layout' => array( 'inherit' => true )
    ), array(
      array( 'core/cover', array(
        'url' => 'your-image.jpg',
        'dimRatio' => 50,
        'isDark' => false,
        'tagName' => 'section',
        'style' => array( 'spacing' => array( 'padding' => array( 'top' => '100px', 'bottom' => '100px' ) ) )
      ), array(
        array( 'core/heading', array( 'level' => 1, 'textAlign' => 'center' ) ),
        array( 'core/paragraph', array( 'align' => 'center' ) )
      ) ),
      array( 'core/group', array( 'layout' => array( 'type' => 'constrained' ) ), array(
        array( 'core/columns', array(), array(
          array( 'core/column', array(), array(
            array( 'core/heading', array( 'level' => 2 ) ),
            array( 'core/latest-posts' )
          ) ),
          array( 'core/column', array(), array(
            array( 'core/heading', array( 'level' => 2 ) ),
            array( 'core/paragraph' )
          ) )
        ) )
      ) )
    ) )
  );
}
add_action( 'init', 'my_theme_register_block_template' );

这段代码会告诉WordPress,当你创建一个新的页面时,应该使用我们定义的Block Template。

4. 创建一个新的页面。

你会发现,新创建的页面已经包含了我们在Block Template中定义的布局。 你可以根据需要在编辑器中修改和调整这些块。

第五幕:高级技巧,玩转theme.json

theme.json的功能远不止于此。 它可以让你控制主题的方方面面。

  • 块级别样式: 你可以为特定的块定义样式。 比如,你可以为core/button块定义默认的背景颜色和字体颜色。
  • CSS变量: 你可以使用CSS变量来定义全局样式。 这样,当你修改CSS变量的值时,所有使用该变量的块都会自动更新。
  • 自定义样式: 你可以添加自定义CSS类,并在theme.json中定义这些类的样式。
  • 模板部件: 你可以创建可重用的模板部件,并在多个Block Template中使用它们。

第六幕:常见问题解答

  • 问:我修改了theme.json,但是页面没有更新怎么办?
    • 答:尝试清除WordPress的缓存。 很多缓存插件会缓存theme.json的内容,导致修改后页面没有立即更新。
  • 问:我不知道某个块的属性有哪些,该怎么办?
    • 答:可以在古腾堡编辑器中查看块的属性。 或者查阅WordPress官方文档。
  • 问:我可以使用PHP代码来修改Block Template吗?
    • 答:可以。 你可以使用render_block过滤器来修改块的输出。

第七幕:总结

Block Template和theme.json是古腾堡主题开发的利器。 它们让我们可以用更简单、更灵活的方式来定义网站的布局和样式。 掌握了这两个工具,你就能轻松打造出个性化的WordPress主题。

特性 Block Template theme.json
功能 定义页面结构和块的排列 定义全局样式和设置,控制主题的外观
格式 HTML注释 JSON
位置 主题目录下的templates文件夹 主题根目录
作用对象 页面内容 全局样式、块级别样式
核心概念 块(Blocks)、布局(Layout) 颜色调色板(Palette)、字体家族(Font Families)、CSS变量(CSS Variables)
适用场景 定义页面布局、创建自定义页面模板 设置主题的全局样式、控制块的默认样式、创建可重用的样式组件

希望今天的讲座对大家有所帮助。 祝大家编码愉快! 我们下期再见!

发表回复

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