{"id":1385,"date":"2018-07-12T18:13:10","date_gmt":"2018-07-12T16:13:10","guid":{"rendered":"http:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=1385"},"modified":"2018-11-09T06:23:47","modified_gmt":"2018-11-09T05:23:47","slug":"sag-niemals-nie-widget-fuer-die-x-neuesten-beitraege-eigener-post-types","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2018\/07\/12\/sag-niemals-nie-widget-fuer-die-x-neuesten-beitraege-eigener-post-types\/","title":{"rendered":"Sag niemals nie: Widget f\u00fcr die X neuesten Beitr\u00e4ge eigener Post Types"},"content":{"rendered":"<p>Ich hab ja gesagt, mir ist das zu kompliziert, aber jetzt hab ich mir doch ein Widget geschrieben, das die X neuesten Beitr\u00e4ge eines w\u00e4hlbaren Post Types anzeigt. Man kann dem Widget einen Titel geben, man kann eingeben wieviele Beitr\u00e4ge angezeigt werden sollen, man kann auch noch anw\u00e4hlen ob das Datum mit angezeigt werden soll oder nicht. Aussehen tut das Ganze so:<\/p>\n<div id=\"attachment_1386\" style=\"width: 299px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1386\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1386\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/post_type_widget.jpg\" alt=\"post_type_widget\" width=\"289\" height=\"361\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/post_type_widget.jpg 289w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/post_type_widget-240x300.jpg 240w\" sizes=\"(max-width: 289px) 100vw, 289px\" \/><p id=\"caption-attachment-1386\" class=\"wp-caption-text\">post_type_widget<\/p><\/div>\n<p>Und die Ausgabe in der Sidebar sieht zum Beispiel so aus:<\/p>\n<div id=\"attachment_1387\" style=\"width: 213px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1387\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1387\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/widget_posts.jpg\" alt=\"widget_posts\" width=\"203\" height=\"214\" \/><p id=\"caption-attachment-1387\" class=\"wp-caption-text\">widget_posts<\/p><\/div>\n<p>Hier hab ich als Post Type &#8222;post&#8220; angegeben (das sind meine Rezepte), das Limit auf 5 gesetzt und Datum ausgeben angekreuzt.<\/p>\n<p>Das Widget wird ganz normal im Plugins-Verzeichnis angelegt, der Header mit der Klassendeklaration sieht so aus:<\/p>\n<pre>\/*\r\nPlugin Name: Post Type Widget\r\nPlugin URI: http:\/\/evileu.de\/wordpress\r\nDescription: Zeigt die neuesten X Beitr\u00e4ge des gew\u00e4hlten Post Types an\r\nAuthor: Evi Leu\r\nVersion: 1.0\r\nAuthor URI: http:\/\/evileu.de\r\n*\/\r\n\r\n\r\nclass PostTypeWidget extends WP_Widget\r\n{\r\n\u00a0 function PostTypeWidget()\r\n\u00a0 {\r\n\u00a0\u00a0\u00a0 $widget_ops = array('classname' =&gt; 'PostTypeWidget', 'description' =&gt; 'Zeigt die neuesten X Beitr\u00e4ge des gew\u00e4hlten Post Types an' );\r\n\u00a0\u00a0\u00a0 $this-&gt;WP_Widget('PostTypeWidget', 'Post Type', $widget_ops);\r\n\u00a0 }<\/pre>\n<p>Interessant wird es in der Formulardefinition, da habe ich mir ein Dropdownfeld mit meinen vorhandenen Post Types gebastelt, ich picke das mal heraus und markiere die anzupassenden Stellen rot:<\/p>\n<pre>&lt;p&gt;\r\n\u00a0\u00a0\u00a0 &lt;label for=\"&lt;?php echo $this-&gt;get_field_id( 'posttype' ); ?&gt;\"&gt;&lt;?php _e( 'Select Post Type', 'textdomain' ); ?&gt;:&lt;\/label&gt;\r\n\u00a0\u00a0\u00a0 &lt;p&gt;Post Type ausw\u00e4hlen\r\n\u00a0\u00a0 &lt;select id=\"&lt;?php echo $this-&gt;get_field_id('posttype'); ?&gt;\" name=\"&lt;?php echo $this-&gt;get_field_name('posttype'); ?&gt;\" class=\"widefat\" style=\"width:100%;\"&gt;\r\n\u00a0\u00a0\u00a0 &lt;option &lt;?php selected( $instance['posttype'], '<span style=\"color: #ff0000;\">post<\/span>'); ?&gt; value=\"<span style=\"color: #ff0000;\">post<\/span>\"&gt;<span style=\"color: #ff0000;\">Post<\/span>&lt;\/option&gt;\r\n\u00a0\u00a0\u00a0 &lt;option &lt;?php selected( $instance['posttype'], '<span style=\"color: #ff0000;\">kochbuch<\/span>'); ?&gt; value=\"<span style=\"color: #ff0000;\">kochbuch<\/span>\"&gt;<span style=\"color: #ff0000;\">Kochbuch<\/span>&lt;\/option&gt;\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0&lt;option &lt;?php selected( $instance['posttype'], '<span style=\"color: #ff0000;\">projects<\/span>'); ?&gt; value=\"<span style=\"color: #ff0000;\">projects<\/span>\"&gt;<span style=\"color: #ff0000;\">Projects<\/span>&lt;\/option&gt; \r\n\u00a0\u00a0\u00a0 &lt;\/select&gt;\r\n\u00a0\u00a0 &lt;\/p&gt;<\/pre>\n<p>Man h\u00e4tte auch die vorhandenen Post Types aus der Datenbank fischen k\u00f6nnen, aber das war mit zu viel Heckmeck, da m\u00fcsste man ja noch die WordPress-eigenen Types und evtl. auch die von irgendwelchen Plugins angelegten herausfiltern, ich fand es so herum entschieden einfacher. Wer mehr Post Types hat, erg\u00e4nzt einfach den Select entsprechend.<\/p>\n<h2>Nachtrag: alle Post Types aus der wp_posts anzeigen<\/h2>\n<p>Jetzt hab ichs doch noch ausprobiert, wer sich alle vorhandenen Post Types aus der wp_posts im Dropdownfeld anzeigen lassen will, kann f\u00fcr den Select folgende Konstruktion verwenden:<\/p>\n<pre>\u00a0&lt;p&gt;Post Type ausw\u00e4hlen\r\n\u00a0\u00a0 &lt;select id=\"&lt;?php echo $this-&gt;get_field_id('posttype'); ?&gt;\" name=\"&lt;?php echo $this-&gt;get_field_name('posttype'); ?&gt;\" class=\"widefat\" style=\"width:100%;\"&gt;\r\n\u00a0\u00a0\u00a0 &lt;?php\r\n\u00a0\u00a0 \u00a0global $wpdb;\r\n\u00a0\u00a0 \u00a0$alleposts = $wpdb-&gt;get_results( \"SELECT DISTINCT post_type \r\n                                      from \".$wpdb-&gt;prefix.\"posts\");\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0foreach($alleposts as $einpost){\u00a0\u00a0 \u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0 echo \"&lt;option \".selected( $instance['posttype'], $einpost-&gt;post_type).\" value=\".$einpost-&gt;post_type.\"&gt;\".$einpost-&gt;post_type.\"&lt;\/option&gt;\";\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0?&gt;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 &lt;\/select&gt;\r\n\u00a0\u00a0 &lt;\/p&gt;<\/pre>\n<p>Da kriegt man halt auch jeden Schrott angezeigt, aber es funktioniert:<\/p>\n<div id=\"attachment_1392\" style=\"width: 327px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1392\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1392\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/alle_post_types.jpg\" alt=\"alle_post_types\" width=\"317\" height=\"416\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/alle_post_types.jpg 317w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/alle_post_types-229x300.jpg 229w\" sizes=\"(max-width: 317px) 100vw, 317px\" \/><p id=\"caption-attachment-1392\" class=\"wp-caption-text\">alle_post_types<\/p><\/div>\n<p>Bleibt jedem selber \u00fcberlassen, ob er diese Option verwenden will oder den statischen Select von oben. Mir ist die statische Dropdownliste lieber, weil sie den Benutzer nicht in Versuchung bringt hier eine sinnfreie Option wie z.B revisions anzuw\u00e4hlen. Nat\u00fcrlich k\u00f6nnte man den SQL entsprechend aufblasen und noch einige &#8222;WHERE post_type NOT LIKE &#8218;xyz'&#8220; dranflicken, aber das ist mir entschieden zu umst\u00e4ndlich.<\/p>\n<h2>Die Checkbox f\u00fcr das Datum<\/h2>\n<p>F\u00fcr die Checkbox zum Datum anzeigen habe ich folgende Konstruktion verwendet:<\/p>\n<pre>&lt;p&gt;\r\n\u00a0\u00a0\u00a0 &lt;input class=\"checkbox\" type=\"checkbox\" &lt;?php checked( $instance[ 'your_checkbox_var' ], 'on' ); ?&gt; id=\"&lt;?php echo $this-&gt;get_field_id( 'your_checkbox_var' ); ?&gt;\" name=\"&lt;?php echo $this-&gt;get_field_name( 'your_checkbox_var' ); ?&gt;\" \/&gt; \r\n\u00a0\u00a0\u00a0 &lt;label for=\"&lt;?php echo $this-&gt;get_field_id( 'your_checkbox_var' ); ?&gt;\"&gt;Datum anzeigen&lt;\/label&gt;\r\n&lt;\/p&gt;<\/pre>\n<p>Die ganze Funktion form($instance) sieht so aus:<\/p>\n<pre>function 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$instance = wp_parse_args( (array) $instance, array( 'posttype' =&gt; '' ) );\r\n\u00a0\u00a0\u00a0 $posttype = $instance['posttype'];\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0$instance = wp_parse_args( (array) $instance, array( 'anzahl' =&gt; '' ) );\r\n\u00a0\u00a0\u00a0 $anzahl = $instance['anzahl'];\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0$instance = wp_parse_args( (array) $instance, array( 'your_checkbox_var' =&gt; '' ) );\r\n\u00a0\u00a0\u00a0 $your_checkbox_var = $instance['your_checkbox_var'];\r\n\u00a0\u00a0 \u00a0\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 &lt;p&gt;\r\n\u00a0\u00a0\u00a0 &lt;label for=\"&lt;?php echo $this-&gt;get_field_id( 'posttype' ); ?&gt;\"&gt;&lt;?php _e( 'Select Post Type', 'textdomain' ); ?&gt;:&lt;\/label&gt;\r\n\u00a0\u00a0\u00a0 &lt;p&gt;Post Type ausw\u00e4hlen\r\n\u00a0\u00a0 &lt;select id=\"&lt;?php echo $this-&gt;get_field_id('posttype'); ?&gt;\" name=\"&lt;?php echo $this-&gt;get_field_name('posttype'); ?&gt;\" class=\"widefat\" style=\"width:100%;\"&gt;\r\n\u00a0\u00a0\u00a0 &lt;option &lt;?php selected( $instance['posttype'], 'post'); ?&gt; value=\"post\"&gt;Post&lt;\/option&gt;\r\n\u00a0\u00a0\u00a0 &lt;option &lt;?php selected( $instance['posttype'], 'kochbuch'); ?&gt; value=\"kochbuch\"&gt;Kochbuch&lt;\/option&gt;\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0&lt;option &lt;?php selected( $instance['posttype'], 'projects'); ?&gt; value=\"projects\"&gt;Projects&lt;\/option&gt; \r\n\u00a0\u00a0\u00a0 &lt;\/select&gt;\r\n\u00a0\u00a0 &lt;\/p&gt;\r\n\u00a0 &lt;p&gt;&lt;label for=\"&lt;?php echo $this-&gt;get_field_id('anzahl'); ?&gt;\"&gt;Anzahl: &lt;input id=\"&lt;?php echo $this-&gt;get_field_id('anzahl'); ?&gt;\" \r\nname=\"&lt;?php echo $this-&gt;get_field_name('anzahl'); ?&gt;\" type=\"number\" value=\"&lt;?php echo attribute_escape($anzahl); ?&gt;\" \/&gt;&lt;\/label&gt;&lt;\/p&gt;\r\n&lt;p&gt;\r\n\u00a0\u00a0\u00a0 &lt;input class=\"checkbox\" type=\"checkbox\" &lt;?php checked( $instance[ 'your_checkbox_var' ], 'on' ); ?&gt; id=\"&lt;?php echo $this-&gt;get_field_id( 'your_checkbox_var' ); ?&gt;\" name=\"&lt;?php echo $this-&gt;get_field_name( 'your_checkbox_var' ); ?&gt;\" \/&gt; \r\n\u00a0\u00a0\u00a0 &lt;label for=\"&lt;?php echo $this-&gt;get_field_id( 'your_checkbox_var' ); ?&gt;\"&gt;Datum anzeigen&lt;\/label&gt;\r\n&lt;\/p&gt;\r\n\u00a0 \r\n\u00a0 \r\n\u00a0 \r\n&lt;?php\r\n\u00a0 }\r\n<\/pre>\n<p>Dann noch die Funktion update() anpassen:<\/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['posttype'] = $new_instance['posttype'];\r\n\u00a0\u00a0 \u00a0$instance['anzahl'] = $new_instance['anzahl'];\r\n\u00a0\u00a0 \u00a0$instance[ 'your_checkbox_var' ] = $new_instance[ 'your_checkbox_var' ];\r\n\u00a0\u00a0\u00a0 return $instance;\r\n\u00a0 }<\/pre>\n<p>Und schliesslich in der Funktion widget() die Variablen abholen:<\/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$your_checkbox_var = $instance[ 'your_checkbox_var' ] ? 'true' : 'false';\r\n\u00a0\u00a0\u00a0 $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);\r\n\u00a0\u00a0 \u00a0$posttype\u00a0\u00a0\u00a0 = empty( $instance['posttype'] ) ? '' : esc_attr( $instance['posttype'] );\r\n\u00a0\u00a0 \u00a0$anzahl\u00a0\u00a0\u00a0 = empty( $instance['anzahl'] ) ? '' : esc_attr( $instance['anzahl'] );<\/pre>\n<p>Der eigentliche OpCode des Widgets ist nicht weiter kompliziert, die Hauptsache ist die SQL-Query, in die ich die Variablen f\u00fcr den Post Type und f\u00fcr die Anzahl einsetze:<\/p>\n<pre>global $wpdb;\r\n\u00a0\u00a0 \u00a0$alleposts = $wpdb-&gt;get_results( \"SELECT * from \".$wpdb-&gt;prefix.\"posts \r\nwhere post_type like '\".<span style=\"color: #ff0000;\">$posttype<\/span>.\"' \r\nand post_status like 'publish' \r\nORDER BY post_date DESC\r\n LIMIT \".<span style=\"color: #ff0000;\">$anzahl<\/span>.\"\");\r\n\u00a0\u00a0\u00a0 \r\n<\/pre>\n<p>Das ganze wird noch nach dem post_status=publish gefiltert und absteigend nach Datum sortiert und kann jetzt in einem foreach ausgegeben werden. Dabei baue ich noch die Abfrage ein, ob das Datum mit ausgegeben werden soll:<\/p>\n<pre>foreach($alleposts as $einpost){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$dt = new DateTime(<span style=\"color: #008000;\">$einpost-&gt;post_date<\/span>);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $einpost-&gt;post_title.\" \";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #ff0000;\">if ($your_checkbox_var == 'true'){ echo $dt-&gt;format('d.m.Y');}<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0}<\/pre>\n<p>Hier k\u00f6nnte man wie schon \u00f6fter gehabt mit dem get_permalink() \u00fcber die ID gleich noch den Link zum entsprechenden Beitrag mit einbauen, das spare ich mir jetzt. Wem das jetzt zu schnell ging, den ganzen Code des Widgets gibt es hier gezippt: <a href=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/07\/post-type-widget.zip\">post-type-widget<\/a><\/p>\n<p>Viel Spa\u00df beim Nachbauen!<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich hab ja gesagt, mir ist das zu kompliziert, aber jetzt hab ich mir doch ein Widget geschrieben, das die X neuesten Beitr\u00e4ge eines w\u00e4hlbaren Post Types anzeigt. Man kann dem Widget einen Titel geben, man kann eingeben wieviele Beitr\u00e4ge angezeigt werden sollen, man kann auch noch anw\u00e4hlen ob das Datum mit angezeigt werden soll [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[48,4,45,2,59],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1385"}],"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=1385"}],"version-history":[{"count":4,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1385\/revisions"}],"predecessor-version":[{"id":1394,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1385\/revisions\/1394"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=1385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=1385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=1385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}