Grundlegender Plugin-Header

<?php
/**
* Plugin Name: Beispiel Plugin
* Plugin URI: http://domain.tld/beispiel-plugin/
* Description: Mit diesem Beispiel Plugin wird der Plugin-Header erklärt.
* Version: 0.1
* Author: Vorname Nachname
* Author URI: http://domain.tld
* Text Domain: beispiel-plugin
* Domain Path: /languages
* License: GPL2 or later
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/

/**
* GPL2 License Text
Copyright JAHR VORNAME NACHNAME E-MAIL-ADRESSE
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/**
* Avoid direct calls
*/
defined('ABSPATH') or die("No direct requests for security reasons."); 
?>

Lösungen für mehrsprachige Websites in Single- oder Multisite-Umgebungen

Lösung über eine Singlesite-Umgebung

Grundsätzliche Vorteile bei einer Lösung in einer Singlesite-Umgebung:

  • in der Regel funktioniert das Wechseln zwischen verschiedenen Sprachversionen über Tabs mit einem Klick, dadurch schnelleres Arbeiten im Administrationsbereich
  • die Mediendateien der Website müssen nicht über eine weitere Lösung im ganzen Multisite-Netzwerk verfügbar gemacht werden
  • nur eine Website muss z. B. hinsichtlich anderer Plugins verwaltet und konfiguriert werden

Plugin-Lösungen für Singlesite-Umgebung:

  • Polylang, kostenlos; Besonderheit: jede Sprachversion wird in eigenen Beitrag / einer Seite gespeichert (Deinstallation leichter möglich)
  • qtranslate x, kostenlos; Besonderheit: Nachfolger von qtranslate, lange Zeit Platzhirsch im kostenfreien Bereich, aber nicht immer mit der aktuellsten WordPress-Version nutzbar
  • stella, einmalig $15; Besonderheit: Oberfläche und Dokumentation nicht in deutscher Sprache verfügbar
  • WPML, ab $29 mit eingeschränkten Funktionen, $195 für unbegrenzte Nutzung/Updates; Besonderheit: Schnittstelle für professionelle Übersetzungsdienstleistung integriert

Lösung über eine Multisite-Umgebung

Grundsätzliche Vorteile bei einer Multisite-Umgebung:

  • in der Regel bessere Performance der Website für den Nutzer, da klare Trennung der Sprachversionen
  • keine größeren Eingriffe in die Datenbank, die eine Deinstallation zu einem anstrengenden Unterfangen machen
  • bei Deinstallation des Plugins existieren die Sprachversionen weiter und können weiter genutzt werden (ggf. nur weniger komfortabel)

Plugin-Lösungen für Multisite-Umgebung

Erweiterte Autoreninformationen ohne Plugin anzeigen

Realisiert werden soll die Anzeige von Autoreninformationen in der Einzelansicht von Beiträgen ohne Plugin. Folgende Punkte sollen angezeigt bzw. beachtet werden:

  • Links zur Website des Autors und ggf. sozialen Netzwerken, sofern diese Informationen im Profil angegeben sind
  • bisher verfasste Beiträge verlinkt mit dem individuellen Archiv des Autoren
  • Ausgabe des Website-Namens im Text via Abfrage, damit die Lösung variabel einsetzbar ist

Über die functions.php oder via Plugin werden benutzerdefinierte Autorenangaben möglich. In einer Multisite-Umgebung präferiere ich den Einsatz dieser Kontaktangaben netzwerkweit, also über ein Must-Use-plugin zu definieren. Zur Übersichtlichkeit auf der Profil-Seite werden dort zunächst AIM, Jabber und YIM deaktiviert.

function custom_contactmethods( $contactmethods ) {
  unset($contactmethods['aim']);
  unset($contactmethods['jabber']);
  unset($contactmethods['yim']);
  $contactmethods['twitter'] = 'Twitter';
  $contactmethods['facebook'] = 'Facebook';
  $contactmethods['xing'] = 'XING';
  return $contactmethods;
}
add_filter('user_contactmethods','custom_contactmethods',10,1);

single.php

<div class="postauthor">
  <p class="postauthorabout">&Uuml;ber den Autor<p>
  <h2><?php the_author(); ?></h2>
  <p class="postauthorbio"><?php if(get_the_author_meta('description') != NULL) { ?><?php the_author_meta('description'); ?> <?php } ?>
  Auf <?php bloginfo('name'); ?> stammen <a href="<?php echo get_author_posts_url( get_the_author_meta( 'ID' ) ); ?>" title="Alle Beitr&auml;ge von <?php the_author(); ?>"><?php the_author_posts(); ?> Beitr&auml;ge</a> aus der Feder von <?php the_author_meta('user_firstname'); ?>.</p>
  <p class="postauthorlinks">
  <?php if(get_the_author_meta('user_url') != NULL) { ?><a href="<?php the_author_meta('user_url'); ?>">Website</a> <?php } ?>
  <?php if(get_the_author_meta('facebook') != NULL) { ?><a href="<?php the_author_meta('facebook'); ?>">Facebook</a> <?php } ?>
  <?php if(get_the_author_meta('twitter') != NULL) { ?><a href="<?php the_author_meta('twitter'); ?>">Twitter</a> <?php } ?>
  <?php if(get_the_author_meta('xing') != NULL) { ?><a href="<?php the_author_meta('xing'); ?>">XING</a> <?php } ?>
  </p>
