d'Economía.net
WORDPRESS

Construcción de bloques ACF con block.json


ACF 6.0 incluye un importante mejora en la forma en que se construyen los bloques. Ahora admite el uso de block.json, que se alinea con el método preferido del núcleo de WordPress para el registro de bloques.

¿Porque es esto importante? A medida que WordPress ofrece nuevas funciones para bloques, puede comenzar a usarlas de inmediato. Los bloques se registran “a la manera de WordPress”, por lo que son compatibles con todas las funciones principales de WP. No tiene que esperar a que ACF agregue soporte para una nueva característica.

¿Qué significa esto para mis bloques más antiguos? Los bloques creados con acf_register_block_type() seguirán funcionando exactamente como se esperaba y no es necesario volver atrás y actualizar el código anterior. Sin embargo, recomiendo usar el nuevo método para todos los bloques futuros.

Para comenzar a usar esto hoy, deberá iniciar sesión en su cuenta de ACF y descargar la versión candidata más reciente.

Si tiene problemas con sus bloques que no aparecen, primero asegúrese de estar en ACF 6.0, luego ejecute su archivo block.json a través de un validador JSON para ver si hay algún problema. Desafortunadamente, no hay mensajes de error cuando tiene un error tipográfico en su archivo JSON.

Crear un archivo block.json

Cada bloque tendrá un archivo block.json, por lo que es mejor tener un directorio para cada bloque. Recomiendo crear un directorio /blocks/ en su tema o complemento para contenerlos.

Cree un archivo block.json en su carpeta específica de bloque. Ejemplo: /blocks/tip/block.json

{
    "name": "cwp/tip",
    "title": "Recipe Tip",
    "description": "",
    "style": "file:./style.css",
    "script": "",
    "category": "cultivatewp",
    "icon": "carrot",
    "apiVersion": 2,
    "keywords": [],
    "acf": {
        "mode": "preview",
	"renderTemplate": "render.php"
    },
    "styles": [],
    "supports": {
        "align": false,
        "anchor": false,
        "alignContent": false,
        "color": {
            "text": false,
            "background": true,
            "link": false
        },
        "alignText": false,
        "fullHeight": false
    },
    "attributes": {
    }
}

La mayor parte de esto se alineará con la configuración de acf_register_block_type(), pero hay algunas cosas importantes a tener en cuenta:

Prefijos personalizados en el nombre del bloque

Para el name ahora puede especificar su propio prefijo, en lugar de que todos los bloques tengan el prefijo automáticamente con acf. Si no agrega un prefijo, se utilizará el ACF.

Guion

Si necesita cargar un archivo JavaScript junto con su bloque, use el script parámetro para pasar el identificador del script: "script": "block-tip".

Asegúrese de registrar también ese script y especificar las dependencias.

/**
 * Register block script
 */
function cwp_register_block_script() {
wp_register_script( 'block-tip', get_template_directory_uri() . '/blocks/tip/block-tip.js', [ 'jquery', 'acf' ] );
}
add_action( 'init', 'cwp_register_block_script' );

Si está aprovechando la API JS de ACF (p. ej.:window.acf.addAction) tendrá que incluir acf como dependencia.

Si usa un espacio de nombres que no sea “acf/”, debe usar el nombre completo del bloque en la devolución de llamada, así que: render_block_preview/type=cwp/tip

Estilo

El style El parámetro le permite especificar una hoja de estilo para incluir con este bloque. Hay dos formas en que se puede usar.

"style": "file:./style.css"

Esto cargará el CSS real directamente en el encabezado del documento. Esto significa que el archivo CSS no se carga como una solicitud separada, lo que reduce el tiempo de carga de la página inicial (pro), pero también que el archivo CSS no se almacena en caché del navegador, lo que aumenta ligeramente el tiempo de carga de la página posterior (con).

Coloque su archivo style.css dentro del directorio de bloques (por ejemplo: /wp-content/themes/my-theme/blocks/tip/style.css).

