In einem meiner aktuellen Projekte sollte es möglich sein, für Beiträge eines Custom-Post-Types Verknüpfungen zu Beiträgen eines anderen CPTs herzustellen. Ich wusste nicht genau, welche Gutenberg-Komponente dafür am besten geeignet wäre, bin dann aber an dem Feld für die Schlagwörter normaler Beiträge hängen geblieben: bei Nutzereingabe erscheinen passende Schlagwörter und können einer Auswahl hinzugefügt werden.
Mit dem FormTokenField
-Feld kann das Verhalten nachgebaut werden, in der verlinkten Readme sind alle Optionen für die Komponente aufgeführt. Damit war die Komponente gefunden, die ich nutzen wollte, statt Schlagwörtern werden CPT-Posts vorgeschlagen.
So sieht die Komponente bei mir im Einsatz aus (Code ist auf das Minimum verkürzt):
// […]
// `posts` contains post objects from REST API call.
// `selectedPosts` contains array of currently selected post IDs.
let postNames = [];
let postFieldValue = [];
if ( posts !== null ) {
// Create post names array.
postNames = posts.map( ( post ) => post.title.raw );
// Create array of post titles that match the post IDs that are currently selected.
postFieldValue = selectedPosts.map( ( postId ) => {
let wantedPost = posts.find( ( post ) => {
return post.id === postId;
} );
if ( wantedPost === undefined || ! wantedPost ) {
return false;
}
return wantedPost.title.raw;
} );
}
const postsSelectComponent = <FormTokenField
label='Posts'
value={ postFieldValue }
suggestions={ postNames }
maxSuggestions={ 20 }
onChange={ ( selectedPosts ) => {
// Build array of selected posts.
let selectedPostsArray = [];
selectedPosts.map(
( postName ) => {
const matchingPost = posts.find( ( post ) => {
return post.title.raw === postName;
} );
if ( matchingPost !== undefined ) {
selectedPostsArray.push( matchingPost.id );
}
}
)
setAttributes( { selectedPosts: selectedPostsArray } );
} }
/>
Code-Sprache: JavaScript (javascript)
Da ich für den User bei den Vorschlägen natürlich nicht die Post-IDs anzeigen möchte, die ich letztlich als Metawert für den Beitrag speichern will, sondern die Titel der Beiträge, ist es etwas komplizierter als das Beispiel aus der Readme, da ich nach dem Auswählen eines oder mehrerer Werte ab Zeile 27 erst die Namen der gewählten Beiträge in die ID umwandeln muss, bevor ich sie speichern kann.
Am Anfang des Codes wiederum muss ich die IDs in die Titel umwandeln, um das FormTokenField
mit den bereits gewählten Beiträgen befüllen zu können.
Wenn ihr bisher noch nicht für Gutenberg entwickelt habt, kann ich euch meinen Beitrag Einrichtung von Webpack für die Gutenberg-Entwicklung bei KrautPress ans Herz legen.
Hi Florian,
hast du das ganze Beispiel als GIST?
Ich wollte letztes Wochenende exakte das gleiche bauen, bin dann aber einer Stelle hängen geblieben und hab es anders gelöst.
https://github.com/Horttcore/loop-control/blob/develop/src/loop-control.js
Ich hab allerdings noch das Problem das der ServerSideRenderer nicht neu gerendert wird, wenn ich ein Wert ändere. Erst wenn der Block den Focus verliert.
Hast du das Problem auch schon?
Meine Vermutung wäre, das der Wert ein der geändert wird ein Objekt ist und deshalb nicht neu rendert. Ich muss mich da mal wieder nen Abend dran hängen.
Hi Ralf,
ich habe
ServerSideRenderer
noch nicht verwendet, sorry. Hier mal eine vereinfachte Version des Blocks: https://gist.github.com/florianbrinkmann/167939b3e0a8c33a5ae3f1c0dc561859Hab es nicht getestet ob es nach dem Entschlacken noch geht, müsste aber, habe eigentlich nur ein paar Controls gelöscht und das Attribut so umgestellt, dass es nicht mehr als Metawert gespeichert wird.
Hoffe, das hilft!
Florian
Hi Florian,
danke für dein Gist. Hab das ganze mal in meine Komponente übernommen und funktioniert wunderbar!
https://github.com/Horttcore/loop-control/blob/develop/src/loop-control.js
Eine weitere Verbesserung wäre es, wenn das FormTokenField die Suggestions je nach Eingabe aktualisiert. Da du sonst nur maximal 100 Posts durchsuchen kannst. Das liegt daran, dass per_page ein Wert zwischen 1 und 100 annehmen muss. -1 funktioniert leider nicht 😉
Hi Ralf,
super, dass es funktioniert!
Ja, es hat mich auch ein bisschen gewundert, aber in dem Fall funktioniert es tatsächlich doch 🙂 Es werden bei mehr als 100 dann automatisch mehrere Requests mit 100er-Batches gemacht und zusammengefügt.
Viele Grüße
Florian
Edit: Hier der entsprechende Code aus dem Gutenberg-Repo: https://github.com/WordPress/gutenberg/blob/%40wordpress/api-fetch%403.11.0/packages/api-fetch/src/middlewares/fetch-all-middleware.js#L45