erik kubica
Estoy tratando de hacer un bloque de columnas personalizado ya que el valor predeterminado de wordpress utilizado por gutenberg no es lo que necesito.
Así que busqué cómo funciona, utiliza el bloque InnerBlocks con una definición de diseño, pero no hay forma de especificar la etiqueta html y la clase para las columnas, por lo que es inútil para mí.
Luego, decidí recorrer las columnas usando el mapa, que funciona bien, luego agregué dentro de cada columna el componente InnerBlocks para permitir insertar otros bloques en la columna, pero el problema es que en cada columna se comparte el contenido de InnerBlocks, así que he intentado establecer la propiedad clave para que cada InnerBlock y columna sean únicos y su contenido aún se comparte (no, no estoy usando un bloque compartido).
Parece que gutenberg está usando la misma instancia de InnerBlocks en cada columna.
Estoy tratando de construir un tipo de bloque donde pueda agregar dinámicamente columnas y en cada columna agregar “tarjetas” con alguna información.
Para dar una idea de lo que estoy haciendo, aquí está el retorno de la función de edición:
<section className="infonav">
<div className="infonav__container">
<div>
<button onClick={onAddBox}>{__('Add column', 'zmg-blocks')}</button>
</div>
<div className="infonav__row">
{[...new Array(columns).keys()].map((item, index) => {
return (
<div className="infonav__row__col" key={"info_cols"+index}>
<div>
<button onClick={onRemoveBox.bind(index)}>
{__('Remove', 'zmg-blocks')}
</button>
</div>
<InnerBlocks key={"info_boxes"+index}/>
</div>
);
})}
</div>
</div>
</section>
Gracias
Swopnil dangol
Parece que Gutenberg Innerblocks solo se puede usar una vez en un bloque
Nota: Un bloque puede representar como máximo un solo elemento InnerBlocks e InnerBlocks.Content en editar y guardar respectivamente. Para crear arreglos distintos de bloques anidados, cree un tipo de bloque separado que represente sus propios InnerBlocks y asígnelos como el único tipo de bloques permitidos.
Fuente: https://github.com/WordPress/gutenberg/tree/master/packages/block-editor/src/components/inner-blocks
Necesita crear otro bloque personalizado (solo para la columna) junto con este bloque que también usa Innerblock dentro de él para que otros bloques puedan anidarse dentro. Puede hacer uso de allowBlocks para permitir solo su columna personalizada en este bloque
-
InnerBlocks
ahora es parte delblock-editor
paquete, no eleditor
paquete. Por lo tanto, la URL correcta es github.com/WordPress/gutenberg/tree/master/packages/…. Aunque en realidad no se recomienda vincular amaster
URL ya que pueden cambiar.– Swissspidy
12 de marzo de 2019 a las 9:08
-
¿Cómo incluirías ese bloque personalizado dentro de tu bloque principal? Si pudiera ilustrar su explicación, sería muy, muy útil 🙂
– Rodrigo D’Agostino
18 de junio de 2019 a las 19:34
snnsnn
Si tenía la intención de agregar múltiples bloques de gutenberg a través de InnerBlock
desde ‘block-editor’ como se muestra a continuación, todavía no hay forma de agregar múltiples bloques:
const BLOCK_TEMPLATE = [
['image-slider', { width: 800, height: 400 }],
['menu'],
];
registerBlockType('peregrine/inner-block-demo', {
title: 'Inner Block Demo',
edit({ className }) {
return (
<div className={className}>
<InnerBlocks
template={BLOCK_TEMPLATE}
templateLock="all"
/>
</div>
);
},
save() {
return (
<div>
<InnerBlocks.Content />
</div>
);
},
});
Múltiples bloques internos tienen complejidades que no parecen valer la pena y, en general, sugieren un bloque que debe dividirse en múltiples bloques más simples o con atributos de bloque (no hijos). Háganos saber cómo funciona la sugerencia anterior para usted y podríamos revisarla.
Puedes seguir la discusión aquí: https://github.com/WordPress/gutenberg/issues/6808
Pero, su código se parece más a agregar elementos internos y eso es posible.
Entonces, para aclarar más, lo que proporciona a la función registerBlockType no es un bloque. Un gutenberg bloquea un código abreviado elegante, algo como esto:
<!-- wp:image -->
<figure class="wp-block-image"><img src="https://stackoverflow.com/questions/51072386/source.jpg" alt="" /></figure>
<!-- /wp:image -->
O esto:
<!-- wp:latest-posts {"postsToShow":4,"displayPostDate":true} /-->
El primero se llama bloque estático porque tiene su contenido en él. El segundo se llama bloque dinámico porque es un bloque de cierre automático y no tiene contenido. El contenido se recuperará de la devolución de llamada de php que proporcionó cuando registró su bloque.
Gutenberg usa React para imprimir una representación visual del bloque en la pantalla del editor. El método de edición en el objeto de configuración debe devolver un elemento de reacción, este elemento se utilizará para producir una representación visual del bloque en el editor. El método de guardado también debería devolver el elemento de reacción, pero este elemento se representará en html estático y se guardará en la base de datos: <figure class="wp-block-image"><img src="https://stackoverflow.com/questions/51072386/source.jpg" alt="" /></figure>
. Ahora, los bloques dinámicos no tienen elemento de retorno ya que devuelven un valor nulo, por lo que no tienen contenido, por eso se cierran automáticamente.
Cuando el servidor responde a una solicitud, obtendrá el contenido almacenado en la base de datos y lo ejecutará a través del analizador para ver si es un bloque estático o dinámico. Si el bloque es estático, tiene su contenido en sí mismo, por lo que se devolverá el contenido. Si es dinámico, se invocará la función de devolución de llamada registrada y se devolverá su valor de retorno.
Ahora, para responder a su pregunta, las funciones de guardar y editar deberían devolver el elemento de reacción. Un elemento de reacción debe tener un único elemento raíz, pero los elementos internos pueden tener cualquier html regular como este:
<div>
<h1>Hello world</h1>
<p>This is a sentence</p>
</div>
Esto es por razones de rendimiento. Las operaciones DOM son costosas, por eso tiene un único punto de entrada al DOM. Por eso es muy rápido. Tiene su propio DOM en adelante, un árbol completo reside en la memoria. React recorrerá su árbol DOM cuando se produzca un cambio y renderizará solo la rama modificada, no pintará el árbol completo con cada pequeño cambio.
Un detalle importante aquí es que el código anterior parece html pero no lo es, es jsx. React no puede procesar html directamente. Jsx será transpilado en el elemento de reacción por un transpilador como babel.
También hay un método createElement en React que se puede usar para crear un elemento de reacción. wp vuelve a exportar este método.
Puede convertir un elemento de reacción en otro. Sin aprender a reaccionar, nunca podrá comprender completamente el poder o el potencial de los bloques. La biblioteca React no es tan grande. Una vez que capte la idea detrás de esto, puede aprender lo suficiente para ser productivo en una semana o dos.
-
Gracias, muy bien explicado, estoy familiarizado con la reacción que desarrollo en ella, pero en reacción pura, este código funcionaría sin ningún problema (ya que hice muchas formas de repetición/recopilación), pero ahora entendí que en caso de que Guttenberg use reaccionar Necesito crear un componente separado para infonav__row__col
– Erik Kubica
30 de enero de 2019 a las 9:24
Tuve el mismo problema y, según la respuesta de Swopnil Dangol, he creado algo como lo siguiente:
Bloque principal:
registerBlockType("my-plugin/parent-block", {
title: "Parent block",
// Amount of columns
attributes: {
columns: { type: "number", default: 3 },
}
edit(props) {
const { attributes: { columns } } = props;
const onChangeColumns = (newColumns) => {
setAttributes({ columns: newColumns });
};
// Either go for the template route
// (create an inner block template based on amount of columns)
const template = Array.from(Array(columns).keys()).map((i) => [
"my-plugin/custom-inner-block",
]);
// Or go for the allowed blocks route
const allowedBlocks = ["my-plugin/custom-inner-block"];
return (
<div {...useBlockProps()}>
{/* Use RangeControl in the InspectorControls to
control the number of columns. */}
<InspectorControls key="setting">
<div class="block-editor-block-card">
<fieldset>
<legend className="blocks-base-control__label">
{__("Amount of columns", "gutenpride")}
</legend>
<RangeControl
label="Columns"
value={columns}
onChange={(value) => onChangeColumns(value)}
min={1}
max={3}
/>
</fieldset>
</div>
</InspectorControls>
<InnerBlocks
template={activeTemplate}
templateLock="all"
allowedBlocks={allowedBlocks}
/>
</div>
)
},
save() {
return (
<div {...useBlockProps.save()}>
<InnerBlocks.Content />
</div>
);
},
// ...
}
Bloque interior personalizado:
registerBlockType("my-plugin/custom-inner-block", {
title: "Custom Inner Block",
edit(props) {
const { attributes } = props;
const { title } = attributes;
return (
<div {...useBlockProps()}>
<InnerBlocks/>
</div>
);
},
save() {
return (
<div {...useBlockProps.save()}>
<InnerBlocks.Content />
</div>
);
},
// ...
});