COS WP Woo
Torna al blog

Sostituzione ACF: campi personalizzati con blocchi e ripetitori Gutenberg

ACF Pro costa fino a $ 249 all'anno e, dopo aver acquistato WP Engine, il futuro del plugin è in discussione. Ti dirò come abbiamo creato una sostituzione completa: oltre 20 tipi di campo, ripetitore, contenuto flessibile, blocchi Gutenberg - con archiviazione in tabelle personalizzate ottimizzate invece del gonfio wp_postmeta.

Sei mesi fa mi ha chiamato una vecchia conoscenza, il direttore tecnico di un distributore industriale che ha un negozio online su WooCommerce con sedicimila prodotti. Sembrava uno che avesse appena ricevuto la fattura per la riparazione del paraurti e allo stesso tempo avesse scoperto che CASCO non la copre. "Oleg", dice, "il nostro abbonamento ACF Pro sta per scadere, hanno cambiato i prezzi e ora per il nostro volume di siti chiedono duecentoquarantanove dollari all'anno. Ho anche letto che WP Engine li ha acquistati e ora tutti si chiedono cosa succederà dopo. Siamo completamente legati a loro: tutte le schede dei prodotti, tutte le caratteristiche, la selezione per viscosità, intervalli di temperatura. Se chiudono o interrompono l'API, ci alzeremo in piedi." E questa frase - "risorgeremo" - ha attirato la mia attenzione, perché non è la prima volta che la sento. Lo sento almeno una volta al mese da persone diverse, e dietro c'è lo stesso problema, a cui poche persone pensano finché non li colpisce sulla fronte.

Il problema sembra semplice: dipendenza da un plugin di terze parti per funzionalità critiche. ACF - Advanced Custom Fields - è diventato di fatto lo standard per i campi personalizzati in WordPress. Quasi tutti i negozi WooCommerce che sono andati oltre il semplice “nome-prezzo-descrizione” utilizzano ACF o i suoi analoghi in un modo o nell’altro. Caratteristiche del prodotto, specifiche tecniche, documentazione, connessioni tra prodotti, condizioni di consegna per articoli specifici: tutto questo vive in campi personalizzati. E tutto questo, infatti, è nelle mani di uno sviluppatore terzo che può cambiare le regole del gioco in qualsiasi momento. Questo è esattamente quello che è successo.

Quando WP Engine ha acquisito ACF, un'ondata di ansia ha attraversato la comunità. Non perché WP Engine sia una cattiva compagnia, ma perché la storia di WordPress è piena di esempi in cui l’acquisizione di un plugin da parte di un player importante ha portato a conseguenze inaspettate. A volte un plugin semplicemente smette di svilupparsi. A volte le politiche dei prezzi cambiano così che le piccole imprese sono costrette a cercare alternative. A volte vengono apportate modifiche che interrompono la compatibilità con le versioni precedenti. E ti siedi con i tuoi sedicimila prodotti, che hanno da venti a trenta campi personalizzati ciascuno, e pensi: cosa dovresti fare? Mossa? Dove? Su cosa? Queste domande non sono astratte; Li ho ricevuti sotto forma di chiamate dirette da clienti che hanno investito anni di lavoro nei loro negozi WooCommerce.

Ricordo che, durante una conferenza WordPress a Mosca, ho avuto una conversazione con il proprietario di una rete di centri di assistenza auto, che aveva un catalogo di pezzi di ricambio su WooCommerce di dodicimila articoli. Ha detto che durante l'aggiornamento di ACF dalla versione 6.1 alla 6.2, tutti i campi condizionali sulle schede prodotto “sono caduti”. I campi semplicemente smisero di essere visualizzati, perché i meccanismi interni della logica condizionale cambiarono. Hanno risolto il problema in due giorni, ma durante questi due giorni il sito ha funzionato con schede prodotto errate. Dodicimila carte con caratteristiche mancanti non sono solo un “inconveniente”, è una perdita diretta nella conversione. E non è colpa di ACF: hanno migliorato il prodotto. Ma la dipendenza dal codice di terze parti significa che accetti qualsiasi modifica, anche quelle per le quali non sei pronto.

Ci ho pensato non come teorico, ma come praticante. Nel nostro progetto principale, un grande distributore di lubrificanti, la tabella wp_postmeta è cresciuta fino a raggiungere novecentotrentasette megabyte. Quasi un gigabyte solo di metadati. Sedicimilaottocentoquarantaquattro beni, ciascuno con decine di campi. Viscosità, punto di infiammabilità, punto di scorrimento, approvazioni del produttore, GOST, serie, linea, tipo di base - e ho appena iniziato a elencarli. E tutto questo è in wp_postmeta, perché è così che funziona ACF. Ogni valore è una riga separata nella tabella. Ogni ripetitore contiene qualche riga in più con metainformazioni sul numero di elementi. E quando esegui WP_Query con una meta query su tre o quattro campi contemporaneamente, il database inizia a piangere. Non sto esagerando. Ho visto che le query impiegano otto secondi per essere completate su un server con unità NVMe e trentadue gigabyte di RAM.

