Gutenberg-lohkon tekeminen Advanced Custom Fieldsillä

WordPressin uusi Gutenberg-editori on oiva työkalu, joka vähentää tarvetta page buildereille ja mahdollistaa erilaisten sisältölajien ja perusasettelujen rakentelun suoraan editorista. Kaikkea Gutenberg ei valmiiksi kuitenkaan osaa. On olemassa lisäosia, jotka tuovat Gutenbergiin uusia lohkoja, mutta entä jos tarvittaisiin kustomoitu, omiin tarpeisiin istuva lohko?

Lohkojen luominen onnistuu kyllä, mutta ei se ihan yksinkertaista ole. Asiaa on kuitenkin mahdollista tehdä helpommaksi käyttämällä Advanced Custom Fields -lisäosaa. Tämä WordPress-kehittäjien perustyökalupakkiin kuuluva lisäosa sisältää helpot työkalut omien lohkojen kehittämiseen. ACF:n ohjeilla homma käy jopa aika helposti.

Blokkien luominen on ACF:ssä Pro-ominaisuus, mutta ACF Pro on kyllä hintansa arvoinen työkalu.

Case Lautapeliopas

Lautapelioppaan etusivulla on elementti, jossa on peliarvosteluja kolmessa palstassa. Aikana ennen Gutenbergia kaikki tämä oli rakennettu shortcodeilla, joilla tehtiin palstat ja pelielementit. Onnistuuhan se niinkin, mutta sivu näytti editorissa aika sekavalta.

Lautapelioppaan kolmisarakkeinen pelilistaus.

Gutenberg paransi tilannetta sikäli, että palstat sai tehtyä Gutenbergin asetteluelementeillä. Itse pelielementit voisi kai myös tehdä Gutenbergin asetteluelementeillä, mutta koen, että siinä kohtaa menisi jo vähän piperrykseksi. Haluaisin mieluummin pitää asettelun erillään elementeistä, koska jos haluan muuttaa asettelua, haluan että se muuttuu kerralla yhdestä paikasta kaikille peleille.

Ja onhan tämä aika kamalan näköistäkin:

Lautapelioppaan etusivun pelilistauksen muokkausnäkymä Gutenbergissä.

Palstan kapeus on oma ongelmansa, johon tartun jutun lopussa, mutta ei noiden pelien shortcodejen muokkaaminen mitään lystiä ole. Entäpä jos tämän tekisikin omana lohkona?

Lohkon luominen ACF:llä

Kun ACF oli muutenkin otettu käyttöön Lautapelioppaassa, se oli ilmeinen työkalu tehtävään.

Lohkon rekisteröiminen käy helposti:

 add_action( 'acf/init', 'peli_block_init' );
function peli_block_init() {
	if ( ! function_exists( 'acf_register_block' ) ) {
		return;
	}

	acf_register_block(array(
		'name'            => 'peli',
		'title'           => __( 'Peli' ),
		'description'     => __( 'Etusivun pelilohko.' ),
		'render_callback' => 'peli_block_render_callback',
		'enqueue_style'   => get_stylesheet_directory_uri() . '/css/pelilohko.css',
		'category'        => 'formatting',
		'icon'            => 'media-default',
		'keywords'        => array( 'peli' ),
	));
}

Funktio ajaa acf_register_block()-funktion, jonka parametreissä on määritelty lohkon ominaisuudet. Nimet ja avainsanat ovat selkeä juttu. render_callback on funktio, joka renderöi lohkon, palataan siihen kohta, ja enqueue_style osoittaa lohkon muotoilun sisältävään CSS-tiedostoon. icon on viittaus kuvakkeena käytettävään Dashiconiin.

Renderöintifunktio perustuu pitkälti alkuperäiseen shortcodeen ja näyttää tältä:

function peli_block_render_callback( $block ) {
	$peli   = get_field( 'peli' );
	$kuvaus = get_field( 'kuvaus' );
	$thumb  = mikko_get_thumb( $peli->ID );
	
	$id = 'peli-' . $block['id'];
	if( ! empty( $block['anchor'] ) ) {
	    $id = $block['anchor'];
	}
	
	$class = 'peli';
	if( ! empty( $block['className'] ) ) {
	    $class .= ' ' . $block['className'];
	}
	if( ! empty( $block['align'] ) ) {
	    $class .= ' align' . $block['align'];
	}

	?>
	<div id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
		<div class="pelikuva"><img class="size-full" src="<?php echo $thumb; ?>" alt="<?php echo esc_attr( get_the_title( $peli->ID ) ); ?>" width="70" height="70" /></div>
		<p><a href="<?php the_permalink( $peli->ID ); ?>"><?php echo get_the_title( $peli->ID ); ?></a> – <?php echo $kuvaus; ?></p>
		</div>
	<?php
}

