Schritt-für-Schritt-Anleitung: Eigenes WordPress-Plugin erstellen und individuellen Content-Typ verwenden
WordPress bietet eine Fülle von Funktionen, die es Benutzern ermöglichen, ihre Webseiten nach ihren individuellen Bedürfnissen anzupassen. Eine der leistungsstärksten Möglichkeiten, dies zu tun, besteht darin, eigene Plugins zu programmieren und individuelle Content-Typen zu verwenden. In diesem Artikel werden wir einen umfassenden Leitfaden bereitstellen, der Dir zeigt, wie Du dein eigenes WordPress-Plugin erstellen und einen maßgeschneiderten Content-Typ implementieren kannst.
Planung
Bevor wir mit dem programmieren starten, nimm dir einen Moment Zeit, um zu überlegen, was genau dein Plugin tun soll. Eine klare Planung wird den Entwicklungsprozess erleichtern.
- Welchen Zweck soll dein Plugin erfüllen?
- Welche Felder brauchst du?
- Wie soll das später auf der Webseite angezeigt werden?
In meiner Schritt-für-Schritt-Anleitung zeige ich dir, wie du ein individuelles WordPress-Plugin erstellst und einen maßgeschneiderten Content-Typ für spezielle Nachrichtenartikel verwendest. Neben den standardmäßigen WordPress-Feldern wie Titel, Editor und Bild füge ich außerdem Untertitel hinzu sowie zwei Felder mit TinyMCE-Editor – eines für die linke Spalte und eines für die rechte Spalte.
Für die Umsetzung empfehle ich eine WordPress-Entwicklungsumgebung, um deine Live-Seite nicht zu beeinträchtigen, falls während der Programmierung etwas schiefgeht. Du benötigst außerdem ein WordPress-Theme, das Bootstrap 5 unterstützt, einen Editor deiner Wahl, Grundkenntnisse in der WordPress Programmierung und natürlich Spaß am Programmieren.
Erstelle dein Plugin Ordner und die benötigten Dateien
Öffne deine WordPress-Installation und navigiere zum Plugin-Verzeichnis. Dies findest du normalerweise unter:
wp-content/plugins
Erstelle in dem Verzeichnis einen neuen Ordner für dein Plugin. Nenn den Ordner am besten nach dem, was dein Plugin macht. In unserer Anleitung nehme ich den Namen „news-content“. Das ganze sieht dann dann so aus:
wp-content/plugins/news-content
Für eine bessere Struktur und Übersicht erstellen wir weitere Unterordner. Du wechselst also in dein eben hinzugefügten Ordern und richtest weitere Ordner ein wie in folgendem Beispiel:
wp-content/plugins/news-content/css
wp-content/plugins/news-content/tpl
Als nächstes erstellen wir unsere PHP-Hauptdatei die für die grundlegenden Funktionen zuständig ist. Benenne die Datei so wie dein Plugin Ordner:
wp-content/plugins/news-content/news-content.php
Implementieren der Grundfunktionalitäten für das WordPress-Plugin
Öffne die news-content.php in einem Editor deiner Wahl und trage folgende Zeilen ein:
<?php
/*
Plugin Name: News Content
Description: Inhaltselement für die Darstellung von News mit Bild und Text
Version: 1.0
Author: Dein Name
Author URI: https://www.deine-domain.de/
*/
if ( ! defined( 'ABSPATH' ) ) { exit; } // Diese Zeile sorgt dafür das nur WordPress diese Datei ausführen darf.
Als nächstes müssen wir den Content Type registrieren. Das machen wir mit folgender Methode die du auch in die news-content.php nach der Zeile 10 einfügst.
function news_content_post_type()
{
$labels = [
'name' => _x( 'News', 'post type general name', 'protipps' ),
'singular_name' => _x( 'News', 'post type singular name', 'protipps' ),
'add_new' => __( 'News erstellen', 'protipps' ),
'add_new_item' => __( 'News erstellen', 'protipps' ),
'new_item' => __( 'News erstellen', 'protipps' ),
'edit_item' => __( 'News bearbeiten', 'protipps' ),
'view_item' => __( 'News anzeigen', 'protipps' ),
'all_items' => __( 'Alle News', 'protipps' ),
'search_items' => __( 'News durchsuchen', 'protipps' ),
'not_found' => __( 'Keine News gefunden.', 'protipps' ),
'not_found_in_trash' => __( 'Keine News im Papierkorb gefunden.', 'protipps' )
];
$args = [
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => [
'slug' => 'news-content'
],
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'supports' => [
'title', 'editor', 'thumbnail'
],
];
register_post_type( 'news_content', $args );
}
add_action( 'init', 'news_content_post_type' );
Was genau die einzelnen Argumente bedeuten, muss ich hier nicht extra erklären, die sind gut dokumentiert in der WordPress-Dokumentation die du hier findest.
Mit der nächsten Methode die Du einfügen kannst, bestimmen wir den Beschreibungstext des Titel Feldes von WordPress. Ohne dieser Methode wird der Standard Wert von WordPress angezeigt.
function news_enter_title( $input )
{
if ( 'news_content' === get_post_type() ) {
return __( 'News Titel hier eingeben', 'protipps' );
}
return $input;
}
add_filter( 'enter_title_here', 'news_enter_title' );
Neue Felder hinzufügen
Als nächstes erstellen wir den Container für unsere neuen Felder. Füge auch diesen Code in die news-content.php ein.
function news_content_new_fields()
{
add_meta_box(
'news_content_fields',
'Inhalt',
'news_content_fields_callback',
'news_content',
'normal',
'high'
);
}
add_action( 'add_meta_boxes', 'news_content_new_fields' );
Im nächsten Schritt definieren wir die zusätzlichen Felder die wir noch benötigen. Die Methode ist umfangreicher wie die bisherigen deshalb habe ich Kommentare im Code platziert und versuche am Ende den Rest noch so verständlich wie möglich zu erklären.
function news_content_fields_callback( $post )
{
// Nonce-Feld für jedes benutzerdefinierte Feld hinzufügen
wp_nonce_field( 'news_subtitle_nonce', 'news_subtitle_nonce' );
wp_nonce_field( 'news_left_nonce', 'news_left_nonce' );
wp_nonce_field( 'news_right_nonce', 'news_right_nonce' );
// Hole die gespeicherten Werte für die benutzerdefinierten Felder
$subtitle = get_post_meta( $post->ID, '_news_subtitle', true );
$left = get_post_meta( $post->ID, '_news_left', true );
$right = get_post_meta( $post->ID, '_news_right', true );
// Start Formular für benutzerdefinierte Felder ausgeben
?>
<p>
<label for="news_subtitle"><b><?php __('Untertitel', 'protipps'); ?></b></label><br>
<input type="text" style="width:100%;" name="news_subtitle" id="news_subtitle" value="<?php echo esc_attr( $subtitle ); ?>" />
</p>
<div class="row">
<div class="col-lg-6">
<label for="news_left"><b><?php __('Linke Spalte', 'protipps'); ?></b></label>
<?php
$settings = [
'textarea_name' => 'news_left',
'textarea_rows' => 5,
'teeny' => false, // Wenn true, zeigt eine vereinfachte Toolbar an, sonst die vollständige Toolbar
'quicktags' => true, // Wenn true, zeigt die Schnelltags-Schaltflächen an
'tinymce' => [
'wpautop' => true,
'toolbar1' => 'formatselect | bold italic strikethrough | bullist numlist | blockquote | alignleft aligncenter alignright alignjustify | link unlink | undo redo',
'toolbar2' => 'styleselect | pastetext | removeformat | charmap | outdent indent | undo redo',
'block_formats' => 'Paragraph=p; Heading 2=h2; Heading 3=h3; Heading 4=h4; Heading 5=h5; Heading 6=h6',
'valid_elements' => 'p[style],strong,em,span[style],a[href|target=_blank],ul,ol,li,blockquote,br,h2,h3,h4,h5,h6',
],
];
wp_editor( $left, 'news_left', $settings );
?>
</div>
<div class="col-lg-6">
<label for="news_right"><b><?php __('Rechte Spalte', 'protipps'); ?></b></label>
<?php
$settings = [
'textarea_name' => 'news_right',
'textarea_rows' => 5,
'teeny' => false, // Wenn true, zeigt eine vereinfachte Toolbar an, sonst die vollständige Toolbar
'quicktags' => true, // Wenn true, zeigt die Schnelltags-Schaltflächen an
'tinymce' => [
'wpautop' => true,
'toolbar1' => 'formatselect | bold italic strikethrough | bullist numlist | blockquote | alignleft aligncenter alignright alignjustify | link unlink | undo redo',
'toolbar2' => 'styleselect | pastetext | removeformat | charmap | outdent indent | undo redo',
'block_formats' => 'Paragraph=p; Heading 2=h2; Heading 3=h3; Heading 4=h4; Heading 5=h5; Heading 6=h6',
'valid_elements' => 'p[style],strong,em,span[style],a[href|target=_blank],ul,ol,li,blockquote,br,h2,h3,h4,h5,h6',
],
];
wp_editor( $right, 'news_right', $settings );
?>
</div>
</div>
<?php
}
Nonce Felder: Nonce-Felder (Number used Once) in WordPress sind Sicherheitsmechanismen, die verwendet werden, um sicherzustellen, dass Formulare auf einer WordPress-Website von autorisierten Benutzern eingereicht werden. Nonce-Felder helfen, Cross-Site Request Forgery (CSRF) Angriffe zu verhindern
get_post_meta: Mit get_post_meta holt man sich die gespeicherten Werte beim editieren von einer News.
Formular: Das Formular wird hier aufgebaut mit einem Subtitle (Textfeld) und zwei weiteren TinyMCE Felder die über die entsprechenden Settings gesteuert werden. Auch für den Editor gibt es schon eine ausführliche Dokumentation auf der offiziellen WordPress Seite.
Wie du siehst habe ich auch schon DIV-Klassen verwendet, die mir später dann Bootstrap korrekt verarbeitet und meine Elemente nebeneinander anzeigen wird. Dazu kommen wir aber später im Detail.
Speichern der Werte aus unseren benutzerdefinierten Feldern
Mit der folgenden Methode speichern wir unsere eingegebenen Werte in der Datenbank von WordPress.
function save_news_content_fields( $post_id )
{
if ( !isset( $_POST['news_subtitle_nonce'] ) || !wp_verify_nonce( $_POST['news_subtitle_nonce'], 'news_subtitle_nonce' ) ) { return; }
if ( !isset( $_POST['news_left_nonce'] ) || !wp_verify_nonce( $_POST['news_left_nonce'], 'news_left_nonce' ) ) { return; }
if ( !isset( $_POST['news_right_nonce'] ) || !wp_verify_nonce( $_POST['news_right_nonce'], 'news_right_nonce' ) ) { return; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// Sicherstellen, dass die Benutzer die erforderlichen Berechtigungen haben
if ( !current_user_can( 'edit_post', $post_id ) ) return;
// Speichern der Werte für benutzerdefinierte Felder
update_post_meta( $post_id, '_news_subtitle', sanitize_text_field( $_POST['news_subtitle'] ) );
update_post_meta( $post_id, '_news_left', wp_kses_post( $_POST['news_left'] ) );
update_post_meta( $post_id, '_news_right', wp_kses_post( $_POST['news_right'] ) );
}
add_action( 'save_post', 'save_news_content_fields' );
Zeile 3,4,5: Hier prüfen wir ob Werte vorhanden sind und dass die eingegebene Daten auch sicher sind.
Zeile 7: Diese Bedingung wird häufig in WordPress-Hooks und Funktionen eingefügt, um zu verhindern, dass bestimmte Codeabschnitte während eines automatischen Speicherns von Beiträgen oder Seiten aktiviert werden.
Zeile 10: Prüfen der Rechte
Zeile 13,14,15: Wenn alles passt, speichern wir die Werte in der Datenbank.
Template für die Anzeige der Inhalte
Damit wir unsere speziellen News erstellen und speichern können ist soweit alles fertig. Nun müssen wir die Inhalte aber noch auf unserer Webseite anzeigen lassen. Dafür verwenden wir eine Template-Datei, ich nenne sie in diesem Fall „page-news-content.php“, die wir in unseren tpl Ordner anlegen müssen. So sollte das Ganze dann aussehen:
wp-content/plugins/news-content/tpl/page-news-content.php
Folgender Inhalt gehört in die page-news-content.php Datei. Erklärung wie gewohnt nach dem Code.
<?php
/**
* Template Name: News Content
*/
if ( ! defined( 'ABSPATH' ) ) { exit; }
get_header(); ?>
<?php
$args = [
'posts_per_page' => 10,
'orderby' => 'ASC',
'post_type' => 'news_content',
'post_status' => 'publish'
];
$custom_query = new WP_Query($args);
if ($custom_query->have_posts()) :
while ($custom_query->have_posts()) : $custom_query->the_post();
$subtitle = get_post_meta(get_the_ID(), '_news_subtitle', true);
$news_left = get_post_meta(get_the_ID(), '_news_left', true);
$news_right = get_post_meta(get_the_ID(), '_news_right', true);
?>
<div class="section news">
<div class="container my-5">
<div class="row">
<?php if ( has_post_thumbnail() ) : ?>
<div class="col-lg-6 text-center">
<div class="image-wrapper p-3">
<a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('full', ['class' => 'img-fluid']); ?></a>
<?php if ( $caption = get_post( get_post_thumbnail_id() )->post_excerpt ) : ?>
<div class="figcaption">
<?php echo $caption; ?>
</div>
<?php endif; ?>
</div>
</div>
<div class="col-lg-6 align-self-center">
<?php else : ?>
<div class="offset-lg-1 col-lg-10 text-center">
<?php endif; ?>
<h2 class="news-subtitle"><?php echo esc_html($subtitle); ?></h2>
<h3 class="news-title"><?php the_title(); ?></h3>
<?php the_content(); ?>
<?php if( $news_left || $news_right) { ?>
<hr>
<div class="row news-content">
<?php if( $news_left ) { ?>
<div class="col-lg">
<?php echo wp_kses_post($news_left); ?>
</div>
<?php } ?>
<?php if( $news_right ) { ?>
<div class="col-lg">
<?php echo wp_kses_post($news_right); ?>
</div>
<?php } ?>
</div>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
<?php endwhile;
wp_reset_postdata();
endif;
?>
<?php get_footer();
Zeile 11-16: Die Argumente welcher Inhalt angezeigt werden soll. In diesem Fall – maximal 10 News – Sortierung „aufsteigend“ – unser Content Type „news_content“ – und nur veröffentlichte.
Zeile 18: Die WP_Query ist eine leistungsstarke Klasse in WordPress, die es ermöglicht, benutzerdefinierte Abfragen für Beiträge, Seiten und benutzerdefinierte Post-Typen durchzuführen.
Zeile 22-24: Damit holen wir die Inhalte von unseren benutzerdefinierten Feldern aus der Datenbank.
Zeile 26-66: Dient dann der Anzeige wie die Inhalte auf der Webseite angezeigt werden. Wir verwenden Bootstrap 5 für unser Grid. Wer Bootstrap schon mal verwendet hat, kann vielleicht erkennen dass ein paar Feinheiten eingebaut sind wie – wenn kein Bild verwendet wird, wird der Text mittig angezeigt, mit Bild zwei-spaltig. Mit den Variablen aus Zeile 22-24 können wir die Texte dann an gewünschter Position anzeigen.
Neues Template zur Verfügung stellen
Damit wir das Template verwenden können, müssen wir unserem Plugin noch sagen wo es zu finden ist. Das ganze müssen wir wieder in unsere Hauptdatei news-content.php machen.
Template im Plugin suchen, nicht im Theme:
function news_redirect_page_template($template) {
if( is_page_template('page-news-content.php') )
$template = WP_PLUGIN_DIR . '/news-content-type/tpl/page-news-content.php';
return $template;
}
add_filter ('page_template', 'news_redirect_page_template');
Als Page-Template Auswahl zur Verfügung stellen:
function register_news_page_template($templates)
{
$templates['page-news-content.php'] = 'News Template';
return $templates;
}
add_filter('theme_page_templates', 'register_news_page_template');
CSS-Datei für das Frontend verknüpfen
Damit wir die Ausgabe auf der Webseite stylen können, erstellen wir uns noch eine CSS Datei (styles.css) in unserem css Order im Plugin und verknüpfen diese mit folgender Methode:
function enqueue_plugin_styles() {
wp_enqueue_style('plugin-styles', plugins_url('css/styles.css', __FILE__));
}
add_action('wp_enqueue_scripts', 'enqueue_plugin_styles');
Backend CSS implementieren
Damit auch im Backend alles schön aussieht, zumindest die beiden Spalten links und rechts angezeigt werden, implementieren wir noch von Bootstrap die Grid CSS-Datei. Bootstrap gibt es hier zum herunterladen.
function admin_custom_style() {
wp_enqueue_style('admin-styles', plugins_url('css/bootstrap-grid.min.css', __FILE__));
}
add_action('admin_enqueue_scripts', 'admin_custom_style');
Plugin aktivieren und testen
Aktiviere dein Plugin in der WordPress-Administration und erstelle eine neue Seite. Wähle bei Template das News Content Template und erstelle dann deine ersten Inhalte. Sieh nach, ob dein individueller Content-Typ korrekt angezeigt wird. Passe deine Funktionen nach Bedarf an und teste erneut, bis du mit dem Ergebnis zufrieden bist.
Herzlichen Glückwunsch! Du hast erfolgreich dein eigenes WordPress-Plugin erstellt und einen individuellen Content-Typ hinzugefügt. Dieser Leitfaden bietet eine solide Grundlage, um weitere Funktionen und Anpassungen hinzuzufügen. Viel Spaß beim Entwickeln!
Weitere Beiträge
TYPO3 8.7 - FAL in eigener Extbase Extension nutzen.
OXID 6 | Vorstellung Modul mit Entwicklerwerkzeugen
PHP | MySQL Datenbankverbindung aufbauen mit PDO
TYPO3 9.5 - Feld seo_title als Browsertitel ausgeben