E se lo guardassimo diversamente? Non come un compito tecnico - sostituire un plugin con un altro - ma come una decisione strategica su chi affidare i tuoi dati aziendali? Quando lavoravo con aziende industriali che costruivano sistemi ERP, nessuna di loro considerava seriamente l’opzione “spostamo la logica chiave in un modulo di terze parti che non controlliamo e per il quale paghiamo un abbonamento annuale”. Sarebbe assurdo. Ma per qualche motivo nel mondo WordPress questa è considerata la norma. Un'azienda con un catalogo di ventimila prodotti memorizza tutte le caratteristiche, tutti i collegamenti, tutti i parametri tecnici in un plugin di terze parti. E paga per questo privilegio. E rischia di perdere l'accesso ad ogni aggiornamento. Forse è ora di smettere di considerarla la norma e iniziare a costruire infrastrutture che ti appartengono?

Ecco perché, quando abbiamo progettato il modulo dei campi personalizzati per COS WP Woo, ho impostato l'attività più ampia del semplice "fai come ACF, solo gratuitamente". La gratuità è un bel bonus, ma non l'obiettivo. L'obiettivo è farlo bene. Assicurati che non faccia male tra due anni, quando la base avrà triplicato le sue dimensioni. E ciò che è ancora più importante è non ritrovarti in una situazione in cui la funzionalità chiave della tua attività dipende dalle decisioni di un fornitore che non controlli.

Perché wp_postmeta è una trappola architetturale

Vediamo perché sono così insistente nel dire che memorizzare campi personalizzati in wp_postmeta è una cattiva idea, soprattutto per i negozi online con un ampio catalogo. WordPress è stato creato come piattaforma di blogging. La tabella postmeta è stata progettata per memorizzare informazioni aggiuntive sui record: una coppia chiave-valore per ciascun record. Funziona alla grande quando hai un centinaio di articoli e ciascuno ha tre o quattro campi allegati. Ma quando si hanno sedicimila prodotti e venticinque campi ciascuno, si ottengono quattrocentomila righe solo per valori diretti. E se ci sono anche ripetitori con tre elementi ciascuno, moltiplica per tre. Inoltre stringhe tecniche utilizzate da ACF per memorizzare le chiavi di campo, l'ordine degli elementi nel ripetitore e i flag. Di conseguenza, otteniamo facilmente da un milione a una riga e mezza in una tabella.

Ed è qui che inizia il divertimento. MySQL gestisce perfettamente un milione di righe, se indicizzi ed esegui query sui dati correttamente. Ma wp_postmeta ha una struttura specifica: post_id, meta_key, meta_value. L'indice è su post_id e meta_key. Quando cerchi "tutti i prodotti con viscosità = 5W-30 E punto di infiammabilità maggiore di duecento E approvazione KAMAZ = sì", MySQL deve creare diversi JOIN della tabella postmeta su se stesso. Ogni meta query è un JOIN separato. Tre condizioni: tre JOIN della stessa tabella di novecento megabyte. E l'ottimizzatore delle query inizia a fare miracoli, ma non i miracoli che ti aspetti. Cerca di trovare il piano di esecuzione ottimale, esamina le opzioni, a volte sceglie una ricerca completa della tabella e ottieni una richiesta che blocca il server.

Abbiamo misurato. Sul nostro server di produzione con cache Redis e MySQL ottimizzato, una query con tre metacondizioni su un catalogo di sedicimila prodotti richiedeva dai tre agli otto secondi senza cache. Con Redis è più veloce, ma solo quando la cache è calda. E la cache viene invalidata ogni volta che il prodotto viene aggiornato. E quando ti sincronizzi con 1C, che aggiorna saldi e prezzi una volta ogni ora, la cache viene invalidata ciclicamente. Si scopre che si tratta di un circolo vizioso: installi Redis per velocizzare le meta query, ma la sincronizzazione uccide la cache e gli utenti attendono nuovamente dai cinque agli otto secondi sulla pagina di filtro. Questo non è un problema teorico, è la realtà quotidiana di qualsiasi negozio WooCommerce con integrazione con un sistema contabile.

Quando abbiamo progettato il modulo CF in COS WP Woo, abbiamo immediatamente immaginato un'architettura di storage diversa. Tre tabelle personalizzate: wpaic_cf_field_groups per i gruppi di campi, wpaic_cf_fields per le descrizioni dei campi e wpaic_cf_values ​​per i valori. La tabella dei valori è strutturata in modo diverso: conosce i tipi di dati, le relazioni tra i campi e la nidificazione. Non memorizza tutto come testo in meta_value, ma utilizza colonne tipizzate. I valori numerici vengono memorizzati come numeri, le date come date, JSON come JSON. Ciò consente a MySQL di utilizzare indici normali e ottimizzazione normale. La stessa query con tre condizioni che richiedeva otto secondi in postmeta viene eseguita in duecento-trecento millisecondi su tabelle personalizzate. La differenza è da venti a trenta volte. E questa non è una cifra di marketing: è una misurazione basata su dati reali, su un server di produzione reale con un carico reale.