ACF-kentistä haetaan lohkon sisältö. Kentässä peli on post object, kuvaus on tekstikenttä ja pienoiskuva haetaan omalla funktiolla ID:n perusteella (pienoiskuvat on varastoitu avainkenttiin, mutta koska kuva voi olla kahdessa eri kentässä, välissä on oma funktio ettei samaa koodia tarvitse kirjoittaa moneen paikkaan).

Elementin id, class ja align noukitaan myös lohkon tiedoista. Tässä tapauksessa näitä ei varsinaisesti tarvita, mutta joskus niille voi olla käyttöä.

Sitten vain tulostetaan HTML-koodia. Tyylit määritellään erillisessä tiedostossa, jonka WordPress liittää automaattisesti mukaan sekä ylläpidossa että front endin puolella aina kun lohkoa käytetään:

.peli { 
	font-size: 90%%;
	display: grid;
	grid-template-columns: 100px auto;
}

.peli p {
	font-size: 90%%;
}

.pelikuva {
    margin-top: 5px;
}

.editor-styles-wrapper .peli p {
	margin-top: 0;
}

Kenttien määritteleminen

Vielä puuttuu lohkon käyttämien kenttien määritteleminen. Kentistä pitää tehdä kenttäryhmä (Field Group), joka yhdistetään sijaintisäännöllä haluttuun lohkoon.

Koska en halua luoda kenttiä käyttöliittymän kautta naksuttelemalla, käytän Geniemin kehittämää ACF Codifieria. Codifierilla kentät on melko suoraviivaista määritellä suoraan koodissa kulkematta käyttöliittymän kautta. Tällä saavutetaan esimerkiksi se merkittävä etu, että kun saitti on versionhallinnassa (ja saitithan ovat versionhallinnassa), muutokset rekisteröityvät versionhallintaan.

Luodaan siis tarvittavat kentät:

namespace Geniem\ACF;

// Luodaan kenttäryhmä.
$peli_block   = new Group( 'Pelilohko', 'pelilohko' );

// Määritetään säännöt.
$peli_saannot = new RuleGroup();
$peli_saannot->add_rule( 'block', '==', 'acf/peli' ); // Huomaa acf/-etuliite.
$peli_block->add_rule_group( $peli_saannot );

// Rekisteröidään kenttäryhmä.
$peli_block->register();

// Luodaan Post Object -kenttä.
$linkitetty_peli = new Field\PostObject( 'Peli', 'peli', 'peli' );

// Rajataan artikkelilaji ja kategoria.
$linkitetty_peli->add_post_type( 'post' );
$linkitetty_peli->add_taxonomy( 'category:peliarvostelut' );

// Luodaan Text Area -kenttä.
$kuvausteksti = new Field\Textarea( 'Kuvaus', 'kuvaus', 'kuvaus' );

// Lisätään kentät ryhmään.
$peli_block->add_field( $linkitetty_peli );
$peli_block->add_field( $kuvausteksti );

Varsin suoraviivaista siis, isoimpana jippona tosiaan tuo sääntöryhmä, jossa lohkon nimeen täytyy huomata laittaa acf/-etuliite, jotta sääntö osuu kohdalleen.

Valmis pelilohko näyttää editorissa nyt tältä:

Valmiita pelilohkoja editorissa.

Paljon parempi!

Leveämpi palsta Gutenbergiin täysleveille sivuille

Gutenbergin editorissa teksti näyttää usein hyvin pitkälti siltä, miltä se julkaistunakin näyttää. Ainakin Twenty Twenty -teeman kanssa täysleveät sivupohjat ovat merkittävä poikkeus: editori käyttää täysleveillä sivuillakin samaa kapeaa palstaa kuin muillakin sivuilla. Kuten yllä nähtiin, se näyttää tässä tapauksessa hirveältä ja valmiin lohkon kohdalla oleva leveämpi palsta toimii paljon paremmin.

Asian korjaamiseen ei onneksi tarvita kuin hieman koodia:

add_filter( 'admin_body_class', 'lautapeliopas_fullwidth_body', 99 );
function lautapeliopas_fullwidth_body( $body_class ) {
	if ( 'templates/template-full-width.php' === get_page_template_slug() ) {
		$body_class .= ' full-width';
	}
	return $body_class;
}

add_action( 'enqueue_block_editor_assets', 'lautapeliopas_gutenberg_assets' );
function lautapeliopas_gutenberg_assets() {
	wp_enqueue_style( 'lautapeliopas-gutenberg', get_stylesheet_directory_uri() . '/css/gutenberg.css', false );
}

Ensimmäinen funktio liittää editorissa body-elementille luokan full-width jos käytössä on täysleveä sivupohja. Toinen funktio lataa käyttöön oman tyylitiedoston Gutenbergiin.

Tuossa tyylitiedostossa määritellään sitten vain näin:

.full-width .wp-block {
    max-width: 100%%;
}

Nyt kun editorissa on auki täysleveää sivupohjaa käyttävä sivu, blokkien leveys on 100%.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *

This site uses Akismet to reduce spam. Learn how your comment data is processed.