Im gemeinsamen Projekt WPEngineer arbeiten wir mittlerweile mit vier Autoren – da ist es recht nützlich, wenn man einen Feed für die Entwürfe hat. Schreibt jemand einen neuen Artikel und speichert diesen ab, dann hat er im Standard von WordPress den Status Entwurf (Draft). Aufgrund dieses Datenbank-Schlüssels kann man daher die Inhalte schnell holen und entsprechend verarbeiten.
Für uns war eine Mail-Möglichkeit nicht erwünschenswert und daher habe ich mir überlegt, dass wir uns über die Entwürfe wie Feed informieren. In dem Zusammenhang habe ich mir mal angeschaut, wie man einen eigenen Feed entwerfen kann. Mit Hilfe des Loop kann man dabei schon recht viel machen, siehe Beitrag „WordPress Feed beeinflussen“.
Zusätzlich bietet das Plugin ein Dashbaord-Widget, welches die letzten fünf Entwürfe aller Autoren zeigt. Das Standard-Widget von WordPress zeigt nur die eigenen Entwürfe.

Das folgenden kleine Plugin kann gern genutzt werden und ich stelle mal meinen Code dar, damit man sich eventuell einen eigenen Feed bauen will. Sei es im Rahmen einer Community oder auf Basis eines anderen Wertes aus der Datenbank.
Der Feed hat keinen Zugriffsschutz – damit ist das Lesen auch mit diversen Online-Tools einfach und unkompliziert. Alternativ könnte man natürlich den geloggten User aus WP abfragen. Diesen Weg überlasse ich aber jedem selbst.
Das Plugin erstellt einen Feed, der unter der URL http://examble.com/?feed=draft erreichbar ist. Der Name des Feed kann in Zeile 27 add_feed( 'draft', array(&$this, 'get_draft_feed') ); frei definiert werden.
<?php
/*
Plugin Name: Drafts Feed
Plugin URI: http://bueltge.de/wordpress-feed-fuer-entwuerfe/829/
Description: Add a new Feed for drafts: <code>/?feed=draft</code>
Version: 0.2
Author: Frank Bültge
Author URI: http://bueltge.de/
Licence: GPL
Last Change: 17.06.2009 10:50:19
*/
//avoid direct calls to this file, because now WP core and framework has been used
if ( !function_exists('add_action') ) {
header('Status: 403 Forbidden');
header('HTTP/1.1 403 Forbidden');
exit();
}
if ( function_exists('add_action') ) {
//WordPress definitions
if ( !defined('WP_CONTENT_URL') )
define('WP_CONTENT_URL', get_option('siteurl') . '/wp-content');
if ( !defined('WP_CONTENT_DIR') )
define('WP_CONTENT_DIR', ABSPATH . 'wp-content');
if ( !defined('WP_PLUGIN_URL') )
define('WP_PLUGIN_URL', WP_CONTENT_URL.'/plugins');
if ( !defined('WP_PLUGIN_DIR') )
define('WP_PLUGIN_DIR', WP_CONTENT_DIR.'/plugins');
if ( !defined('PLUGINDIR') )
define( 'PLUGINDIR', 'wp-content/plugins' ); // Relative to ABSPATH. For back compat.
if ( !defined('WP_LANG_DIR') )
define('WP_LANG_DIR', WP_CONTENT_DIR . '/languages');
// plugin definitions
define( 'FB_DF_BASENAME', plugin_basename(__FILE__) );
define( 'FB_DF_BASEFOLDER', plugin_basename( dirname( __FILE__ ) ) );
define( 'FB_DF_TEXTDOMAIN', 'draft_feed' );
}
if ( !class_exists('DraftFeed') ) {
class DraftFeed {
// constructor
function DraftFeed() {
add_action( 'init', array(&$this, 'add_draft_feed') );
if ( is_admin() ) {
add_action( 'wp_dashboard_setup', array(&$this, 'my_wp_dashboard_setup') );
add_action( 'admin_head', array(&$this, 'add_my_css') );
add_action( 'admin_init', array(&$this, 'textdomain') );
}
}
function textdomain() {
if ( function_exists('load_plugin_textdomain') ) {
if ( !defined('WP_PLUGIN_DIR') ) {
load_plugin_textdomain( FB_DF_TEXTDOMAIN, str_replace( ABSPATH, '', dirname(__FILE__) ) . '/languages' );
} else {
load_plugin_textdomain( FB_DF_TEXTDOMAIN, false, dirname( plugin_basename(__FILE__) ) . '/languages' );
}
}
}
function my_wp_dashboard_recent_drafts( $drafts = false, $view_content = false ) {
if ( $drafts )
return;
$drafts_query = new WP_Query( array(
'post_type' => 'post',
'post_status' => 'draft',
'posts_per_page' => 5,
'orderby' => 'modified',
'order' => 'DESC'
) );
$drafts =& $drafts_query->posts;
if ( $drafts && is_array( $drafts ) ) {
$list = array();
foreach ( $drafts as $draft ) {
$url = get_edit_post_link( $draft->ID );
$title = _draft_or_post_title( $draft->ID );
$user = get_userdata($draft->post_author);
$author = $user->display_name;
$item = '<a href="' . $url . '" title="' . sprintf( __( 'Edit “%s”', FB_DF_TEXTDOMAIN ), esc_attr( $title ) ) . '">' . $title . '</a> ' . __( 'by', FB_DF_TEXTDOMAIN ) . ' ' . stripslashes( apply_filters('comment_author', $author) ) . ' <abbr title="' . get_the_time(__('Y/m/d g:i:s A'), $draft) . '">' . get_the_time( get_option( 'date_format' ), $draft ) . '</abbr>';
$list[] = $item;
}
?>
<ul>
<li><?php echo join( "</li>\n<li>", $list ); ?></li>
</ul>
<p class="textright"><a href="edit.php?post_status=draft" class="button"><?php _e('View all', FB_DF_TEXTDOMAIN); ?></a></p>
<?php
} else {
_e( 'There are no drafts at the moment', FB_DF_TEXTDOMAIN );
}
}
function my_wp_dashboard_setup() {
wp_add_dashboard_widget( 'my_wp_dashboard_recent_drafts', __( 'Recents Drafts', FB_DF_TEXTDOMAIN ) . ' <small>' . __( 'of all authors', FB_DF_TEXTDOMAIN ) . '</small>', array(&$this, 'my_wp_dashboard_recent_drafts') );
}
function add_my_css() {
$echo = '';
$echo .= "\n";
$echo .= '<style type="text/css">'."\n";
$echo .= '<!--'."\n";
$echo .= '#my_wp_dashboard_recent_drafts abbr {' . "\n";
$echo .= 'font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif;' . "\n";;
$echo .= 'font-size: 11px;' . "\n";
$echo .= 'color: #999;' . "\n";
$echo .= 'margin-left: 3px;' . "\n";
$echo .= '}'."\n";
$echo .= '-->'."\n";
$echo .= '</style>'."\n";
echo $echo;
}
// add feed via hook
function add_draft_feed() {
// set name for the feed
// http://examble.com/?feed=draft
add_feed( 'draft', array(&$this, 'get_draft_feed') );
}
// get feed
function get_draft_feed() {
global $wpdb;
// draft or future
$sql = "
SELECT ID, post_title, post_date, post_author, post_author, guid, post_excerpt, post_content
FROM $wpdb->posts
WHERE post_status = 'draft'
ORDER BY post_date_gmt DESC
";
$items = $wpdb->get_results($sql);
if ( !headers_sent() )
header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
$more = 1;
?>
<?php echo '<?xml version="1.0" encoding="' . get_option('blog_charset') . '"?' . '>'; ?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
<?php do_action('rss2_ns'); ?>
>
<channel>
<title><?php bloginfo_rss( 'name' ); wp_title_rss(); ?></title>
<atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
<link><?php bloginfo_rss( 'url' ) ?></link>
<description><?php bloginfo_rss( 'description' ) ?></description>
<pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false ); ?></pubDate>
<generator>http://bueltge.de/</generator>
<language><?php echo get_option( 'rss_language' ); ?></language>
<sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
<sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
<?php do_action('rss2_head'); ?>
<?php
if ( empty($items) ) {
echo '<!-- No submissions found yet. //-->';
} else {
foreach ($items as $item) {
?>
<item>
<title><?php echo stripslashes( apply_filters( 'comment_author', $item->post_title ) ); ?></title>
<link><?php echo stripslashes( apply_filters( 'comment_author_url', get_permalink($item->ID) ) ); ?></link>
<pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', $item->post_date ); ?></pubDate>
<dc:creator><?php echo stripslashes( apply_filters('comment_author', $item->post_author) ); ?></dc:creator>
<guid isPermaLink="false"><?php echo stripslashes( apply_filters('comment_author_url', $item->guid) ); ?></guid>
<?php if ( $item->post_excerpt != '' ) { ?>
<description><![CDATA[<?php echo trim(stripslashes( apply_filters('comment_text', $item->post_excerpt) ) ); ?>]]></description>
<?php } else { ?>
<description><![CDATA[<?php echo strip_tags( trim( stripslashes( apply_filters('comment_text', $item->post_content) ) ) ); ?>]]></description>
<?php } ?>
<content:encoded><![CDATA[<?php echo trim( stripslashes( apply_filters( 'comment_text', $item->post_content ) ) ); ?>]]></content:encoded>
<?php do_action('rss2_item'); ?>
</item>
<?php
}
}
?>
</channel>
</rss>
<?php
}
} // end class
$df_wp_injector = new DraftFeed();
} // end if class exists
// WP init and add ne function for feed
if ( isset($df_wp_injector) && function_exists( 'add_action' ) ) {
add_action( 'DraftFeed', array(&$df_wp_injector, 'init') );
}
?>
Download:
Ist die Arbeit nicht 1 Euro wert?
Jede Spende wird dankbar angenommen und ermöglicht das weitere Arbeiten an freier Software.
Möchtest du mehr oder anders spenden, so besuche meine Wunschliste.
Download als zip-Datei:
draft-feed-03.zip – 11 kByte
draft-feed.zip – 11 kByte
Historie
- 0.1 - Idee und Lösung
- 0.2 - Dashboard Widget hinzugefügt; Mehrsprachigkeit ergänzt (17/06/2009)
- 1.0.0 - Update for new codex (12/20/2012)
- Gewartete Version im zugehörigen Github Repo
Vielleicht wäre es leichter, wenn du auch ein Admin Menü hinzufügen würdest, aber natürlich ist es unwichtig für eine Einstellungen
Schönes Plugin, habe auch ein Artikel dazu geschrieben..
Das plug in ist in jedem fall brauchbar!ich finde den admin bereich allerdings jetzt nicht wichtig,ein bißchen coden Sollte man schon können
Ganz großes Tennis, Frank. Da ich bei einem kleinen Blog immer die Texte der anderen Autoren Korrektur lese, ist das natürlich eine super Bereicherung für den Workflow. Danke!
Hi,
cooles Plugin, gibt es auch eine Möglichkeit die geplanten Artikel in einem Feed anzuzeigen?
Wenn man mit mehreren Leuten arbeitet und die Artikel planen möchte ist die WordPressansicht leider nicht sehr hilfreich um zu sehen wann welcher Artikel live gestellt wird.
@Schnappinator: ja, dass sollte ebenso gehen. Ändere einfach in
'post_status' => 'future', damit werden nur die Post abgerufen, die in der Zukunft erscheinen. Zusätzlich kannst du noch beiadd_feed( 'draft', array(&$this, 'get_draft_feed') );
draftinfutureo.ä. ändern, dass ist der Name für den Feed, so dass dann die Adresse zum Feed wie folgt wäre:http://examble.com/?feed=future.Das sollte genügen, habe es aber nicht getestet.
Hi Frank,
danke für die Info. Ich werde es mal ausprobieren und dann hier eine Info geben ob es klappt.
Ich habe einige Zeit lang versucht, das Plugin auf published Posts umzuschreiben (um Feedburner zu umgehen). Leider hab ich viel zu kompliziert gedacht und wollte den Code durchkämmen.
Die Lösung (kein Scherz!) brachte folgendes:
Suchen+Ersetzen: "draft" durch "publish" - bei mir waren es 37 Ersetzungen
jetzt im FeedSmith Plugin diese Zeile:
global $wp, $feedburner_settings, $feed, $withcomments;
if (is_feed() && $feed != 'comments-rss2' && !is_single() && $wp->query_vars['category_name'] == '' && ($withcomments != 1) && trim($feedburner_settings['feedburner_url']) != '') {
ändern zu
global $wp, $feedburner_settings, $feed, $withcomments;
if (is_feed() && $feed != 'publish' && $feed != 'comments-rss2' && !is_single() && $wp->query_vars['category_name'] == '' && ($withcomments != 1) && trim($feedburner_settings['feedburner_url']) != '') {
Fertig!
Hallo Frank,
ich nutze das Plugin schon sehr lange und finde es toll. Nur eines verstehe ich nicht. Warum werden in meinem Feed auf dem Dashboard Avatare mit angezeigt, die in keinem Zusammenhang mit den Autoren stehen?
vg, daniel
@Daniel: ich habe im Plugin keinerlei Avatare drin, eventuell kommen die via anderes Plugin rein, in unserem genutztem Plugin ist es auch unter 3.2 von WP noch wie im Screenshot.
Hallo Frank,
ja das scheint so zu sein. Ist ja auch nicht dramatisch...
Vielen Dank nochmal für die Zeit.
Daniel
@Daniel:
Ich hatte ebenfalls das 'Problem' mit angezeigten Avataren, habe dies jedoch gelöst, indem ich im Widget-Code (Zeile 89) comment_author durch post_author ersetzt habe. Nun sieht wieder alles so aus wie vorher. Vielleicht hilft dies ja ...