C'è un'altra sfumatura non ovvia di cui si parla raramente. La colonna meta_value in wp_postmeta è di tipo LONGTEXT. Ciò significa che l'indice su questa colonna è parziale, basato solo sui primi caratteri. Quando esegui una meta query con l'operatore uguale, MySQL può utilizzare l'indice. Ma quando hai bisogno di un LIKE o di un confronto numerico, l'indice è inutile perché MySQL non sa che meta_value memorizza un numero. È costretto a convertire la stringa in un numero per ogni riga della tabella. Su novecento megabyte di dati, ciò significa una ricerca completa. E nessuna impostazione MySQL aiuterà: il problema è nell'architettura di archiviazione stessa e non nella configurazione del server. Lo abbiamo testato utilizzando EXPLAIN su query reali: MySQL ha mostrato onestamente il tipo: ALL, ovvero una scansione completa della tabella.

Ma il punto è questo. L'archiviazione rapida è solo la base. All'utente nell'amministratore di WordPress non interessa dove si trovano fisicamente i suoi dati. Per lui è importante che l'interfaccia funzioni bene, che i campi siano creati facilmente, che i ripetitori non abbiano problemi e che Gutenberg visualizzi normalmente i contenuti personalizzati. E qui arriviamo a ciò che costituisce effettivamente il valore fondamentale di ACF: non l'archiviazione dei dati, ma l'interfaccia di gestione. E qui occorreva non solo ripetere quanto fatto da ACF, ma fare un passo avanti.

Venti tipi di campi e un'interfaccia che non richiede istruzioni

