Support » Allgemeine Fragen » Wie „individuelle Felder“ global verfügbar machen

  • Gelöst Kai J.

    (@kjoussen)


    Hallo zusammen,

    ich bastel gerade an einem Childtheme mit mehreren verschiedenen Templates, einige davon können mit den „individuellen Feldern“ ein wenig beeinflusst werden.

    Was mich wundert und trotz tiefster Suche (selbst bei Google war ich auf Seite 3) habe ich keine Lösung gefunden.

    Wie gesagt, mit custom fields kann das Erscheinungsbild der Ausgabe eines Templates beeinflusst werden.
    Wenn ich auf einer Seite mit Beiträgen für eine Kategorie diese custom fields eintrage – also Name und Wert geht alles.
    Aber wieso merkt sich WP diese Felder nicht?
    Wenn ich auf einer anderen Seite (gleiches Template) mit Beiträgen einer anderen Kategorie bin, werden mir diese custom fields nicht in der DropDown-Liste angezeigt, ich muss das erneut eingeben.

    Was kann man da machen? Da gibts doch bestimmt was für die Installation oder functions.php, aber ich finde nichts.

    Danke schon mal.

    Gruß

    Kai

Ansicht von 14 Antworten - 1 bis 14 (von insgesamt 14)
  • So wie du es beschreibst, verwendest du nur das Eingabemenü für Eigene Felder (Custom Fields), dass sich über die Einstellungen im Drei-Punkte-Menü einblenden lässt:

    Screenshot Individuelle Felder

    Dieses Menü hat tatsächlich den Nachteil, dass du eine willkürliche Kombination von Name und Wert (Key:Value) eintragen kannst. Das stellt eine Fehlerquelle dar, etwa wenn BenutzerInnen einmal farbe, einmal Farbe sowie verschiedene Tippfehler wie z.B. Frabe eingeben – du hast damit zig verschiedene Felder, was das Auslesen erschwert.

    Die Lösung besteht in der Einrichtung von Metaboxen. Damit sind vorgegebene Eingabefelder gemeint, die eine Beschreibung des Feldes beinhalten, einen Feldnamen fest vorgeben und für die Eingabe verschiedene Eigabeformate (Datumswähler, Farb-Auswahlfeld, Texteingabefeld, numerisches Feld, …) festlegen.
    Das kann dann z.B. so aussehen:

    Screenshot Einstellungen

    Metaboxen kannst du mit einem eigenen Plugin hinzufügen, was aber (selbst mit einem Toolkit wie CMB2) etwas aufwendiger zu programmieren ist. Viele Nutzer verwendet statt dessen das Plugin Advanced Custom Fields, mit dem ich die im Screenshot oben angezeigten Metaboxen in drei Minuten erstellt habe. Das Plugin kann anschließend auch im Backend ausgeblendet werden, damit AnwenderInnen (oder übereifrige Kunden) nicht versehentlich etwas verstellen. ACF ist kostenlos, eine kostenpflichtige Version bietet zusätzliche Optionen.

    Thread-Starter Kai J.

    (@kjoussen)

    Ja, ich dachte wirklich in kann „meine“ Felder in die bestehende Auswahlliste bei individuelle Felder einfügen, scheint aber nicht zu gehen.

    Aber das mit den Metaboxen ist super, das gefällt mir und ich bin auf meiner Dev-Umgebung schon fleißig dabei das über meine functions.php zu implementieren.
    Ist gar nicht mal so wild.

    Vielen Dank für den Tipp!

    Thread-Starter Kai J.

    (@kjoussen)

    So, also im Großen und Ganzen funktioniert es wie es soll.

    Ich habe eine eigene Metabox, die Werte werden in die DB geschrieben, meine Unterseite, die darauf reagieren soll, tut es auch, aber….wenn ich wieder in den Edit-Modus der Seite gehe, stehen die vorher eingetragenen Werte für „meine“ Custom-Fields nicht in „meiner“ Metabox, sondern – mit den richtigen Variablennamen – oben unter all den anderen Individuellen Feldern.
    Äh….wo ist mein Fehler?

    Ich poste hier mal den Teil aus meiner functions.php.

    /* Metaboxes for Post/Page Edit Screen */
    function myhamburg_add_custom_box() {
    	add_meta_box(
    		'mh_box_id',                 // Unique ID
    		'My Hamburg Page Options',   // Box title
    		'myhamburg_box_id_html',     // Content callback, must be of type callable
    		'page'                       // Post type
    	);
    }
    add_action( 'add_meta_boxes', 'myhamburg_add_custom_box' );
    
    function myhamburg_box_id_html($post) {
    	echo 'Here you can set some individual settings for this particular page.' . "<br>";
    	echo 'These settings only affect blog-style pages. They do not affect static pages';
    
    	$mh_date_sort_order = get_post_meta($post->ID, 'mh_date_sort_order', true);
    	$mh_show_static_content = get_post_meta($post->ID, 'mh_show_static_content', true);
    	$mh_show_sec_nav = get_post_meta($post->ID, 'mh_show_sec_nav', true);
    
    	?>
    	<table class="form-table">
    		<tr>
    			<th><label for="mh_date_sort_order">Date Sort Order</label></th>
    			<td><input type="text" id="mh_date_sort_order" name="mh_date_sort_order" value="<?php esc_attr( $mh_date_sort_order ) ?>" class="regular-text"></td>
    			<td>1 = ascending Order, anything else or emtpy = standard descending order</td>
    		</tr>
    		<tr>
    			<th><label for="mh_show_static_content">Show static content of page</label></th>
    			<td><input type="text" id="mh_show_static_content" name="mh_show_static_content" value="<?php esc_attr( $mh_show_static_content ) ?>" class="regular-text"></td>
    			<td>1 = show static content, anything else or emtpy = do not show static content</td>
    		</tr>
    		<tr>
    			<th><label for="mh_show_sec_nav">Show second pagination above posts</label></th>
    			<td><input type="text" id="mh_show_sec_nav" name="mh_show_sec_nav" value="<?php esc_attr( $mh_show_sec_nav ) ?>" class="regular-text"></td>
    			<td>1 = show additional pagination above posts, anything else or emtpy = do not show second pagination</td>
    		</tr>
    	</table>'
    	<?php
    }
    
    add_action( 'save_post', 'mh_save_meta', 10, 2 );
    function mh_save_meta( $post_id, $post ) {
    	// check current use permissions
    	$post_type = get_post_type_object( $post->post_type );
     	if ( ! current_user_can( $post_type->cap->edit_post, $post_id ) ) {
    		return $post_id;
    	}
     	// Do not save the data if autosave
    	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
    		return $post_id;
    	}
    	if( isset( $_POST[ 'mh_date_sort_order' ] ) ) {
    		update_post_meta( $post_id, 'mh_date_sort_order', sanitize_text_field( $_POST[ 'mh_date_sort_order' ] ) );
    	} else {
    		delete_post_meta( $post_id, 'mh_date_sort_order' );
    	}
    	if( isset( $_POST[ 'mh_show_static_content' ] ) ) {
    		update_post_meta( $post_id, 'mh_show_static_content', sanitize_text_field( $_POST[ 'mh_show_static_content' ] ) );
    	} else {
    		delete_post_meta( $post_id, 'mh_show_static_content' );
    	}
    	if( isset( $_POST[ 'mh_show_sec_nav' ] ) ) {
    		update_post_meta( $post_id, 'mh_show_sec_nav', sanitize_text_field( $_POST[ 'mh_show_sec_nav' ] ) );
    	} else {
    		delete_post_meta( $post_id, 'mh_show_sec_nav' );
    	}
    	return $post_id;
    }
    

    wenn ich wieder in den Edit-Modus der Seite gehe, stehen die vorher eingetragenen Werte für „meine“ Custom-Fields nicht in „meiner“ Metabox, sondern – mit den richtigen Variablennamen – oben unter all den anderen Individuellen Feldern.

    In der Metabox änderst du Werte für Custom Fields. Wenn du dir Custom Fields anzeigen lässt, ist es richtig, dass die Werte dort ausgegeben werden.

    Deinen Code habe ich rasch ausprobiert – es scheint alles korrekt zu funktionieren, auch wenn ich die Eingabe vermutlich eher mit einem Kontrollkästchen lösen und validieren würde.
    Bei </table>' <?php ist dir außerdem ein Hochkomma reingerutscht, das da nicht hingehört.

    Bei der Prüfung der Benutzerrechte hätte ich vermutlich das etwas einfachere

    if ( ! current_user_can( 'edit_posts' ) ) {
      return $post_id;
    }

    verwendet (vgl. https://developer.wordpress.org/reference/functions/current_user_can/).

    Thread-Starter Kai J.

    (@kjoussen)

    Moin,

    vielen Dank fürs Review und die schnelle Antwort.

    Aber dass ich in meiner Meta-Box etwas eintrage und es dann unter all den normalen individuellen Feldern erscheint „kann ich nicht akzeptieren“ 😉
    Für was baue ich denn dann in der Meta-Box im HTML-Teil extra value= ein?

    Ich habe ein Plug-In installiert, welches auch eine Meta-Box mitbringt und da passiert das nicht. Ich versuche gerade dessen Code zu verstehen…..vergeblich bisher.

    Also muss ich irgendwo oder irgendwie eine andere Technik verwenden, oder?
    Soll ich dann vielleicht gar nicht „Custom Fields“ verwenden sondern….ja was denn dann?

    Ich bin nach diesem Tutorial vorgegangen, habe jetzt aber auch das hier gefunden und sehe schon ein paar Unterschiede, die ich allerdings noch nicht ganz verstehe.

    Sicherheitshalber gebe ich zu, dass es sich hier nur um meine private Web-Seite handelt, weil viele meiner Freunde und Verwandten über den Globus verstreut sind und dort können sie immer neue Infos über mich etc. erfahren (ohne Facebook oder ähnliches Ungemach zu verwenden).
    Daneben bringe ich mir mit dieser Seite einfach php bei.
    Also dringend ist das Problem damit gar nicht. Aber es nagt an mir…..

    Thread-Starter Kai J.

    (@kjoussen)

    Da scheint es noch mehr Unterschiede zu geben….

    Ich habe 3 Felder.
    Angenommen ich trage im ersten Feld eine 1 ein und lasse die anderen leer.
    Dann stehen in der DB alle drei Keys in meta_key, aber nur beim ersten die 1 in meta_value.
    So weit so gut.

    Gehe ich wieder auf die Edit-Seite sehe ich oben bei individuelle Felder brav meine 1 zu dem einen Schlüssel.
    Trage ich jetzt im zweiten Key auch eine 1 ein, guess what, für diesen Key wird die 1 in die DB geschrieben, für den vorher im ersten Key wird die 1 gekillt.
    Ist ja auch logisch, weil in meinem Formular (Meta-Box) die Input-Box nicht gefüllt wurde beim lesen aus der DB. Ergo schreibe ich auch „nix“ zurück.

    Also irgendwo ist da ein grundlegender Wurm und ich finde ihn nicht.

    ist es richtig, dass du das Thema trotzdem als gelöst markiert hast?

    Thread-Starter Kai J.

    (@kjoussen)

    Ups…..stimmt, da war ja was.

    Also immer noch ungelöst.

    Thread-Starter Kai J.

    (@kjoussen)

    Also der Fehler scheint im Aufbau der Metabox zur Anzeige zu sein.

    Ich habe zu Testzwecken zwischen den Zeilen in denen ich die Werte aus der DB lese und der <table> einfach mal ein „echo variable“ eingefügt. Die Werte sind da, aber werden nicht in die Input-Boxen als Value eingetragen.
    Ergo, wenn ich speichere, wird da nix geschrieben.

    Und jetzt verstehe ich meine HTML und (zugegebenermaßen noch eher dünnen) php Kenntnisse nicht mehr.

    Aber dass ich in meiner Meta-Box etwas eintrage und es dann unter all den normalen individuellen Feldern erscheint „kann ich nicht akzeptieren“

    Wenn du dein Custom Field mit vorangestelltem Unterstrich (z.B. _mh_date_sort_order) anlegst, wird es auch nicht unter Custom Fields aufgeführt, wird aber weiter in der Metabox genutzt.

    Trage ich jetzt im zweiten Key auch eine 1 ein, guess what, für diesen Key wird die 1 in die DB geschrieben, für den vorher im ersten Key wird die 1 gekillt. Ist ja auch logisch, weil …

    Sorry, dafür ist es mir anscheinend noch zu früh. 😀

    Thread-Starter Kai J.

    (@kjoussen)

    Guten Morgen,

    danke, das mit dem _ hat funktioniert. Ich habe ja inzwischen einiges gelesen, aber das ist mir nirgends aufgefallen (was nicht heißen soll, dass es nirgends stand).

    Also gut, das funktioniert soweit, aber in meiner Metabox werden die Werte immer noch nicht angezeigt, obwohl sie ja sauber aus der DB gelesen werden.

    Also ich habe 3 Felder: A B und C
    Ich trage in meiner Box in A eine 1 ein (oder was auch immer, völlig egal)
    Der Wert wird sauber in der DB gespeichert und Seiten, die dieses Feld lesen reagieren sauber darauf.

    Etwas später gehe ich wieder in den Edit-Modus und trage bei B eine 1 ein.
    Da die bisherigen Werte aus der DB ja nicht in meiner Metabox eingetragen werden – trotz VALUE = …., steht in A also nichts, ergo wird für B der Wert in die DB geschrieben, für A aber gelöscht.
    Logisch.

    Deswegen ist ja Grundübel ja die Frage, warum die Werte – obwohl eingelesen und verfügbar – nicht in den Textboxen erscheinen.

    Die Einträge in deiner Metabox werden richtig gespeichert, bei erneutem Aufruf der Webseite im Editor auch wieder eingelesen, dann aber nicht richtig an das Eingabefeld übergeben. Im <input>-Tag musst du statt

    value="<?php esc_attr( $mh_date_sort_order ) ?>"

    bitte folgendes verwenden:
    value="<?php echo esc_attr( $mh_date_sort_order ) ?>"

    Dein Code hat außerdem noch eine Sicherheitslücke: Du solltest beim Speichern Nonces verwenden, also

    add_action( 'save_post', 'mh_save_meta', 10, 2 );
    function mh_save_meta( $post_id, $post ) {
    	// check current use permissions
    	$post_type = get_post_type_object( $post->post_type );
     	if ( ! current_user_can( $post_type->cap->edit_post, $post_id ) ) {
    		return $post_id;
    	}
     	// Do not save the data if autosave
    	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
    		return $post_id;
    	}

    ersetzen mit

    add_action( 'save_post', 'mh_save_meta', 10, 2 );
    function mh_save_meta( $post_id, $post ) {
            // Checking Nonce
           if ( !isset( $_POST['my_hamburg_nonce'] ) || !wp_verify_nonce( $_POST['my_hamburg_nonce'], basename( __FILE__ ) ) )
        return $post_id;
    
    	// check current user permissions
    	$post_type = get_post_type_object( $post->post_type );
     	if ( ! current_user_can( $post_type->cap->edit_post, $post_id ) ) {
    		return $post_id;
    	}
     	// Do not save the data if autosave
    	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
    		return $post_id;
    	}

    Damit das Nonce gesetzt wird, musst du im Formular ebenfalls noch Code ergänzen:

    function myhamburg_box_id_html($post) {
    
    	wp_nonce_field( basename( __FILE__ ), 'my_hamburg_nonce' );
    
            echo 'Here you can set some individual …'; //Code abgekürzt!
    

    Hatte ich erwähnt, dass die Programmierung einer Metabox etwas aufwendiger zu programmieren ist? 😉

    Thread-Starter Kai J.

    (@kjoussen)

    In Österreich sagt man: „I werd narrisch“.

    1000 Dank, das geht jetzt wie gewünscht. Warum aber dann alle (4) Tutorials, die ich dazu gelesen habe demzufolge auch falsch sind, vermag ich nicht zu sagen….

    Das mit Nonces hatte ich in der Zwischenzeit bereits eingebaut, aber danke für den Hinweis.

    Und ja, das hattest Du erwähnt, Asche auf mein Haupt.
    Aber im Großen und Ganzen lags ja nur an zwei Kleinigkeiten. Der _ und das fehlende echo.

    „aber sowas weiß man doch …“ 😛

    Schön, dass ich helfen konnte.

Ansicht von 14 Antworten - 1 bis 14 (von insgesamt 14)
  • Das Thema „Wie „individuelle Felder“ global verfügbar machen“ ist für neue Antworten geschlossen.