</div>

style.css

.postauthorabout { font-size:0.8em; }
.postauthorabout, .postauthorlinks { font-variant:small-caps; }
.postauthorbio { margin:0 0 0.8em 0; }
.postauthorlinks { font-weight:bold; }
.postauthorlinks a { margin:0 0.4em 0 0; }

Ergebnis

So kann das Ganze dann aussehen:

Autoreninformationen Screenshot

Referenz

Suchfunktion verbessern

Realisation über ein Plugin. Beitrag dient als Notiz und wird kontinuierlich erweitert.

/*
Plugin Name: Verbesserte Suchfunktion
Description: Diverse Verbesserungen für die interne Suche auf der Website.
Version: 1.0
*/

// Bei einzelnem Suchergebnis sofort auf Beitrag/Seite weiterleiten

add_action('template_redirect', 'redirect_single_post');
function redirect_single_post() {
if (is_search()) {
global $wp_query;
if ($wp_query->post_count == 1 && $wp_query->max_num_pages == 1) {
wp_redirect( get_permalink( $wp_query->posts['0']->ID ) );
exit;
}
}
}

Referenz

Kontaktangaben im Impressum für alle Websites zentral verwalten

Als mu-plugin realisiert wird das Impressum zentral für alle Websites einer Multisite-Umgebung nutzbar. Der Shortcode impressum integriert das Impressum. Mit der Variable impressum email=“name@tld.de“ kann die E-Mail-Adresse angepasst werden. Sinnvoll ist diese Lösung insbesondere dann, wenn über die Websites hinweg die gleichen Kontakdaten gelten. Sie kann z.B. um dann ebenfalls zentral verwaltete Datenschutzhinweise erweitert werden.

function shortcode_imprint($atts, $content = null) {
 // Die hier angegebene E-Mail-Adresse wird angezeigt, wenn die Variable email bei Eingabe des Shortcodes nicht gesetzt wird.
 extract(shortcode_atts(array( 'email' => '2013@wpdoc.de' ), $atts));
 $return = '<p>Max Mustermann<br />
 Musterstra&szlig;e 5<br />
 43524 Musterhausen<br />
 Telefon 4531 4564761<br />
 E-Mail ' . $email . '</p>';
 return $return;
 }
add_shortcode('impressum', 'shortcode_imprint');

Benutzerdefinierte Admin-Toolbar mit Abmelde-Link und Suche im Backend

Plugin zur Veränderung der Admin-Toolbar:

  • Das WordPress-Logo, das Profil-Menü und die reguläre Suchfunktion im Frontend werden entfernt
  • Eine Suchfunktion im Frontend und Backend, ein „Abmelden“-Link und ein „Profil bearbeiten“-Link unter „Meine Seiten“ werden hinzugefügt

<?php
/*
Plugin Name: Custom Adminbar
Plugin URI: https://wpdoc.de/?p=214
Description: Benutzerdefinierte Adminbar mit Abmelde-Link und Suche im Backend.
Author: Johannes Ries
Author URI: http://johannesries.de
Version: 1.0
*/

function custom_admin_bar() {
$form = '<form action="' .esc_url( admin_url('edit.php') ). '" method="get" id="adminbarsearch">';
$form .= '<input name="s" tabindex="1" type="text" value="" maxlength="54" />';
$form .= '<input type="submit" value="' .__('Search'). '"/>';
$form .= '</form>';

global $wp_admin_bar;
$wp_admin_bar->remove_menu('wp-logo');
$wp_admin_bar->remove_menu('my-account');
$wp_admin_bar->remove_menu('search');
$wp_admin_bar->add_menu( array(
'id'    => 'wp-custom-edit-profile',
'title' => 'Mein Profil bearbeiten',
'parent'=>'my-sites',
'href'  => self_admin_url('profile.php'),
'meta' => array('title' => 'Passwort, E-Mail-Adresse und weitere Details &auml;ndern')
));
$wp_admin_bar->add_node( array(
'parent' => 'top-secondary',
'id'    => 'custom-logout',
'title' => 'Abmelden',
'href'  => wp_logout_url(),
'meta' => array('title' => 'Abmelden')
) );
$wp_admin_bar->add_menu(
array(
'parent' => 'top-secondary',
'id' => 'custom-search',
'title' => $form,
'meta' => array('class' => 'admin-bar-search')
)
);
}