Quando ho analizzato il modo in cui i nostri clienti utilizzano ACF, ho compilato un elenco dei tipi di campo riscontrati più spesso. Campo di testo, area di testo, numero, email, URL: queste sono le cose fondamentali di cui non puoi fare a meno. Anche la selezione, la casella di controllo e la radio sono standard. Ma poi iniziano cose più interessanti: relazioni tra oggetti, una galleria di immagini, data e ora, selettore di colori, editor WYSIWYG, file allegati, commutazioni vero/falso, Google Maps (anche se quest'ultimo, a dire il vero, serve solo a pochi). E questi tipi “avanzati” sono ciò che rende i campi personalizzati uno strumento davvero potente.

Abbiamo implementato più di venti tipi di campo nel modulo CF per COS WP Woo. Non trasformerò l’articolo in una documentazione tecnica elencandoli tutti, ma voglio evidenziarne alcuni che considero fondamentali per i negozi WooCommerce e che abbiamo implementato in un modo fondamentalmente diverso rispetto ad ACF.

CfRelationshipField - relazioni tra oggetti. Questo è ciò che utilizzano quasi tutti i nostri clienti e ciò che ACF non funziona idealmente su cataloghi di grandi dimensioni, per usare un eufemismo. Quando hai sedicimila prodotti e devi selezionare quelli correlati, la ricerca AJAX in ACF inizia a rallentare. Inserisci tre lettere, aspetti un secondo o due, arrivano i risultati, ma non sei sicuro di aver trovato tutti i prodotti corrispondenti, perché ACF limita l'output. La nostra implementazione di CfRelationshipField utilizza la ricerca indicizzata e l'impaginazione. Inizi a inserire il nome del prodotto e i risultati appaiono immediatamente, anche su un catalogo di ventimila articoli. Perché la ricerca non viene effettuata tramite meta_value tramite LIKE, ma tramite normali indici full-text. E i risultati sono impaginati: puoi scorrere tutte le corrispondenze, invece di sperare che il prodotto che ti serve sia tra i primi venti.

CfGalleryField - galleria di immagini. Altro punto dolente. In ACF, la galleria viene eseguita tramite il caricatore multimediale standard di WordPress ed è... tollerabile. Ma quando devi caricare dieci foto di un prodotto, ordinarle nell'ordine corretto, ritagliarne una, sostituirne un'altra: il processo si trasforma in una sequenza di clic su finestre modali. Ho aperto il catalogo multimediale, ho selezionato un file, l'ho chiuso, ho capito che dovevo ritagliarlo: l'ho riaperto, ho trovato il file, ho aperto l'editor, l'ho ritagliato, salvato, chiuso. Il nostro CfGalleryField è integrato direttamente nel metabox: caricamento dei file tramite trascinamento della selezione direttamente nell'area del campo, ordinamento tramite trascinamento della selezione, ritaglio delle immagini senza uscire dall'editor del prodotto. Sembra una cosa da poco, ma quando un content manager elabora cinquanta prodotti al giorno, ogni clic salvato viene moltiplicato per cinquanta. In una settimana si accumula un'ora e mezza di tempo puro. In un mese: un'intera giornata lavorativa. Non mi piace contare l'efficienza in minuti, ma quando la differenza è così evidente, i numeri parlano da soli.

E ora parliamo di ciò che distingue il lavoro professionale con campi personalizzati dal lavoro amatoriale: Ripetitore e Contenuto flessibile. Due tipologie di campi che ACF tiene dietro un muro a pagamento da molto tempo, e che determinano sostanzialmente se è possibile costruire o meno una directory seria con una struttura dati complessa su WordPress.

Ripetitore e Contenuto Flessibile: quando i semplici campi non bastano

Sai cosa è divertente? Quando mostro ai nuovi clienti un elenco di tipi di campo, di solito dicono: "Bene, abbiamo solo bisogno di testo e selezione, il resto non è necessario". E dopo tre mesi di lavoro, usano relazioni, gallerie, ripetitori e contenuti flessibili, e chiedono: “Esiste un tipo di campo per...” I bisogni crescono con la comprensione delle possibilità. Pertanto, per noi era di fondamentale importanza implementare tutti i venti e più tipi contemporaneamente e non aggiungerli gradualmente. Perché quando il cliente si rende conto che ha bisogno di un ripetitore, ma non c'è, torna ad ACF. E poi è quasi impossibile restituirlo. Le prime impressioni contano, e se il primo giorno di utilizzo una persona non trova il tipo di campo desiderato, basta, non ci sarà una seconda possibilità.

Onestamente, il ripetitore è la funzionalità per la quale la maggior parte delle persone acquista ACF Pro. La versione gratuita di ACF non lo prevede, ed è questo il motivo principale per cui si spendono quarantanove dollari l'anno per l'abbonamento. Cos'è il ripetitore nel contesto di WooCommerce? Immagina una scheda prodotto: olio motore. Ha le approvazioni delle case automobilistiche: BMW Longlife-01, Mercedes-Benz MB 229.5, Volkswagen VW 502.00. Ogni tolleranza è più di una semplice riga di testo. Si tratta di un oggetto con un nome, numero, stato (valido o obsoleto) e un collegamento a un documento di conferma. E un olio può avere da due a quindici tolleranze di questo tipo. Come memorizzarlo senza un ripetitore? Ovviamente puoi inserire tutto in un campo di testo separato da virgole. Ma in questo caso non sarai in grado di filtrare correttamente per tolleranze, non sarai in grado di visualizzarli in una forma strutturata, non sarai in grado di verificarne la validità. Oppure puoi creare quindici campi separati “Tolleranza 1”, “Tolleranza 2”... “Tolleranza 15” - ma questo è brutto e inflessibile.

Repeater risolve questo problema in modo elegante. Crei un gruppo di sottocampi - "Nome dell'approvazione", "Numero", "Stato", "Documento" - e indichi che questo gruppo è ripetibile. Nell'editor del prodotto, il gestore dei contenuti vede il pulsante "Aggiungi autorizzazione", fa clic su di esso e viene visualizzato un nuovo blocco con quattro campi. Compilato, cliccato di nuovo: è apparso il secondo blocco. Devi cambiare l'ordine: trascina e rilascia con il mouse. È necessario eliminare: fare clic sulla croce. Tutto è intuitivo, tutto funziona. Il manager non ha bisogno di sapere nulla sul database, su JSON o sui meta campi: deve semplicemente fare clic su "Aggiungi" e compilare il modulo.

Il nostro CfRepeaterField in COS WP Woo va oltre il ripetitore ACF standard in diversi modi importanti. In ACF, i dati del ripetitore vengono archiviati in postmeta come un insieme di meta campi separati: _tolerances_0_name, _tolerances_0_number, _tolerances_1_name, _tolerances_1_number e così via. Più un campo separato _tolerances, che memorizza il numero di elementi. Per un prodotto con dieci tolleranze e quattro sottocampi, si tratta di quarantuno voci postmeta per un solo ripetitore. Quarantuno righe in una tabella che pesa già quasi un gigabyte. E se hai tre ripetitori su un prodotto - uno per le omologazioni, uno per le caratteristiche tecniche, uno per la documentazione - ottieni facilmente centoventi righe in postmeta per un prodotto. Moltiplicate per sedicimila prodotti e otterrete quasi due milioni di linee solo dai ripetitori. La nostra implementazione memorizza i dati del ripetitore come documento JSON in un campo di una tabella tipizzata. Tutte e dieci le tolleranze con tutti i sottocampi: una voce invece di quarantuno. Allo stesso tempo, la ricerca e il filtraggio funzionano tramite le funzioni JSON di MySQL, che nella versione 8.0 e successive sono abbastanza veloci e supportano l'indicizzazione.

Ma il ripetitore è solo una piccola cosa. Il vero potere inizia dai contenuti flessibili. Immagina di dover creare non solo un insieme ripetibile di campi identici, ma un costruttore da blocchi diversi. Nella pagina di un brand, ad esempio, possono essere presenti: un blocco di testo con una descrizione, un blocco con caratteristiche sotto forma di tabella, un blocco con una gallery prodotti, un blocco con una video recensione, un blocco con recensioni dei rivenditori. Ciascuno di questi blocchi ha la propria struttura di campo: il blocco di testo ha solo un editor WYSIWYG, la galleria ha una serie di immagini con didascalie, la tabella delle caratteristiche ha un ripetitore con coppie parametro-valore. E l'utente dovrebbe essere in grado di aggiungere qualsiasi blocco in qualsiasi ordine, come un costruttore Lego. Questo è contenuto flessibile.

CfFlexibleContentField nel nostro modulo implementa esattamente questo scenario. Definisci una serie di "layout", ciascuno con i propri campi. E nell'editor, il gestore dei contenuti seleziona il layout desiderato, lo aggiunge alla pagina e compila i campi. Magari aggiungerne un altro uguale o diverso. Può trascinare i blocchi e cambiare l'ordine. Il risultato è una struttura di pagina completamente personalizzata, assemblata da componenti già pronti, senza una singola riga di codice. E credo che il contenuto flessibile sia ciò che trasforma WordPress da una piattaforma di blogging in un vero e proprio sistema di gestione dei contenuti di livello aziendale. Perché senza di essa ogni pagina non standard richiede l'intervento dello sviluppatore, ma il gestore dei contenuti può gestirla da solo. Per le aziende B2B questo è di fondamentale importanza: pagine di marca, cataloghi di prodotti per settore, sezioni tecniche: tutto questo deve essere aggiornato regolarmente ed è semplicemente non redditizio attirare un programmatore ogni volta.

E qui arriviamo a un argomento che è stato una vera rivelazione per me: l'integrazione dei campi personalizzati con Gutenberg. Quando ho iniziato questo progetto, ero scettico. Pensavo che Gutenberg fosse goffo e ridondante per WooCommerce. Ma mi sbagliavo, ed ecco perché.

Blocchi Gutenberg e costruttori di regole visive

Sapete cosa mi ha irritato di più dell'ACF? Il fatto che i campi personalizzati vivano separatamente dal contenuto. Apri l'editor del prodotto, in alto c'è Gutenberg con una descrizione, e da qualche parte sotto, sotto le cinque schermate a scorrimento, ci sono i metabox ACF con campi personalizzati. Due universi separati che non sanno nulla l'uno dell'altro. Il gestore dei contenuti è costretto a scorrere avanti e indietro, a ricordare di cosa è responsabile e a sperare di non aver mancato un campo obbligatorio da qualche parte nei metabox inferiori. Questo non è un problema di architettura: è un problema di esperienza dell'utente. E per un content manager che lavora con cinquanta prodotti al giorno, questa esperienza determina la sua produttività.

Ho visto progetti in cui le persone inventano i propri campi ripetibili a livello di tema, tramite JavaScript e AJAX nell'amministratore. Ha funzionato, ma ogni aggiornamento di WordPress o WooCommerce si è trasformato in una lotteria. Il ripetitore autoprodotto potrebbe rompersi a causa di una modifica in jQuery, a causa di un nuovo formato metabox o a causa di un aggiornamento dell'editor TinyMCE. E ogni volta lo sviluppatore ha passato ore a sistemare quella che dovrebbe, in buona fede, essere la funzionalità standard della piattaforma. I campi personalizzati con blocchi ripetibili non sono un lusso, sono l'infrastruttura di base per qualsiasi directory seria. E il fatto che WordPress non lo includa ancora nel core è uno dei motivi principali per cui esiste un intero settore dei plugin attorno ai campi personalizzati.

Quando abbiamo progettato il modulo CF, ho fissato un obiettivo: ogni gruppo di campi personalizzati dovrebbe ricevere automaticamente una visualizzazione a blocchi in Gutenberg. Non “può essere configurato tramite un plugin separato”, non “richiede ulteriore sviluppo”, ma automaticamente. Ho creato un gruppo di campi e il blocco corrispondente è apparso immediatamente in Gutenberg. Ciò viene implementato tramite il componente CfBlocks, che registra dinamicamente i blocchi Gutenberg in base alla configurazione dei gruppi di campi. Tecnicamente funziona così: quando si salva un gruppo di campi, il codice PHP genera una registrazione del blocco tramite Register_block_type() e il componente React esegue il rendering del modulo di input direttamente nell'editor.

Come si presenta in pratica? Supponiamo che tu abbia creato un gruppo di campi “Caratteristiche tecniche olio” con i seguenti campi: viscosità, punto di infiammabilità, punto di scorrimento, tolleranze del produttore, area di applicazione. Dopo aver salvato il gruppo, il blocco Specifiche dell'olio appare nella libreria dei blocchi Gutenberg. Il gestore dei contenuti può inserirlo direttamente nel contenuto del prodotto, accanto alla descrizione, tra i paragrafi, ovunque. E i campi vengono visualizzati nel contesto del contenuto, anziché in un metabox separato nella parte inferiore della pagina. Ciò cambia radicalmente il flusso di lavoro. Invece di "compilare la descrizione in alto, quindi scorrere verso il basso e compilare le caratteristiche", si ottiene un unico flusso: descrizione, quindi un blocco con caratteristiche, quindi un'altra descrizione, quindi un blocco con tolleranze. Tutto è in un unico posto, nel giusto ordine.

Naturalmente abbiamo mantenuto anche l'approccio classico con i metabox. Non tutti gli utenti sono pronti per Gutenberg e non tutti gli script richiedono la rappresentazione a blocchi. Ci sono aziende in cui l’editor di WordPress è impostato in modalità classica e cambiare le abitudini delle persone non è compito nostro. Se sei abituato ai metabox, per favore, funzionano esattamente come in ACF. Ma l’opportunità di passare ai blocchi esiste e non richiede ulteriori sforzi. È una questione di preparazione del team, non di limitazioni tecniche.

Veniamo ora ai visual designer: una delle cose di questo modulo di cui sono più orgoglioso. CfLocationRulesBuilder è un costruttore visivo che determina esattamente dove verranno visualizzati i campi personalizzati. In ACF, funziona tramite elenchi a discesa: "Mostra questo gruppo di campi se il tipo di record è prodotto E la categoria di prodotto è masla". Errori, testo breve, logica AND/OR non ovvia che confonde anche gli utenti esperti. Il nostro builder è un'interfaccia visiva costruita in React, dove le regole sono rappresentate come carte. Vedi letteralmente la logica: questo blocco di condizioni è collegato tramite AND e ad un altro blocco tramite OR. Trascini le carte, cambi le condizioni e capisci subito cosa accadrà. L'ho mostrato a diversi content manager che in precedenza avevano avuto paura di toccare le impostazioni ACF per mesi: l'hanno capito in cinque minuti. Nessuna documentazione, nessuna formazione.

CfConditionalLogicBuilder va ancora oltre. Questa è una logica condizionale a livello di singolo campo: mostrare o nascondere un campo in base ai valori di altri campi. Ad esempio, se il tipo di olio è “motore”, mostrare il campo “tolleranze motore”. Se la tipologia è “idraulica”, mostrare il campo “Classe ISO”. Se viene selezionato il produttore “Shell”, mostrare il campo aggiuntivo “Shell line”. Perché è necessario? Quindi, la scheda prodotto per l'olio motore e l'olio idraulico sono due schede diverse con una serie di campi diversa. E invece di mostrare al manager tutti e trenta i campi contemporaneamente (metà dei quali non applicabili), la logica condizionale mostra solo quelli rilevanti. Meno campi - meno errori - completamento più veloce. ACF ha questo, ma è implementato come un semplice elenco di condizioni senza feedback visivo. Il nostro builder mostra visivamente le connessioni tra i campi: vedi quali campi dipendono da quali, dove viene applicata quale logica. E, cosa più importante, puoi testare le condizioni direttamente nel designer, senza andare nell'editor del prodotto.

Mi chiedo da molto tempo se questi visual builder valgano il mio tempo. Il codice è proprio questo: potrebbe essere semplicemente un file di configurazione o un'API software. Ma poi mi sono ricordato quante volte i clienti mi hanno chiamato con la domanda "perché questo campo non viene visualizzato in questa o quella categoria?" - e la risposta era sempre la stessa: le regole di localizzazione erano configurate in modo errato perché l'interfaccia di configurazione era incomprensibile. Il visual designer non risolve tutti i problemi del mondo, ma risolve questo in particolare: le persone smettono di commettere errori durante la configurazione e smettono di chiamarmi. E questo, credetemi, vale le settimane di sviluppo che abbiamo dedicato a questi componenti.

Livello di compatibilità ed ecosistema: perché non è solo un altro plugin

Quando abbiamo iniziato a progettare il modulo CF, mi sono subito reso conto che il novanta per cento dei potenziali utenti erano persone che già utilizzavano ACF. E non sono pronti semplicemente a “prendere e cambiare”. Hanno modelli di temi che chiamano get_field() e the_field(). Hanno plugin che si integrano con ACF tramite la sua API. Hanno un codice personalizzato in Functions.php che utilizza gli hook ACF. Muoversi senza un livello di compatibilità significa: riscrivere l'intero frontend del sito, tutti i template, tutte le integrazioni. Per un sito con sedicimila prodotti questo significa mesi di lavoro e un rischio enorme di rompere qualcosa. Questo non è un rischio che un business intelligente correrebbe, anche se il nuovo strumento è oggettivamente migliore.

Pertanto, abbiamo implementato Register_cf_compat() - un livello di compatibilità che intercetta tutte le funzioni ACF standard e le instrada al nostro modulo. Le funzioni get_field(), the_field(), get_sub_field() e have_rows() funzionano tutte. Puoi disattivare ACF, attivare il nostro modulo e i tuoi modelli continueranno a funzionare senza modificare una singola riga di codice. Il livello di compatibilità funziona a livello delle funzioni wrapper. Quando il tuo modello chiama get_field con una chiave di campo e un ID post, il nostro wrapper determina a quale gruppo di campi appartiene il campo, accede alla tabella wpaic_cf_values ​​invece che a postmeta e restituisce il valore nello stesso formato restituito da ACF. Per i ripetitori, la logica è più complicata: have_rows() inizializza l'iteratore interno, the_row() sposta il puntatore, get_sub_field() recupera il valore dalla riga corrente. Tutti questi meccanismi vengono riprodotti esattamente perché comprendiamo: un punto rotto nel modello e il cliente ritorna ad ACF per sempre.

Ma voglio essere sincero: la compatibilità al 100% è un'utopia. Se il tuo codice utilizza direttamente le classi interne ACF o se sei legato a hook specifici che non sono presenti nella documentazione, potrebbero esserci delle sfumature. Abbiamo trattato l'API pubblica, che è descritta nella documentazione e che viene utilizzata nel novantacinque per cento dei casi. I restanti cinque sono esotici che devono essere analizzati individualmente. Per la stragrande maggioranza dei siti, la migrazione si presenta così: installato COS WP Woo, attivato il modulo CF, importati gruppi di campi da ACF, disattivato ACF, controllato: funziona.

La migrazione dei dati è un processo separato. Il livello di compatibilità consente al tuo sito di funzionare immediatamente, ma i dati sono ancora fisicamente in postmeta. Per ottenere vantaggi in termini di prestazioni, dobbiamo trasferire i dati da postmeta alle nostre tabelle personalizzate. Si tratta di un'operazione separata eseguita da un processo in background tramite l'Action Scheduler, senza interrompere il sito, senza tempi di inattività. Per sedicimila prodotti, la migrazione richiede dai venti ai trenta minuti circa. Dopo la migrazione ottieni sia la compatibilità con il vecchio codice che le prestazioni del nuovo storage. E i vecchi dati in postmeta possono essere lasciati come backup o eliminati quando sei sicuro che tutto funzioni correttamente.

E l'API REST? Questa è una domanda che gli sviluppatori si pongono ed è del tutto legittima. Nei progetti moderni, il frontend è sempre più separato dal backend: architettura headless, applicazioni mobili, integrazione con sistemi esterni. L'accesso ai campi personalizzati tramite API non è un lusso, ma una necessità. ACF Pro fornisce un'API REST, ma con avvertenze: è necessario abilitare esplicitamente il supporto API per ciascun gruppo di campi, il formato della risposta non è sempre prevedibile e, per i ripetitori, i dati arrivano in una forma piatta, che è necessario assemblare in modo indipendente in una struttura. Il nostro modulo fornisce un'API REST completa fin dall'inizio. Un controller con CRUD completo per gruppi di campi e valori. I valori dei campi sono disponibili in formato annidato: il ripetitore viene restituito come un array di oggetti, il contenuto flessibile viene restituito come un array di blocchi che indicano il tipo di layout. Nessuna raccolta manuale dei dati lato client. Il formato è prevedibile, documentato e non cambia tra le versioni.

Nove servizi gestiscono il modulo dietro le quinte. CfFieldGroupService gestisce i gruppi di campi. CfFieldService: singoli campi e relative configurazioni. CfFieldValueService: lettura e scrittura di valori. CfRelationshipService: connessioni tra oggetti. Sei pagine React nel pannello di amministrazione danno il pieno controllo: elenco di gruppi di campi, editor di gruppi, progettista di regole di layout, progettista di logica condizionale, migrazione da ACF, impostazioni del modulo. Tutto è basato su componenti standard di WordPress, quindi l'interfaccia sembra nativa e non è in conflitto con altri plugin.

So che molti diranno: “Perché fare tutto questo se ci sono Carbon Fields, Pods, Meta Box?” È una domanda giusta e ti risponderò direttamente. Carbon Fields è un ottimo plugin gratuito, ma non ha un'interfaccia visiva per la creazione di campi nel pannello di amministrazione, tutto avviene tramite codice. Questo è normale per uno sviluppatore, ma è un vicolo cieco per un content manager. Pods è un framework potente, ma è eccessivo per la maggior parte delle attività e ha una curva di apprendimento ripida che intimidisce anche gli utenti WordPress esperti. Meta Box è buono, ma pagato per funzioni avanzate ed è ancora legato al proprio ecosistema di una dozzina di componenti aggiuntivi. Ognuno di essi risolve parte del problema, ma nessuno risolve quello che ho descritto all'inizio: la dipendenza da un fornitore di terze parti per funzionalità mission-critical.

Ma la cosa più importante è che nessuno di questi plugin è integrato con la tua ricerca, il tuo modulo 1C, il tuo B2B. Il modulo CF in COS WP Woo fa parte dell'ecosistema. Funziona insieme al modulo di integrazione 1C, che mappa gli attributi del prodotto da 1C: Trade Management ai campi personalizzati. Funziona con un modulo di ricerca che indicizza i campi personalizzati per la ricerca full-text tramite Typesense. Funziona con il modulo B2B, che utilizza campi personalizzati per configurare i diritti di accesso al gruppo. Quando un manager aggiunge un nuovo permesso al ripetitore, il nostro modulo scrive i dati su wpaic_cf_values, aggiorna l'indice di ricerca Typesense attraverso gli hook del modulo di ricerca e controlla se il permesso si riferisce a KAMAZ o MAZ, aggiunge automaticamente il prodotto alla categoria "Per apparecchiature russe". Un'azione del manager produce tre risultati in sistemi diversi.

Non sto dicendo che ACF sia un cattivo prodotto. È fantastico. Ha stabilito lo standard per i campi personalizzati in WordPress e per questo gli siamo molto grati. Ma il mondo è cambiato. WordPress è diventato una piattaforma per l'e-commerce serio, per portali B2B e per l'integrazione con i sistemi ERP. E i requisiti per i campi personalizzati sono cresciuti così tanto che l’approccio “tutto in postmeta, tutto tramite meta query” ha semplicemente smesso di ridimensionarsi. Non è colpa dell'ACF, è l'evoluzione dei compiti. Uso spesso l'analogia del trasporto. L'ACF è una berlina affidabile che si guida bene in città. Ma quando devi trasportare venti tonnellate di merci da Chelyabinsk a Mosca, prendi un camion. Non perché la berlina sia cattiva, ma perché il compito è diverso.

Per quanto riguarda il costo, contiamo onestamente. ACF Pro costa dai quarantanove ai duecentoquarantanove dollari all'anno, a seconda del numero di siti. In cinque anni: da duecentoquarantacinque a milleduecentoquarantacinque dollari solo per i campi personalizzati. Aggiungete a ciò le estensioni WooCommerce necessarie per il filtraggio in base ai meta campi, per i prezzi B2B basati sui meta campi, per l'indicizzazione della ricerca dei meta campi - e il costo totale di proprietà aumenta da tre a quattro volte. COS WP Woo include tutto questo in un'unica licenza. Campi personalizzati, ricerca, B2B, 1C: tutto funziona insieme, tutto è supportato da un team, tutto viene aggiornato in modo sincrono. Non è necessario verificare la compatibilità di cinque plugin ogni volta che aggiorni. Non è necessario scrivere hook per collegare un plugin a un altro. Non c'è bisogno di pregare che l'aggiornamento ACF non interrompa l'integrazione con il plugin di ricerca.

Ma non voglio che questo articolo sembri una proposta di vendita. Pertanto, sarò onesto su ciò che il nostro modulo non fa ancora. Non abbiamo un plugin separato per il frontend che genererebbe moduli basati su campi personalizzati: abbiamo il nostro modulo moduli per questo. Non disponiamo di blocchi per Elementor o WPBakery: ci affidiamo a Gutenberg e, se il tuo sito è interamente basato su Elementor, l'integrazione avverrà tramite shortcode anziché tramite widget nativi. E il nostro livello di compatibilità con ACF non copre il cento per cento: ho già parlato di scenari esotici. Questa è una posizione onesta e preferisco essere aperto riguardo alle limitazioni piuttosto che occuparmi in seguito degli utenti delusi.

Questo è ciò che penso sia più importante. Quando scegli uno strumento per archiviare e gestire i tuoi dati aziendali (e i campi prodotto personalizzati sono i tuoi dati aziendali), dovresti pensare a un orizzonte da cinque a dieci anni. L’ACF esisterà ancora tra cinque anni? Molto probabilmente sì. Ma costerà lo stesso? Supporterà la stessa architettura? WP Engine lo porterà nella direzione di cui la tua azienda ha bisogno? Nessuno lo sa. E quando hai sedicimila prodotti e la tabella postmeta pesa un gigabyte, ogni risposta sbagliata a queste domande costa carissimo. Scelgo la prevedibilità, uno strumento che controllo, che archivia i dati in modo efficiente, che è integrato con il mio ecosistema e che non dipende dalle decisioni strategiche di un fornitore di terze parti.

C'è un pensiero che voglio lasciare per ultimo. Viviamo in un’era in cui i dati sono la risorsa principale del business. Le caratteristiche dei tuoi prodotti, le loro connessioni, i loro parametri tecnici non sono solo campi di un database. Questa è la conoscenza che la tua azienda ha accumulato nel corso degli anni. La viscosità di ogni olio, la compatibilità con ogni tipo di motore, le raccomandazioni per ogni settore: dietro ogni campo compilato ci sono ore di lavoro tecnico. E questa conoscenza è archiviata in uno strumento che non controlli, in un formato non ottimale per i tuoi compiti, in una tabella che pesa quasi un gigabyte e rallenta ad ogni richiesta. Forse è tempo di pensare a come archiviare correttamente questa conoscenza? È ora di scegliere uno strumento che rispetti i tuoi dati tanto quanto tu rispetti i tuoi clienti.

E se in questo momento sei seduto davanti allo schermo con una lettera aperta sul rinnovo del tuo abbonamento ACF Pro e pensi "e se non rinnovo?" - prova a farti tre domande. Quanto costa in denaro la tua dipendenza da ACF, non solo l'abbonamento, ma anche il tempo per supportare le integrazioni? Quanto pesa la tua tabella postmeta e in che modo ciò influisce sulla velocità del sito? E hai un piano B nel caso in cui ACF cambi l'API o la politica dei prezzi? Se almeno una delle risposte non ti soddisfa, allora è tempo di pensare ai cambiamenti.

Prova COS WP Woo: quattordici giorni gratis. Installa, attiva il modulo campi personalizzati, importa un gruppo da ACF, lavoraci per una settimana. Senti la differenza nella velocità delle richieste, prova il costruttore di regole visive, guarda come funziona il ripetitore in un blocco Gutenberg. E poi decidi: con le tue mani, utilizzando i tuoi dati, senza promesse di marketing. Perché l'argomento migliore è la tua esperienza.