"style": "block-tip"

esto se ejecutará wp_enqueue_style( 'block-tip' ) para cargar el archivo CSS normalmente, con los pros/contras opuestos enumerados anteriormente. En otra parte de tu tema/complemento deberías tener wp_register_style( 'block-tip', get_template_directory_uri() . '/blocks/tip/style.css' )

Diatriba rápida sobre estilos:

Si está utilizando un tema FSE (“tema de bloque”), la carga de estilo funcionará exactamente como espera. Los archivos CSS y los estilos en línea solo se cargarán si esa página contiene el bloque.

Si eres como yo y creas temas basados ​​en PHP “clásicos”, WordPress carga cada estilo de bloque registrado en el encabezado, independientemente de si ese bloque existe en la página. Puedes usar el should_load_separate_core_block_assets filtro para decirle a WP que solo cargue los que se requieren, pero espera hasta wp_footer para cargar el CSS, causando grandes problemas de CLS que hacen que esta función sea inútil.

El argumento central de WP (tal como lo entiendo) es que no sabemos exactamente qué bloques están en la página actualmente. Podrían estar en el contenido de la publicación, en bloques reutilizables, en áreas de widgets basadas en bloques u otras funciones basadas en bloques. Si bien todo eso es cierto, hubiera preferido cargar los archivos CSS que hacer sepa que están en el contenido de la publicación en el encabezado y cargando los que faltan en el pie de página.

Había creado mi propio cargador de CSS que averiguaba qué bloques aparecían en la página, pero ahora opto por usar WP Rocket para eliminar el CSS no utilizado de la página.

Guion

Si necesita cargar un archivo JavaScript junto con su bloque, use el script parámetro para pasar el identificador del script: "script": "block-tip".

Asegúrese de registrar también ese script y especificar las dependencias.

/**
 * Register block script
 */
function cwp_register_block_script() {
wp_register_script( 'block-tip', get_template_directory_uri() . '/blocks/tip/block-tip.js', [ 'jquery', 'acf' ] );
}
add_action( 'init', 'cwp_register_block_script' );

Si está aprovechando la API JS de ACF (p. ej.:window.acf.addAction) tendrá que incluir acf como dependencia.

Si usa un espacio de nombres que no sea “acf/”, debe usar el nombre completo del bloque en la devolución de llamada, así que: render_block_preview/type=cwp/tip

Icono

Puede especificar un ícono de Dashicons para usar o incluir un SVG real:

"icon": "<svg xmlns="http://www.w3.org/2000/svg" viewBox='0 0 22.5 22.5'><defs><style>.a{fill:#222;}.b{fill:#1fa8af;}</style></defs><path class="a" d='M20.17,4a10.17,10.17,0,0,0-7-3.5L11.91.38h-.18a.64.64,0,0,0-.47.13A.68.68,0,0,0,11,.93L10.6,3.79a.48.48,0,0,0,.12.43.54.54,0,0,0,.44.18h.11l1.44.17c3.94.45,6.12,2.69,5.84,6a8.37,8.37,0,0,1-2.49,5.12A8.14,8.14,0,0,1,10,18.06l-.65,0H9.15a.8.8,0,0,0-.5.17.68.68,0,0,0-.25.44L8,21.5a.49.49,0,0,0,.12.42.57.57,0,0,0,.45.18h.17l1,0h.34a11.61,11.61,0,0,0,8.21-3.39,12.76,12.76,0,0,0,3.77-7.92A9.49,9.49,0,0,0,20.17,4Z'/><path class="b" d='M9.2,17h.15L10,17a7.61,7.61,0,0,0,3.64-.77L15,6.15a8.65,8.65,0,0,0-2.33-.57l-1-.12-1,7.35L9.23,7c-.11-.45-.33-.67-.65-.67H7.16c-.29,0-.5.22-.65.67L5.1,12.81,3.82,3a.55.55,0,0,0-.61-.55H.78a.36.36,0,0,0-.29.16A.6.6,0,0,0,.37,3a.5.5,0,0,0,0,.18L2.53,19.22a1.07,1.07,0,0,0,.23.6.64.64,0,0,0,.53.23H5.16c.37,0,.61-.21.73-.65l2-7.19Z'/></svg>",

