{"id":1057,"date":"2018-04-02T17:02:37","date_gmt":"2018-04-02T15:02:37","guid":{"rendered":"http:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=1057"},"modified":"2018-04-02T17:44:09","modified_gmt":"2018-04-02T15:44:09","slug":"widget-basteln-macht-spass-ein-widget-mit-benutzereingaben","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2018\/04\/02\/widget-basteln-macht-spass-ein-widget-mit-benutzereingaben\/","title":{"rendered":"Widget-Basteln macht Spa\u00df: ein Widget mit Benutzereingaben"},"content":{"rendered":"<p>Das, so gebe ich ehrlich zu, ist zusammengeklaut und abgekupfert und herausgegooglet. Da aber das Widgetbasteln in WordPress erstens Spa\u00df macht und zweitens vielf\u00e4ltige Einsatzm\u00f6glichkeiten bietet, beschreibe ich hier doch mal recht ausf\u00fchrlich meinen Weg zum eigenen Widget mit Benutzereingaben. Das Meiste hab ich aus <a href=\"https:\/\/www.makeuseof.com\/tag\/how-to-create-wordpress-widgets\/\">dieser Anleitung hier bei makuseof.com<\/a> gelernt, da wird einem das funktionale Gerippe eines WordPress-Widgets vorgelegt. Ebenfalls sehr aufschlussreich ist <a href=\"https:\/\/premium.wpmudev.org\/blog\/create-custom-wordpress-widget\/\">diese Anleitung hier bei wpmudev<\/a>.<\/p>\n<h2>Die Vorgabe: ein Featured Category Widget<\/h2>\n<p>Ich hab mir eine relativ einfach Aufgabe gestellt. Mein Widget soll ausgeben, wieviele Rezepte bisher ver\u00f6ffentlich wurden, und dann soll man noch eine Featured Category anw\u00e4hlen k\u00f6nnen, f\u00fcr die dann ebenfalls die Anzahl der Rezepte ausgegeben wird, also so in der Art:<\/p>\n<h3>Rezepte insgesamt 317<\/h3>\n<h3>56 davon Vegetarisch<\/h3>\n<p>Dann h\u00e4tte ich noch gern einen frei w\u00e4hlbaren Titel f\u00fcr das Widget. Das h\u00f6rt sich simpel an, war aber in der Realisieung nicht ohne, nicht zuletzt weil der Codex zu den Widget-Funktionalit\u00e4ten sehr l\u00fcckenhaft und umst\u00e4ndlich ist. Aber wir fangen mal ganz vorne an, und sehen wie weit wir kommen.<\/p>\n<h2>Anlegen der Widget-Datei<\/h2>\n<p>Man erzeugt im Plugins-Verzeichnis seiner WordPress-Installation ein neues php-File mit dem Namen des Widgets, z. B. mein-tolles-widget.php. Die kriegt jetzt erstmal den klassischen Plugin-Header:<\/p>\n<pre>\/*\r\nPlugin Name: Top Category Widget\r\nPlugin URI: http:\/\/evileu.de\/wordpress\r\nDescription: Gibt die Gesamtzahl der ver\u00f6ffentlichten Rezepte und die Anzahl der Beitr\u00e4ge einer frei w\u00e4hlbaren Kategorie an\r\nAuthor: Evi Leu\r\nVersion: 1.0\r\nAuthor URI: http:\/\/evileu.de\r\n*\/<\/pre>\n<p>Dann passiert Folgendes:<\/p>\n<pre>class <span style=\"color: #ff0000;\"><strong>FeaturedCategoryWidget<\/strong><\/span> extends WP_Widget\r\n{\r\n\u00a0 function <span style=\"color: #ff0000;\"><strong>FeaturedCategoryWidget<\/strong><\/span>()\r\n\u00a0 {\r\n\u00a0\u00a0\u00a0 $widget_ops = array('classname' =&gt; '<span style=\"color: #ff0000;\"><strong>FeaturedCategoryWidget<\/strong><\/span>', 'description' =&gt; '<span style=\"color: #ff0000;\"><strong>Zeigt die Anzahl der Rezepte einer frei w\u00e4hlbaren Kategorie an<\/strong><\/span>' );\r\n\u00a0\u00a0\u00a0 $this-&gt;WP_Widget('<span style=\"color: #ff0000;\"><strong>FeaturedCategoryWidget<\/strong><\/span>', '<span style=\"color: #ff0000;\"><strong>Featured Kategorie<\/strong><\/span>', $widget_ops);\r\n\u00a0 }<\/pre>\n<p>Eine neue Instanz der Klasse WP_Widget wird angelegt und mit unseren eigenen Benennungen versehen, ich hab die mal fett und rot markiert. Dann kommt noch etliches andere, was sp\u00e4ter erkl\u00e4rt wird, und am Ende der Datei wird noch per add_action das Widget aktiviert:<\/p>\n<pre>add_action( 'widgets_init', create_function('', 'return register_widget(\"<span style=\"color: #ff0000;\">FeaturedCategoryWidget<\/span>\");') );?&gt;<\/pre>\n<p>Das reicht aus, damit das Testwidget in den zur Verf\u00fcgung stehenden Plugins angezeigt wird und aktiviert werden kann. Macht aber noch keinen Sinn, es tut ja noch nichts.<\/p>\n<h2>Das Formular f\u00fcr die Benutzereingaben<\/h2>\n<p>Daf\u00fcr brauchts eine Funktion namens form($instance), die sieht so aus, meine Erg\u00e4nzungen in rot:<\/p>\n<pre>\u00a0function form($instance)\r\n\u00a0 {\r\n\u00a0\u00a0\u00a0 $instance = wp_parse_args( (array) $instance, array( 'title' =&gt; '' ) );\r\n\u00a0\u00a0\u00a0 $title = $instance['title'];\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0<span style=\"color: #ff0000;\">$instance = wp_parse_args( (array) $instance, array( 'select' =&gt; '' ) );<\/span>\r\n<span style=\"color: #ff0000;\">\u00a0\u00a0\u00a0 $select = $instance['select'];<\/span>\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\r\n?&gt;\r\n\u00a0 &lt;p&gt;&lt;label for=\"&lt;?php echo $this-&gt;get_field_id('title'); ?&gt;\"&gt;Titel: &lt;input class=\"widefat\" id=\"&lt;?php echo $this-&gt;get_field_id('title'); ?&gt;\" name=\"&lt;?php echo $this-&gt;get_field_name('title'); ?&gt;\" type=\"text\" value=\"&lt;?php echo attribute_escape($title); ?&gt;\" \/&gt;&lt;\/label&gt;&lt;\/p&gt;\r\n\u00a0 \r\n\u00a0\u00a0 <span style=\"color: #ff0000;\">&lt;p&gt;<\/span>\r\n<span style=\"color: #ff0000;\">\u00a0\u00a0\u00a0 &lt;label for=\"&lt;?php echo $this-&gt;get_field_id( 'select' ); ?&gt;\"&gt;&lt;?php _e( 'Select category', 'textdomain' ); ?&gt;:&lt;\/label&gt;<\/span>\r\n<span style=\"color: #ff0000;\">\u00a0\u00a0\u00a0 &lt;?php wp_dropdown_categories( array( 'show_option_none' =&gt;' ','name' =&gt; $this-&gt;get_field_name( 'select' ), 'selected' =&gt; $select ) ); ?&gt;<\/span>\r\n<span style=\"color: #ff0000;\">\u00a0 &lt;\/p&gt;<\/span><\/pre>\n<p>Damit werden zwei Felder f\u00fcr die Benutzereingaben angelegt. Das erste f\u00fcr den Titel hab ich aus dem Beispiel von <a href=\"https:\/\/www.makeuseof.com\/tag\/how-to-create-wordpress-widgets\/\">makuseof.com<\/a> \u00fcbernommen. Das zweite Feld f\u00fcr das Auswahlfeld hab ich mir zusammengegooglet, das stellt eine Dropdown-Liste aller Kategorien zur Verf\u00fcgung und belegt die Variable $select mit der ID (numerisch) der gew\u00e4hlten Kategorie.<\/p>\n<p>Jetzt kommt noch eine Funktion, die uns die vorher gew\u00e4hlten Werte aus dem Formular zur Verf\u00fcgung stellt, auch die hab ich einfach \u00fcbernommen:<\/p>\n<pre>function update($new_instance, $old_instance)\r\n\u00a0 {\r\n\u00a0\u00a0\u00a0 $instance = $old_instance;\r\n\u00a0\u00a0\u00a0 $instance['title'] = $new_instance['title'];\r\n\u00a0\u00a0 \u00a0$instance['select'] = $new_instance['select'];\r\n\u00a0\u00a0\u00a0 return $instance;\r\n\u00a0 }<\/pre>\n<p>Und jetzt kommt endlich die tats\u00e4chliche Funktionalit\u00e4t des Widgets. Da werden zuerst noch die beiden Variablen $title und $select ges\u00e4ubert, aber dann kanns losgehen<\/p>\n<pre>function widget($args, $instance)\r\n\u00a0 {\r\n\u00a0\u00a0\u00a0 extract($args, EXTR_SKIP);\r\n\u00a0\r\n\u00a0\u00a0\u00a0 echo $before_widget;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);\r\n\u00a0\u00a0 \u00a0$select\u00a0\u00a0\u00a0 = empty( $instance['select'] ) ? '' : esc_attr( $instance['select'] );\r\n\u00a0\u00a0 \u00a0\r\n\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 <span style=\"color: #339966;\">\/\/ WIDGET CODE KOMMT HIER<\/span>\r\n\u00a0\u00a0\u00a0 \r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0echo $after_widget;\r\n\u00a0 }<\/pre>\n<p>Der tats\u00e4chliche OpCode des Widgets ist sehr straightforward:<\/p>\n<pre>echo \"&lt;h3&gt;\".$title.\"&lt;\/h3&gt;\";\r\n\u00a0\u00a0 \u00a0echo \"Rezepte insgesamt: \".wp_count_posts()-&gt;publish.\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0global $wpdb;\r\n\u00a0\u00a0 \u00a0$alleposts = $wpdb-&gt;get_results( \"SELECT * from \".$wpdb-&gt;prefix.\"term_taxonomy where term_id = \".<span style=\"color: #ff0000;\">$select<\/span>.\"\");\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0foreach($alleposts as $einpost){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $einpost-&gt;count;\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0echo \" davon \".get_the_category_by_ID($select);<\/pre>\n<p>Ich geb erstmal den vom Benutzer eingegebenen Titel als h3 aus, danach die Gesamtzahl der ver\u00f6ffentlichten Posts=Rezepte. Dann kommt eine kleine Datenbankabfrage, ich hol mir aus der wp_term_taxonomy die Anzahl der zur aktuellen Kategorie (ID liegt auf der Variablen $select) vorhandenen Beitr\u00e4ge, die steht da n\u00e4mlich praktischerweise drin, da muss man nicht lang rummachen. Das wars! Unser Widget hat jetzt ein Eingabefeld f\u00fcr den Titel und eine Dropdownliste zur Auswahl der Kategorie:<\/p>\n<div id=\"attachment_1059\" style=\"width: 331px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1059\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1059\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_mit_dropdown.jpg\" alt=\"widget_mit_dropdown\" width=\"321\" height=\"578\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_mit_dropdown.jpg 321w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_mit_dropdown-167x300.jpg 167w\" sizes=\"(max-width: 321px) 100vw, 321px\" \/><p id=\"caption-attachment-1059\" class=\"wp-caption-text\">widget_mit_dropdown<\/p><\/div>\n<p>Der Output ist unspektakul\u00e4r, aber es funktioniert wie geplant:<\/p>\n<div id=\"attachment_1060\" style=\"width: 1100px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1060\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1060\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_output.jpg\" alt=\"widget_output\" width=\"1090\" height=\"411\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_output.jpg 1090w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_output-300x113.jpg 300w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_output-768x290.jpg 768w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_output-1024x386.jpg 1024w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/widget_output-624x235.jpg 624w\" sizes=\"(max-width: 1090px) 100vw, 1090px\" \/><p id=\"caption-attachment-1060\" class=\"wp-caption-text\">widget_output<\/p><\/div>\n<h2>Kurzer Blick auf die Datenbank<\/h2>\n<p>Wer \u00fcbrigens wissen m\u00f6chte, wo die Benutzereingaben gespeichert werden, das ist ein bisschen frustelig. Die werden n\u00e4mlich serialized abgespeichert, in der wp_options. Sucht da nach einem Eintrag mit dem Namen widget_[name eures widgets]. Im Feld option_value steht dann sowas:<\/p>\n<p>a:2:{i:2;a:2:{s:5:&#8220;title&#8220;;s:12:&#8220;Alle Rezepte&#8220;;s:6:&#8220;select&#8220;;s:2:&#8220;29&#8243;;}s:12:&#8220;_multiwidget&#8220;;i:1;}<\/p>\n<h2>Der gesamte Code als ZIP<\/h2>\n<p>Weil die Schachtelung doch ein wenig kompliziert ist, kommt hier noch der gesamte Code des Widgets als ZIP-Archiv: <a href=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/04\/category-widget.zip\">category-widget<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das, so gebe ich ehrlich zu, ist zusammengeklaut und abgekupfert und herausgegooglet. Da aber das Widgetbasteln in WordPress erstens Spa\u00df macht und zweitens vielf\u00e4ltige Einsatzm\u00f6glichkeiten bietet, beschreibe ich hier doch mal recht ausf\u00fchrlich meinen Weg zum eigenen Widget mit Benutzereingaben. Das Meiste hab ich aus dieser Anleitung hier bei makuseof.com gelernt, da wird einem das [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,45,2],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1057"}],"collection":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/comments?post=1057"}],"version-history":[{"count":4,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1057\/revisions"}],"predecessor-version":[{"id":1064,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1057\/revisions\/1064"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=1057"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=1057"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=1057"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}