add_action(
'plugins_loaded',
function () {
if ( is_admin_bar_showing() ) {
add_action('wp_before_admin_bar_render','custom_admin_bar');
}
}
);
?>

RSS-Feeds deaktivieren und aus wp_head entfernen

Plugin

// Feeds deaktivieren und Fehlermeldung ausgeben
 function disable_feed() {
 wp_die( __('Für diese Website ist kein Feed verf&uuml;gbar. <a href="'. get_bloginfo('url') .'">Zur Startseite</a>.') );
 }
 add_action('do_feed', 'disable_feed', 1);
 add_action('do_feed_rdf', 'disable_feed', 1);
 add_action('do_feed_rss', 'disable_feed', 1);
 add_action('do_feed_rss2', 'disable_feed', 1);
 add_action('do_feed_atom', 'disable_feed', 1);
// Feeds aus wp_head entfernen
 remove_action( 'wp_head', 'feed_links_extra', 3 );
 remove_action( 'wp_head', 'feed_links', 2 );

Letzte Bearbeitungen Admin Dashboard Widget

Plugin

add_action( 'wp_dashboard_setup', 'dashboard_last_edits_register_dashboard_widget' );
 function dashboard_last_edits_register_dashboard_widget()
 {
 wp_add_dashboard_widget(
 __FUNCTION__, 'K&uuml;rzlich bearbeitete Inhalte', 'dashboard_last_edits_render_dashboard_widget');
 }
function dashboard_last_edits_render_dashboard_widget() { 
 $posts = get_posts(
 array ('numberposts' => 10, 'post_type' => array ( 'post', 'page' ), 'orderby' => 'modified')
 );
 if ( ! $posts )
 {
 print 'Keine Bearbeitungen gefunden. <a href="'
 . admin_url( 'post-new.php' ) . '">Einen Beitrag schreiben.</a>';
 }
 else
 {
 echo '<ul>';
 foreach ( $posts as $post )
 { printf('<li>&raquo; <a href="%1$s">%2$s</a></li>', esc_html( get_permalink( $post->ID )),
 esc_html( $post->post_title )); }
 echo '</ul>';
 }
}

Zentrale Funktionen für Sicherheit und Nutzerfreundlichkeit im WPMU-Netzwerk

Zentrale Datei mit Funktionen, die im kompletten MU-Netzwerk ausgeführt werden.

/wp-content/mu-plugins/general-security-usability.php

<?php
/*
Plugin Name: General Security &amp; Usability
Plugin URI: https://wpdoc.de/?p=81
Description: Grundlegende Einstellungen hinsichtlich Sicherheit, Nutzerfreundlichkeit und Datenschutz.
Author: Johannes Ries
Author URI: http://johannesries.de
Version: 2.1
*/

// NOBLOGREDIRECT Workaround
remove_action( 'template_redirect', 'maybe_redirect_404' );

// Kommentare ohne IP-Adresse und Cookies speichern
add_filter( 'pre_comment_user_ip', '' );
  remove_action( 'set_comment_cookies', 'wp_set_comment_cookies' );// Login-Fehlermeldung bearbeiten
  function failed_login() {
  return 'Die eingegebenen Daten sind fehlerhaft. ';
}
add_filter('login_errors', 'failed_login');

// Dashboard umbennen in Übersicht
add_filter(
'gettext', 'change_names' );
add_filter( 'ngettext', 'change_names' );
function change_names( $translated ) { $translated = str_ireplace(
'Dashboard', '&amp;Uuml;bersicht', $translated );
return $translated;}

// Bilder grundsätzlich mit Datei (nicht Anhangseite) verlinken
update_option('image_default_link_type','file');

// Leere Absätze entfernen
add_filter('the_content', 'remove_empty_p', 20, 1);
function remove_empty_p($content) {
  $content = force_balance_tags($content);
  return preg_replace('#<p>(s|&nbsp;)*+(<brs*/*>)?(s|&nbsp;)*</p>#', '', $content);
}

// Änderungsmöglichkeit für das Farbschema des Administrationsbereich entfernen
function admin_color_scheme() {
  global $_wp_admin_css_colors;
  $_wp_admin_css_colors = 0;
}
add_action('admin_head', 'admin_color_scheme');

// Aktualisierungshinweis nur für Admins in Singlesite-Umgebung bzw. nur für Superadmins in Multisite-Umgebung
add_action(
'plugins_loaded',
function () {
  if (( is_multisite() &amp;&amp; !current_user_can('manage_network') ) || ( !is_multisite() &amp;&amp; !current_user_can('create_users'))) {
  add_action( 'init', create_function( '$a', &quot;remove_action( 'init', 'wp_version_check' );&quot; ), 2 );
  add_filter( 'pre_option_update_core', create_function( '$a', &quot;return null;&quot; ) );
  add_filter( 'pre_site_transient_update_core', create_function( '$a', &quot;return null;&quot; ) );
}
}
);
?>