readme.txt, Plugin-Header und SVN: wie WordPress.org ein Plugin liest

Management Summary
Die Plugin-Seite auf WordPress.org entsteht aus mehreren Dateien. Angaben im Programm nennen Version und Voraussetzungen, während eine Readme-Datei die Beschreibung liefert und die veröffentlichte Fassung auswählt. Widersprüche können dazu führen, dass eine Aktualisierung mit alter Versionsnummer erscheint oder der Beschreibungstext unverändert bleibt. Das Beispiel erklärt das Zusammenspiel von herunterladbarer Erweiterung, öffentlichen Angaben und Bildern, damit Veröffentlichungen nachvollziehbar und pflegbar bleiben.
Inhalt
- Der Plugin-Header: Angaben am Anfang der PHP-Datei
- Die Readme: Beschreibung und ausgewählte Version
- Welches Feld wird angezeigt?
- SVN: drei Ordner mit unterschiedlichen Aufgaben
- Bilder und Vorschau
- Erste Veröffentlichung in einem Commit
- Eine weitere Version veröffentlichen
- Prüfung vor der Veröffentlichung
- Fragen und Antworten
- Weitere Artikel und Quellen
WordPress.org liest Angaben zu einem Plugin aus mehreren Dateien. Der Kopf der PHP-Hauptdatei enthält unter anderem die Versionsnummer und die benötigte PHP-Version. Die readme.txt liefert die Beschreibung für das Plugin-Verzeichnis. Ein Eintrag in dieser Readme bestimmt außerdem, welcher Versionsordner veröffentlicht wird. Stimmen diese Angaben nicht überein, kann beispielsweise die Download-Schaltfläche eine alte Versionsnummer zeigen.
Das folgende Beispiel erklärt den Weg von den Dateien bis zur Verzeichnisseite. „LW Reading Time“ ist ein Musterplugin, keine hier nachgewiesene Veröffentlichung. Kontoname, URLs, getestete Versionen, Screenshots und Übersetzungen müssen vor einer echten Einreichung zum tatsächlichen Plugin passen.
Der Plugin-Header: Angaben am Anfang der PHP-Datei
Ein Header ist hier ein Kommentarblock am Anfang der PHP-Hauptdatei. WordPress erkennt ein Plugin bereits am Feld Plugin Name. Für die Aufnahme ins Verzeichnis reicht dieses eine Feld jedoch nicht aus. Der Verzeichnisimport sucht die Hauptdatei direkt im veröffentlichten Ordner. Deshalb liegen Hauptdatei und Readme direkt unter trunk/, nicht nochmals unter trunk/lw-reading-time/.
<?php
/**
* Plugin Name: LW Reading Time
* Plugin URI: https://lukaswojcik.com/plugins/lw-reading-time/
* Description: Shows the estimated reading time above single posts.
* Version: 1.2.0
* Requires at least: 6.5
* Requires PHP: 7.4
* Author: Lukas Wojcik
* Author URI: https://lukaswojcik.com/
* License: GPLv2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: lw-reading-time
*
* @package LW_Reading_Time
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Prepends the estimated reading time to the content of single posts.
*
* @param string $content Post content.
* @return string Filtered content.
*/
function lw_reading_time_prepend( $content ) {
if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
return $content;
}
$words = preg_split( '/\s+/u', trim( wp_strip_all_tags( $content ) ), -1, PREG_SPLIT_NO_EMPTY );
if ( false === $words ) {
return $content;
}
$minutes = max( 1, (int) ceil( count( $words ) / 200 ) );
$label = sprintf(
/* translators: %d: number of minutes. */
_n( '%d minute read', '%d minutes read', $minutes, 'lw-reading-time' ),
$minutes
);
return '<p class="lw-reading-time">' . esc_html( $label ) . '</p>' . $content;
}
add_filter( 'the_content', 'lw_reading_time_prepend' );
Das Beispiel schätzt die Lesezeit anhand von durch Leerraum getrennten Textteilen und 200 Wörtern pro Minute. Auch geschützte Leerzeichen werden berücksichtigt. Das ist eine Näherung, keine sprachwissenschaftliche Wortzählung; Sprachen ohne Leerzeichen zwischen Wörtern benötigen ein anderes Verfahren. Die Ausgabe beträgt mindestens eine Minute. Bei ungültigem UTF-8 bleibt der Inhalt unverändert.
Versionbezeichnet die Plugin-Version. PHP vergleicht Versionsangaben mitversion_compare():1.02gilt dabei als neuer als1.1. Einheitliche Nummern wie1.2.0vermeiden solche Überraschungen.Requires at leastundRequires PHPnennen die Mindestversionen. WordPress liest diese Anforderungen aus der PHP-Datei. Identische Angaben in der Readme verhindern widersprüchliche Anzeigen.Requires Pluginsenthält bei Bedarf Verzeichnisnamen wiewoocommerce, keine PHP-Dateipfade. Für Verzeichnisplugins müssen die dort genannten Abhängigkeiten ebenfalls im Verzeichnis veröffentlicht sein. Das Feld ersetzt keine Prüfung benötigter Funktionen oder konkreter Versionsstände.Update URIbleibt bei einem normalen Verzeichnisplugin weg. Der Import akzeptiert keine beliebige externe Update-Adresse; eine erkannte Verzeichnisadresse muss zum selben Plugin gehören.Text Domainordnet übersetzbare Texte dem Plugin zu und entspricht dem Slug, also dem kurzen Verzeichnisnamen.
Die Readme: Beschreibung und ausgewählte Version
Die Readme verwendet eine vereinfachte Markdown-Schreibweise. Doppelte Gleichheitszeichen markieren Abschnitte. Der kurze Text nach den Kopfzeilen erscheint unter dem Plugin-Namen. Eine knappe Beschreibung mit höchstens 150 Zeichen vermeidet abgeschnittene Sätze.
=== LW Reading Time ===
Contributors: lukaswojcik
Tags: reading time, posts, content
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.2.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Shows the estimated reading time above single posts, based on the word count of the post content.
== Description ==
LW Reading Time counts the words of a post and shows the estimated reading time above the content of single posts.
* No settings page, no database tables.
* The output is a single paragraph with the class `lw-reading-time`.
* Translations are managed on translate.wordpress.org.
== Installation ==
1. Install the plugin via Plugins > Add New, or upload the folder `lw-reading-time` to `/wp-content/plugins/`.
2. Activate the plugin.
3. Open any single post; the reading time appears above the content.
== Frequently Asked Questions ==
= How is the reading time calculated? =
The word count of the post content is divided by 200 and rounded up to full minutes.
= Does the plugin change pages? =
No. Only single posts of the post type `post` are changed.
== Screenshots ==
1. Reading time above a single post.
2. The same post with the Polish translation active.
== Changelog ==
= 1.2.0 =
* Plural forms for the reading time label.
* WordPress 6.5 or later is required.
= 1.1.0 =
* Output limited to the main query.
== Upgrade Notice ==
= 1.2.0 =
Adds plural forms. WordPress 6.5 or later is now required.
Die Angaben im Muster sind Beispiele. Eine Übersetzung auf translate.wordpress.org, die genannten Bilder und ein Test mit einer bestimmten WordPress-Version müssen tatsächlich vorhanden sein, bevor entsprechende Aussagen veröffentlicht werden. Contributors enthält WordPress.org-Benutzernamen; Tags höchstens fünf passende Suchbegriffe. Tested up to nennt den wirklich getesteten WordPress-Versionszweig, keine gewünschte zukünftige Kompatibilität.
Die üblichen Abschnitte erklären Funktion, Installation, häufige Fragen, Screenshots und Änderungen. Nummerierte Screenshot-Beschreibungen gehören zu screenshot-1, screenshot-2 und so weiter. Lange ältere Änderungslisten lassen sich in eine eigene Datei auslagern. Der Handbook-Hinweis auf mögliche Probleme oberhalb von 10 kB ist keine allgemeine harte Importgrenze.
Welches Feld wird angezeigt?
| Anzeige | Quelle beim Verzeichnisimport |
|---|---|
| Plugin-Name | Readme-Titel; normalerweise PHP-Header als Ersatz, auch wenn der Readme-Titel nur dem Slug entspricht. |
| Kurzbeschreibung | Readme; PHP-Beschreibung als Ersatz. |
| Versionsnummer | Version im PHP-Header. |
| WordPress-/PHP-Mindestversion | Passend formatierter PHP-Header; Readme als Ersatz. |
| Tested up to | Zusätzlicher PHP-Header, falls vorhanden und akzeptiert; sonst Readme. |
| Suchbegriffe und Mitwirkende | Readme. |
Die Tabelle beschreibt den geprüften Importcode. Die Versionsprüfung im Header akzeptiert an dieser Stelle bereits bestimmte Folgen aus Ziffern und Punkten; eine akzeptierte Zeichenfolge belegt daher noch keinen echten Kompatibilitätstest. Die Readme hat eigene Prüfregeln, unter anderem für zu weit vorausliegende Werte. Diese Regeln gelten nicht automatisch genauso für den Header. Das Verzeichnis kann Versionsangaben außerdem auf einen zugehörigen veröffentlichten Versionsstand abbilden.
SVN: drei Ordner mit unterschiedlichen Aufgaben
SVN ist die Versionsverwaltung des Plugin-Verzeichnisses. trunk/ enthält den vorbereiteten Stand, tags/1.2.0/ die Dateien einer bestimmten Version und der oberste Ordner assets/ die Bilder für die Verzeichnisseite. Diese Bilder gehören nicht zum heruntergeladenen Plugin-ZIP.
Im üblichen Ablauf steht in trunk/readme.txt der Eintrag Stable tag: 1.2.0. WordPress.org sucht dann tags/1.2.0/. Existiert dieser Ordner mit den passenden Dateien, stammen Code und Beschreibung aus diesem Versionsordner. Eine nur in trunk geänderte Beschreibung erscheint dann nicht auf der Plugin-Seite. Versionsnummer im PHP-Header, Ordnername und Stable-tag-Angaben müssen zusammenpassen.

