codelight/acf-blocks

此包的最新版本(2.1.2)没有提供许可证信息。

2.1.2 2023-11-14 08:15 UTC

This package is auto-updated.

Last update: 2024-09-14 10:19:01 UTC


README

ACF Blocks 是一个轻量级库,提供干净、面向对象的 API 来创建和渲染 ACF 字段组。

您的 WordPress 代码库不必一团糟。

此库处于测试阶段。请自行承担风险。欢迎贡献。

概述

ACF Blocks 引入了 的概念,它们本质上是字段组和灵活布局的控制器(或实际上是 ViewModel)。字段使用优秀的 ACF Builder 库创建。

使用 ACF Blocks 的三个主要好处是

  • 加速简单站点的开发,
  • 提供一种超级简单但干净的架构,用于开发更复杂的站点,
  • 允许在项目之间重用块。

安装

composer require codelight/acf-blocks dev-master

如果您在 2018 年还没有使用 Composer,那么请现在开始使用,这对您将是一个巨大的帮助。[待办:文章]

示例 1:快速过程化块

让我们以创建和渲染一个简单的字段组为例。

<?php
// blocks.php

use Codelight\ACFBlocks\Blocks;
use Codelight\ACFBlocks\BlockType;

add_action('init', function() {

    // Create a new block
    $imageBlock = new BlockType('example_image');
    
    /**
     * Define ACF fields - see https://github.com/StoutLogic/acf-builder
     * Add an image field and a wysiwyg field.
     * Also add the field group to template-image.php page template
     */
    $imageBlock->getFieldsBuilder()
        ->addImage('awesome_image', ['return_format' => 'id'])
        ->addWysiwyg('boring_text')
        ->setLocation('page_template', '==', 'template-image.php');
    
    /**
     * Add a function for processing raw ACF data before it's sent to the template.
     * This allows you to do additional processing depending on the data and keep your templates clean.
     */
    $imageBlock->addCallback(function($data) {
    
        // Return the full image html with srcset attribute generated by wordpress
        $data['image'] = wp_get_attachment_image($data['awesome_image'], 'large');
        
        // Split the wysiwyg contents into an excerpt and the full text
        $data['excerpt'] = wp_trim_words($data['boring_text'], 25);
        $data['text'] = $data['boring_text'];
        
        return $data;
    });
    
    // Set the template for this block
    $imageBlock->setTemplate('templates/blocks/image.php');
    
    // Register the block with the main block manager class
    $blocks = Blocks::getInstance();
    $blocks->registerBlock($imageBlock);
}
<?php
// template-image.php
/**
 * Template name: Image
 *
 * This is the page template where we will be rendering our block.
 * Calling `blocks()->get()` inside the Loop will return all pre-rendered blocks 
 * assigned to that specific page or post.
 */
?>
<?php while (have_posts()) : the_post(); ?>
    <?php foreach (blocks()->get() as $block): ?>
        <?= $block; ?>
    <?php endforeach; ?>
<?php endwhile; ?>
<?php
// templates/blocks/image.php
/**
 * This is the template of the single block.
 * Data is injected automatically.
 */
?>
<section class="section-image">
    <?= $image; ?>
    <div class="description">
        <div class="description-excerpt">
            <?= $excerpt; ?>
        </div>
        <div class="description-full">
            <?= $text; ?>
        </div>
    </div>
</section>

示例 2:将块封装在类中

让我们以更干净的方式创建相同的块——作为一个类。这个类应该在一个名为 ImageBlock.php 的单独文件中。你可能希望将它保存在一个名为 'blocks' 的单独文件夹中。

<?php
use Codelight\ACFBlocks\BlockType;

class ImageBlock extends BlockType {

    protected $config = [
        // The machine-readable name of the block
        'name' => 'example_image';
        // The location of the template
        'template' => 'templates/blocks/image.php',
    ];

    // This function is called when the block type is initialized for the first time.
    // You'll use it mostly to register the fields
    public function init()
    {
        $this->getFieldsBuilder()
            ->addImage('awesome_image', ['return_format' => 'id'])
            ->addWysiwyg('boring_text')
            ->setLocation('page_template', '==', 'template-image.php');
    }
    
    // This function works in a similar way to addCallback() - it allows you to
    // modify the data that's passed into the template
    public function filterData($data)
    {
        // Return the full image html with srcset attribute generated by wordpress
        $data['image'] = wp_get_attachment_image($data['awesome_image'], 'large');
        
        // Split the wysiwyg contents into an excerpt and the full text
        $data['excerpt'] = wp_trim_words($data['boring_text'], 25);
        $data['text'] = $data['boring_text'];
        
        return $data;
    }
}

我们还需要注册我们刚刚创建的块。这需要添加到你的 functions.php(或等效文件)中

<?php
require_once('blocks/ImageBlock.php');

add_action('init', function() {
    $blocks = Blocks::getInstance();
    $blocks->init([
        'blocktypes' => [
            // array of block class names as strings
            'ImageBlock',
        ]
    ]);
});

这就完成了。你还需要添加如前例所示的模板。

示例 3:设置灵活布局

让我们继续上一个示例,但将 ImageBlock 注册为灵活内容布局。
首先,我们需要创建一个包含 ImageBlock 的灵活内容块。

<?php
use Codelight\ACFBlocks\FlexibleContentBlockType;

class FlexibleBlock extends FlexibleContentBlockType
{
    protected $config = [
        // The machine-readable name of the block
        'name'      => 'flexible_block',
        // The location of the template
        'template'  => 'blocks.content-builder',
    ];
    
    public function init()
    {
        $this->getFieldsBuilder()
             ->setGroupConfig('title', 'Content Blocks')
             ->setLocation('post_type', '==', 'page');
                
        // This registers our ImageBlock as a child block of this flexible content layout
        $this->registerBlockType('ImageBlock');
    }
}

这个灵活内容块与任何其他块的工作方式完全一样。要注册它,修改你之前添加到 functions.php(或等效文件)中的代码,如下所示

<?php
require_once('blocks/ImageBlock.php');
require_once('blocks/FlexibleBlock.php');

add_action('init', function() {
    $blocks = Blocks::getInstance();
    $blocks->init([
        'blocktypes' => [
            // array of block class names as strings
            'ImageBlock',
            'FlexibleBlock',
        ]
    ]);
});

现在,你将在每个页面上都有一个灵活内容区域,可以添加 ImageBlock。请注意,ImageBlock 仍然将作为常规(非灵活布局)块添加到 template-image.php 中。ImageBlock 将在这两种情况下使用相同的模板。这提供了一种在模板、灵活内容区域甚至项目之间重用块的方法。还可能在不同的情境中使用不同的模板(例如,灵活布局与常规页面上下文),同时保持块的后端代码不变。

示例 4:这有什么用呢?

一个明显的答案是,一旦你了解了基本概念,它比手动编写所有令人烦恼的模板代码快约 10 倍。然而,使用 ACF Blocks 的主要优势是它使你以特定的、干净的、灵活的和模块化的方式构建事物。现在你有了一个非常好的方法来分离你的模板和功能。你可以重用和扩展 ACF 字段组和块。你总是知道你的代码在哪里。这种方法加快了小型项目的开发速度,但在拥有大量不同字段和字段组的巨大站点上下文中表现得尤为出色。

待办:添加更多复杂示例。

常见问题解答

使用这个库会影响性能吗?
不,这只是一个非常薄的抽象层。它并不做什么,只是允许你编写更好的代码。

我正在使用soberwp/controller,这个库已经为我提供了一个控制器。为什么我要使用这个库呢?
soberwp/controller背后的概念很棒,但在灵活布局的上下文中并不实用。