FCA

Los ajustes específicos de ACF irán en esta matriz.

Usar mode para especificar cómo se representa el bloque en el editor de bloques. El valor predeterminado es “automático”, que representa el bloque para que coincida con la interfaz hasta que lo seleccione, luego se convierte en un editor de grupo de campos ACF. Si se establece en “vista previa”, siempre se verá como la interfaz y puede editar el grupo de campos ACF en la barra lateral.

Usar renderTemplate para especificar qué archivo PHP representará este bloque. Por lo general, tengo un archivo render.php en cada directorio de bloques para mantener la coherencia.

Como alternativa, puede utilizar renderCallback para especificar una función de PHP que generará el contenido del bloque.

Estilos

Usar styles para especificar una matriz de estilos de tipo de bloque.

"styles": [
        { "name": "default", "label": "Default", "isDefault": true },
        { "name": "red", "label": "Red" },
        { "name": "green", "label": "Green" },
        { "name": "blue", "label": "Blue" }
    ],

Soporta

Usar supports para especificar qué características de Gutenberg admite este bloque. El valor predeterminado es false para todos los elementos, por lo que no necesita especificar todos los elementos que no admite, pero normalmente los dejo todos marcados false para que pueda alternar fácilmente los que quiero true.

En este ejemplo, la única característica que admite este bloque es un color de fondo:

"supports": {
        "align": false,
        "anchor": false,
        "alignContent": false,
        "color": {
            "text": false,
            "background": true,
            "link": false
        },
        "alignText": false,
        "fullHeight": false
    },

Atributos

Puede establecer los atributos predeterminados para las características del bloque. Por ejemplo, si el bloque admite un color de fondo, puede hacer que ese bloque use el tertiary color por defecto:

"attributes": {
	"backgroundColor": {
		"type": "string",
		"default": "tertiary"
	}
}

Para obtener más información, consulte el artículo del manual del editor de bloques sobre metadatos en block.json.


Registra tu bloque

Ahora debería tener una carpeta en su tema/complemento con block.json, style.css y render.php. El siguiente paso es decirle a WordPress sobre su bloque usando register_block_type().

En el archivo functions.php de su complemento o tema, agregue:

/**
 * Load Blocks
 */
function cwp_load_blocks() {
	register_block_type( get_template_directory() . '/blocks/tip/block.json' );

	// Optional - register stylesheet if using Style Method 2 from above
	wp_register_style( 'block-tip', get_template_directory_uri() . '/blocks/tip/style.css' );
}
add_action( 'init', 'cwp_load_blocks' );

¡Eso es todo! Ahora debería poder acceder a su bloque personalizado en el editor de bloques.

Uso avanzado

Si bien lo anterior funciona como un ejemplo básico, hay algunas formas en que podemos mejorar esto:

  1. Registra cada bloque que existe en el directorio /blocks
  2. Guarde en caché la lista de bloques para que no estemos atravesando el sistema de archivos en cada carga de página
  3. Registre una hoja de estilo para cada bloque
  4. Incluya cualquier grupo de campos ACF asociado con ese bloque
  5. Incluya cualquier archivo PHP adicional requerido por el bloque

Aquí está el código que uso en mis temas, seguido de una descripción de lo que está haciendo.

<?php
/**
 * Blocks
 *
 * @package      CultivateClient
 * @author       CultivateWP
 * @since        1.0.0
 * @license      GPL-2.0+
 **/

namespace Cultivate\Blocks;

/**
 * Load Blocks
 */
