Ich muss greifen the_content()
über eine AJAX-Anfrage und rendern alle Gutenberg-Blöcke mit ihrem Inline-Styling auf der Seite.
Das Problem ist, dass der Fußzeile in Designvorlagen eindeutige Blockklassen hinzugefügt werden.
.wp-container-5 {
display: flex;
gap: 2em;
flex-wrap: nowrap;
align-items: center;
}
Wann get_the_content()
über eine AJAX-Anforderung verwendet wird, wird das eindeutige Block-Styling nicht gerendert. Ich würde vermuten, dass dies daran liegt, dass das Inline-Block-Styling auf einer Art Haken beruht, der nicht mit einer AJAX-Anfrage ausgelöst wird. do_blocks()
rendert das Inline-Styling nicht.
Ich habe die Datenbank durchsucht und die WordPress-Quelldateien durchforstet und kann nicht finden, wo Klassen mögen .wp-container-5
kommen aus. Ich dachte, wenn ich die Position des Inline-Stylings finden könnte, könnte ich es einfach abfragen und auf der Seite rendern.
Weiß jemand, wo die eindeutigen Blockstile gespeichert sind und/oder wie man sie abfragt und über eine AJAX-Anfrage einschließt?
Ich habe es geschafft, dies nach vielen Stunden der Frustration zu lösen.
Im wp-includes/block-supports/layout.php
da ist eine funktion die aufgerufen wird wp_render_layout_support_flag()
. Diese Funktion nimmt den Inhalt eines Blocks und ein Blockobjekt und weist die eindeutige Klasse zu wp-container-
mit einer eindeutigen ID am Ende. Anschließend wird das Inline-Styling mit der Funktion gerendert wp_get_layout_style()
und reiht dieses Styling ein wp_enqueue_block_support_styles()
.
Das Problem ist, wp_render_layout_support_flag()
gibt das Styling nicht zurück. Es gibt den Blockinhalt mit CSS-Klassen zurück und fügt das Styling mit passenden CSS-Klassen in die Fußzeile ein. Es ist also nicht so einfach, nur anzurufen wp_get_layout_style()
da eine eindeutige ID vergeben wird wp_render_layout_support_flag()
das wird nur dann abgeglichen wp_get_layout_style()
heißt innerhalb der wp_render_layout_support_flag()
Funktion.
Die Lösung war das Kopieren und Einfügen (nicht ideal, aber es funktioniert). wp_render_layout_support_flag()
funktionieren und leicht verändern.
function my_render_layout_support_flag( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$support_layout = block_has_support( $block_type, array( '__experimentalLayout' ), false );
if ( ! $support_layout ) {
return $block_content;
}
$block_gap = wp_get_global_settings( array( 'spacing', 'blockGap' ) );
$default_layout = wp_get_global_settings( array( 'layout' ) );
$has_block_gap_support = isset( $block_gap ) ? null !== $block_gap : false;
$default_block_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $default_block_layout;
if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) {
if ( ! $default_layout ) {
return $block_content;
}
$used_layout = $default_layout;
}
$class_name = wp_unique_id( 'wp-container-' );
$gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) );
// Skip if gap value contains unsupported characters.
// Regex for CSS value borrowed from `safecss_filter_attr`, and used here
// because we only want to match against the value, not the CSS attribute.
if ( is_array( $gap_value ) ) {
foreach ( $gap_value as $key => $value ) {
$gap_value[ $key ] = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value;
}
} else {
$gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value;
}
$fallback_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), '0.5em' );
// If a block's block.json skips serialization for spacing or spacing.blockGap,
// don't apply the user-defined value to the styles.
$should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' );
$style = wp_get_layout_style( ".$class_name", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value );
// This assumes the hook only applies to blocks with a single wrapper.
// I think this is a reasonable limitation for that particular hook.
$content = preg_replace(
"https://stackoverflow.com/" . preg_quote( 'class="', "https://stackoverflow.com/" ) . "https://stackoverflow.com/",
'class="' . esc_attr( $class_name ) . ' ',
$block_content,
1
);
// This is where the changes happen
return '<style>' . $style . '</style>' . $content;
}
Die einzige Änderung ist nahe dem Ende wo wp_enqueue_block_support_styles()
wurde entfernt und jetzt werden Styling und Inhalt zurückgegeben.
Jetzt können Gutenberg-Blöcke gerendert werden und haben das richtige Styling, wenn Sie einen AJAX-Aufruf verwenden!
$content = get_the_content(null, true, $post_id);
$blocks = parse_blocks( $content );
foreach ($blocks as $block) {
echo my_render_layout_support_flag( render_block($block), $block );
}
Diese Lösung fühlt sich irgendwie lächerlich an, aber sie funktioniert … WordPress sollte wirklich das asynchrone Rendern von Blöcken unterstützen.
Ich habe dies nicht in der Antwort einer AJAX-Anfrage mit dem alten getestet admin-ajax.php
Methode, aber ich hatte versucht, dasselbe in einer Antwort von der REST-API zu erreichen.
Nachdem ich diesen Thread gefunden und die von Myles bereitgestellte Lösung gelesen habe – danke für Ihre Details, übrigens – und in die wp_render_layout_support_flag
etwas mehr funktionieren, habe ich mir eine mögliche Alternative ausgedacht.
Im Allgemeinen könnten Sie mit der REST-API so etwas hinzufügen:
register_rest_field('post', 'styles', [
'get_callback' => function ($post) {
ob_start();
do_action('wp_footer');
$content = ob_get_clean();
// perform any needed manipulation
return $content;
},
'schema' => [
'description' => __('Styles'),
'type' => 'string',
],
]);
Sie möchten wahrscheinlich Inhalte ohne Stil im Ergebnis entfernen, falls Sie andere Funktionen haben, die Inhalte verschieben, die darin erscheinen würden wp_footer
.
Vielleicht bringt dir so etwas das, was du suchst:
ob_start();
the_content();
do_action('wp_footer');
$content = ob_get_clean();
Dies ist ein neues Verhalten in wp (ich denke seit v6). Ich bin mir nicht sicher, wie ich das einfach lösen kann, da ich jetzt mit der restlichen API die gleichen Probleme habe. Woher bekomme ich das Styling, wenn nicht von der API selbst?
– hupe31
6. Juli um 15:34 Uhr