Ein fehlender Versionsordner ist kein harmloser Normalzustand. Der Import kann auf trunk zurückfallen; eine aktivierte Release-Bestätigung kann den Import stattdessen stoppen. Stable tag: trunk ist für neue Plugins nicht erlaubt. Das Verzeichnis baut betroffene ZIP-Versionen neu, nicht grundsätzlich alle alten Versionen bei jedem Commit. Ein Commit ist eine gemeinsam gespeicherte Änderung; die Verarbeitung und zwischengespeicherte Anzeige folgen zeitversetzt.
Bilder und Vorschau
Der oberste assets-Ordner nimmt die dokumentierten Dateinamen auf: etwa banner-772x250.png, zusätzlich banner-1544x500.png für hochauflösende Anzeigen, icon-128x128.png, icon-256x256.png und nummerierte Screenshots. Die Bildmaße müssen zum jeweiligen Format passen. Dokumentierte kleingeschriebene Namen vermeiden Unklarheiten; der geprüfte Importcode ignoriert Großbuchstaben nicht pauschal.
Für eine Playground-Vorschau beschreibt das Handbuch assets/blueprints/blueprint.json. Diese JSON-Datei enthält Schritte zum Einrichten einer Testumgebung im Browser. Eine gültige Datei allein schaltet die Vorschau nicht öffentlich: Zusätzlich muss die öffentliche Vorschau in der erweiterten Plugin-Ansicht aktiviert werden. Bildänderungen können wegen Zwischenspeichern verzögert erscheinen.
Erste Veröffentlichung in einem Commit
Die Befehle setzen ein bereits genehmigtes Repository, vorbereitete Dateien und die benötigten Bilder voraus. Der Platzhalter WPORG_USERNAME steht für den echten WordPress.org-Kontonamen. Die Anmeldung benötigt die passenden SVN-Zugangsdaten. Hauptdatei und Readme enthalten bereits Version 1.2.0.
# Run in a shell that stops on errors. Replace the approved slug and account.
set -eu
# First release: check out the repository created after approval.
svn co https://plugins.svn.wordpress.org/lw-reading-time lw-reading-time-svn
cd lw-reading-time-svn
# Main plugin file and readme.txt go directly into trunk/, not into a subfolder.
cp ../lw-reading-time/lw-reading-time.php ../lw-reading-time/readme.txt trunk/
svn add trunk/*
# Banner, icon, screenshots and blueprint go into the top-level assets/ folder.
cp ../lw-reading-time-assets/banner-772x250.png ../lw-reading-time-assets/banner-1544x500.png assets/
cp ../lw-reading-time-assets/icon-128x128.png ../lw-reading-time-assets/icon-256x256.png assets/
cp ../lw-reading-time-assets/screenshot-1.png ../lw-reading-time-assets/screenshot-2.png assets/
mkdir assets/blueprints
cp ../lw-reading-time-assets/blueprint.json assets/blueprints/
svn add assets/*
# Serve the images as images instead of application/octet-stream.
svn propset svn:mime-type image/png assets/*.png
# Prepare the tag before publishing anything. The source files already say 1.2.0.
svn cp trunk tags/1.2.0
svn status
svn diff
# One commit publishes trunk, tag and assets together. The username is case sensitive.
svn ci -m "Release LW Reading Time 1.2.0 with assets" --username WPORG_USERNAME
Der Versionsordner entsteht vor dem Commit. Dadurch werden trunk, Version und Bilder zusammen gespeichert. svn status zeigt geänderte Pfade, svn diff die Textänderungen. Die MIME-Eigenschaft kennzeichnet PNG-Dateien als Bilder. Bei JPEG lautet der Typ image/jpeg.
Eine weitere Version veröffentlichen
Das zweite Beispiel startet im übergeordneten Ordner der vorhandenen Arbeitskopie. Die vorbereiteten Dateien enthalten jetzt Version 1.3.0. Das Kopieren ersetzt hier nur zwei Dateien. Alte, nicht mehr benötigte Dateien verschwinden dadurch nicht: Solche Pfade müssen nach Prüfung ausdrücklich mit svn delete entfernt werden.
# Run from the parent directory of the existing working copy.
set -eu
# Next release: bring the working copy up to date.
cd lw-reading-time-svn
svn up
# Version header and Stable tag both say 1.3.0 in the copied files.
cp ../lw-reading-time/lw-reading-time.php ../lw-reading-time/readme.txt trunk/
# This example copies two files only. Inspect obsolete tracked files separately.
# Use svn delete on each deliberately removed path before tagging.
svn add --force trunk
svn stat
svn diff
# Copy trunk to the new tag and commit trunk and tag together.
svn cp trunk tags/1.3.0
svn ci -m "Release 1.3.0"
svn cp übernimmt die Versionsgeschichte. Alte veröffentlichte Versionsordner bleiben unverändert. Entwicklungsdateien, private Konfigurationen und ZIP-Archive gehören nicht in die ausgelieferten Plugin-Dateien. Eine .gitignore schützt nicht vor einem versehentlichen SVN-Commit. Der separate oberste assets-Ordner wird hingegen nicht mit dem Plugin installiert.
Prüfung vor der Veröffentlichung
Der Readme-Validator prüft Namen, Felder und Textaufbau. Das Werkzeug prüft nicht, ob der Versionsordner existiert, der PHP-Header dieselbe Version nennt oder Abhängigkeiten verfügbar sind. Diese Fragen betreffen weitere Dateien beziehungsweise den Verzeichnisimport. Ein fehlerfreies Readme-Ergebnis ist deshalb keine Freigabe des Plugins.
Bei Eingabe einer URL akzeptiert der geprüfte Validator bestimmte Hosts, darunter plugins.svn.wordpress.org und raw.githubusercontent.com, sowie passende Readme-Dateinamen. Der abgerufene Inhalt muss kleiner als 512 KiB sein; genau 512 KiB werden bereits abgewiesen. Diese Abrufgrenze ist nicht mit dem Hinweis auf eine kurze Readme zu verwechseln.
Die beiden SVN-Abläufe wurden in einem getrennten lokalen Repository geprüft: gemeinsame erste Veröffentlichung, korrekte Versionskopien, Bildtyp, erhaltene alte Version und saubere Arbeitskopie. Acht weitere isolierte PHP-Prüfungen decken die Textzählung und Fehlerfälle ab. Das ersetzt weder einen echten WordPress-Lauf noch Plugin Check oder die Freigabe durch WordPress.org. Die Aussagen zum Import beruhen auf dem gelesenen Quellcode; der Importdienst wurde nicht lokal nachgebaut.
Fragen und Antworten
Warum bleibt die Beschreibung trotz Commit unverändert?
Bei einem gültigen Stable tag liest das Verzeichnis die Beschreibung aus dem zugehörigen Versionsordner. Eine Änderung nur in trunk reicht dann nicht. Zusätzlich können Import und Zwischenspeicher die sichtbare Änderung verzögern.
Warum stimmt die angezeigte Version nicht mit dem Ordnernamen überein?
Die angezeigte Versionsnummer stammt aus dem PHP-Header. Ein neuer Ordnername ändert den Inhalt dieses Feldes nicht. Header, Readme und Versionsordner müssen denselben Release bezeichnen.
Warum unterscheiden sich Readme und Anzeige bei Tested up to?
Ein akzeptierter Header-Wert kann die Readme überschreiben. Außerdem kann das Verzeichnis den eingetragenen Versionszweig auf einen zugehörigen veröffentlichten Stand abbilden. Die Anzeige beweist keinen zusätzlichen Test des Plugins.
Weitere Artikel und Quellen
- Prüfung und Verzeichnisregeln
- Plugin Check
- Übersetzungen
- Playground und Blueprints
- Plugin Handbook: readme.txt format
- Plugin Handbook: Header Requirements
- Plugin Handbook: Using Subversion
- Plugin Handbook: plugin assets
- Plugin Handbook: Previews and Blueprints
- WordPress.org: Readme Validator
- WordPress.org: Beispiel-readme.txt
- GitHub WordPress/wordpress.org: Readme-Parser (class-parser.php)
- GitHub WordPress/wordpress.org: Readme-Validator (class-validator.php)
- GitHub WordPress/wordpress.org: Plugin-Importer (class-import.php)
- GitHub WordPress/wordpress-develop: validate_plugin_requirements() in plugin.php
- GitHub WordPress/wordpress-develop: Upgrade Notice in update-core.php
- Make WordPress Core: Introducing Plugin Dependencies in WordPress 6.5
- WordPress.org: Plugin Check (PCP), Plugin-Seite und Changelog
- WordPress.org API: core version check