function load_blocks() {
	$theme  = wp_get_theme();
	$blocks = get_blocks();
	foreach( $blocks as $block ) {
		if ( file_exists( get_template_directory() . '/blocks/' . $block . '/block.json' ) ) {
			register_block_type( get_template_directory() . '/blocks/' . $block . '/block.json' );
			wp_register_style( 'block-' . $block, get_template_directory_uri() . '/blocks/' . $block . '/style.css', null, $theme->get( 'Version' ) );

			if ( file_exists( get_template_directory() . '/blocks/' . $block . '/init.php' ) ) {
				include_once get_template_directory() . '/blocks/' . $block . '/init.php';
			}
		}
	}
}
add_action( 'init', __NAMESPACE__ . '\load_blocks', 5 );

/**
 * Load ACF field groups for blocks
 */
function load_acf_field_group( $paths ) {
	$blocks = get_blocks();
	foreach( $blocks as $block ) {
		$paths[] = get_template_directory() . '/blocks/' . $block;
	}
	return $paths;
}
add_filter( 'acf/settings/load_json', __NAMESPACE__ . '\load_acf_field_group' );

/**
 * Get Blocks
 */
function get_blocks() {
	$theme   = wp_get_theme();
	$blocks  = get_option( 'cwp_blocks' );
	$version = get_option( 'cwp_blocks_version' );
	if ( empty( $blocks ) || version_compare( $theme->get( 'Version' ), $version ) || ( function_exists( 'wp_get_environment_type' ) && 'production' !== wp_get_environment_type() ) ) {
		$blocks = scandir( get_template_directory() . '/blocks/' );
		$blocks = array_values( array_diff( $blocks, array( '..', '.', '.DS_Store', '_base-block' ) ) );

		update_option( 'cwp_blocks', $blocks );
		update_option( 'cwp_blocks_version', $theme->get( 'Version' ) );
	}
	return $blocks;
}

/**
 * Block categories
 *
 * @since 1.0.0
 */
function block_categories( $categories ) {

	// Check to see if we already have a CultivateWP category
	$include = true;
	foreach( $categories as $category ) {
		if( 'cultivatewp' === $category['slug'] ) {
			$include = false;
		}
	}

	if( $include ) {
		$categories = array_merge(
			$categories,
			[
				[
					'slug'  => 'cultivatewp',
					'title' => __( 'CultivateWP', 'cultivate_textdomain' ),
					'icon'  => \cwp_icon( [ 'icon' => 'cultivatewp', 'group' => 'color', 'force' => true ] )
				]
			]
		);
	}

	return $categories;
}
add_filter( 'block_categories_all', __NAMESPACE__ . '\block_categories' );

Mi get_blocks() La función escanea el directorio /block y crea una matriz de todos mis bloques. Guardo esto como una opción para que solo tengamos que hacer esto una vez y usar la versión del tema actual para reventar el caché. Entonces, cuando agrego un nuevo bloque, también subo el número de versión en style.css

El código hace lo siguiente para cada bloque:

  • Llamar register_block_type() usando el archivo block.json
  • Llamar wp_register_style() para registrar la hoja de estilo del bloque. Esto solo se cargará si el archivo block.json especifica un style.
  • si hay un init.php archivo en el directorio de bloques, cárguelo también. Esto es lo que uso para cualquier código PHP adicional que quiera ejecutar independientemente de la representación del bloque.
  • Estoy haciendo todo esto en el init gancho con una prioridad de 5 para que pueda usar el normal init (prioridad 10) dentro de mi archivo init.php.
  • El acf/settings/load_json El filtro le dice a ACF que busque en mis directorios de bloques los archivos de grupo de campos JSON de ACF.

¿Necesitas ayuda?

Pregunta al soporte de ACF 🙂. Estoy cerrando los comentarios en esta publicación porque probablemente no tendré tiempo para responder preguntas y solucionar problemas, pero el equipo de soporte de ACF es excelente y muy receptivo.

También actualizaré esta publicación con más información y recursos a medida que los encuentre.

Información adicional



Bill Erickson

Comments

comments

RELACIONADOS