Webdesign-Blog

Hier finden sich vor allem Tipps, Tricks und Code-Schnipsel aus unserem Arbeitsalltag, die (in der Regel) nicht dutzendfach bei Google auftauchen, wenn man danach sucht. Viel Spaß!

Tipp: Sehr gute automatische Übersetzungen mit DeepL

Die Übersetzungsautomaten von Google uns Microsoft sind ja so gut wie jedem bekannt, nicht zu letzt wegen dem einen oder anderen Lacher der aufkommt wenn man sich dort ganze (Ab)Sätze übersetzen lässt. Ganz ohne Lacher, dafür aber mit erstaunlich guten Übersetzungen überzeugt das neue Übersetzungs-Tool DeepL.

 

WordPress: Benutzer per PHP anlegen

Manchmal kommt es vor, dass man die FTP-Zugangsdaten zu einer Website hat, aber keinen WordPress-Zugang. Der Kunde kennt sich nicht aus und der Webdesigner, der die Seite mal vor langer Zeit erstellt hat, ist nicht mehr greifbar. In so einem Fall leistet diese kleine PHP-Funktion in den functions.php sehr gute Dienste:

function add_admin_user()
{
	$login = 'myself';
	$passw = 'very#secret';
	$email = 'me@example.com';

	if ( !username_exists( $login )  && !email_exists( $email ) ) {
		$user_id = wp_create_user( $login, $passw, $email );
		$user = new WP_User( $user_id );
		$user->set_role( 'administrator' );
	}
}
add_action('init','add_admin_user');

JavaScript: URL-Parameter abfragen

Mit dieser kleinen Funktion lassen sich in JavaScript URL-Parameter / Query-Strings abfragen:

// URL-Parameter abfragen
function getUrlParameterByName(name, url)
{
	if (!url) url = window.location.href;
	name = name.replace(/[\[\]]/g, "\\$&");
	var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url);
	if (!results) return null;
	if (!results[2]) return '';
	return decodeURIComponent(results[2].replace(/\+/g, " "));
}

alert(getUrlParameterByName('mein-url-parameter'));

PHP: ZIP-Archive extrahieren

Trotz immer schneller werdenden Internet-Verbindungen dauert das Hochladen von Verzeichnissen mit tausenden von Dateien und Unterverzeichnissen, wie das zum Beispiel bei kompletten WordPress-Installationen oder komplexen Themes der Fall ist, immer noch seine Zeit.

Deutlich schneller ist es, statt dessen ein ZIP-Archiv hochzuladen. Falls man auf dem Server keine SSH-Zugang hat, lässt sich die ZIP-Datei mit folgendem kleinen PHP-Skript zu extrahieren.

<?php 
// Dateiname bestimmen (muss hier im selben Verzeichnis liegen)
$file="meine-datei.zip";

// Absoluten Pfad bestimmen
$path=pathinfo(realpath($file), PATHINFO_DIRNAME);

// ZIP-Datei öffnen und prüfen
$zip=new ZipArchive;
$res=$zip->open($file);
if ($res===TRUE)
{
	// ZIP-Datei extrahieren
	$zip->extractTo($path);
	$zip->close();

	// Erfolgsmeldung
	echo("<h2>Erfolg :-)</h2>");
	echo("<p><code><strong>$file</strong></code> erforgreich in das Verzeichnis <code><strong>$path</strong></code> endpackt.</p>");
}
// Fehlermeldung
else
{
	echo("<h2>Fehler :-(</h2>");
	echo("<p><code><strong>$file</strong></code> konnte nicht geöffnet werden.</p>");
}

WordPress: Seitenweite Suche mit Omnisearch und Search Everything

Leider verfügt  WordPress über keine seitenweite Suche, die in allen Post Types gleichzeitig sucht. Das ist aber vor allem bei großen Seiten sehr praktisch. Zum Glück lässt sich diese Funktion relativ einfach mit den Plugins Jetpack Omnisearch und Search Everything nachrüsten:

Schritt 1: Jetpack installieren

Jetpack installieren und Omnisearch aktivieren:

Jetpack Omnisearch

Tipp: Man muss Jetpack nicht zwingend mit WordPress.com verbinden, Omnisearch lässt sich auch im Development Mode verwenden. Dazu einfach die Zeile define('JETPACK_DEV_DEBUG', true); in die wp-config.php einfügen.

mehr lesen…

WordPress: Standard-Editor-Farben ersetzen

Der WordPress-Editor bietet die Möglichkeit an, Texten eine Farbe zuzuweisen:

WordPress: Standard-Editor-Farben

Nur leider stimmen diese Farben natürlich nicht mit den Farben der Website überein. Mit der folgenden PHP-Funktion lassen sich die Standard-Farbwerte entsprechend den Vorgaben des Corporate Designs ändern:

function modify_colors($content)
{
	// Farben zuordnen
	$array = array (
		'#ff0000' => '#de0202',
		'#3366ff' => '#006bad'
	);

	// Farben im Inhalt suchen und ersetzen
	$content=strtr($content, $array);

	return $content;
}
add_filter('the_content', 'modify_colors');

JavaScript: Session-Daten mit JavaScript

Vor allem bei Websites mit aktivem Caching, die nicht bei jedem Aufruf dynamisch neu erstellt werden, kann es praktisch sein, Nutzereingaben mit den JavaScript-Funktionen sessionStorage.setItem() und sessionStorage.getItem() zu sichern. Hier ein einfaches Beispiel:

// Beispiel: Verwendung sessionStorage.setItem()
$('#my_alert .close').click(function() {
	sessionStorage.setItem('popup', 'closed');
});

// Beispiel: Verwendung sessionStorage.getItem()
if(sessionStorage.getItem('popup')=='closed') {
	$('#my_alert').remove();
}

jQuery: Events und Statusabfragen für responsives Webdesign

Bei der Umsetzung komplexer responsiver Webdesigns sind CSS-Media-Queries oft nicht ausreichend um alle gewünschten Änderungen zu erfassen und entsprechende Anpassungen vorzunehmen. Mit der folgenden Funktion und den dazugehörenden Events lassen sich über erweiterte Regeln das responsive Verhalten einer Website bestimmen.

Events

  • $(document).ready(): Das Document Object Model ist verfügbar.
  • $(window).load(): Die Website ist komplett geladen.
  • $(window).resize(): Die Größe des Browser-Fensters wird verändert.
  • $(window).orientationchange(): Das Gerät wird vom Quer- zum Hochformat gedreht oder umgekehrt.
  • $('form').submit(): Ein Formular wurde gesendet.
jQuery(document).ready(function($)
{
	var window_width=null;
	var window_width_old=null;

	function update_responsive_settings(mode)
	{
		// Viewport dynamisch anpassen
		viewport = document.querySelector("meta[name=viewport]");
		if(mode=='orientationchange') viewport.setAttribute('content', 'width=device-width');
		if($(window).width()>420) viewport.setAttribute('content', 'width=1100');
		
		// Breite sichern
		window_width_old=window_width;
		window_width=$(window).width();

		// Breite prüfen und falls unverändert abbrechen
		if(window_width_old==window_width) return;

		// Aktionen entsprechend Breite
		if(window_width<=420)
		{
			mobile_nav('create'); // Beispielfunktion
		}
		else
		{
			mobile_nav('remove'); // Beispielfunktion
		}

		// Aktionen entsprechend Bereite und Modus
		if(window_width<=420 && mode=='load')
		{
			$('#my_box').fadeIn();
		}
	}
	update_responsive_settings('ready');
	$(window).load(function() { update_responsive_settings('load'); });
	$(window).resize(function() { update_responsive_settings('resize'); });
	$(window).bind('orientationchange', function() { update_responsive_settings('orientationchange'); });
	$('form').submit(function() { update_responsive_settings('form_submit'); });
});

jQuery: HTML-Formular per AJAX senden

So lässt sich ein bestehendes HTML-Formular samt aller Input-Felder mit jQuery per AJAX senden:

jQuery(document).ready(function($)
{
	$("#my_form").submit(function(event) {
		// Standard-Aktion abbrechen
		event.preventDefault();	

		// Formular per AJAX senden
		var form=$(this);
		$.ajax({
			type: 'POST',
			url: form.prop('action'),
			data : form.serialize(),
			dataType: 'json',
			encode: true
		}).done(function(data) {
			// Aktionen bei Erfolg
			console.log('done: '+data);
		}).fail(function(data) {
			// Aktionen bei einem Fehler
			console.log('fail: '+data);			
		});
	});
});

PHP: Zeilenanzahl großer Dateien ermitteln

Auf Linux/Unix-Systemen lässt sich die Zeilenanzahl (sehr) großer Textdateien mit exec() und wc -l ermitteln:

$logfile_location='logs/my_logfile.txt';
if(file_exists($logfile_location)) $logfile_lines=intval(exec("wc -l ".$logfile_location));
else $logfile_lines=0;

WordPress: Sprache und Übersetzung in PHP anpassen

Die Spracheinstellungen lassen sich in WordPress nicht nur über die Einstellungen sondern auch über den Filter add_filter(‘locale’, …) in den functions.php dynamisch anpassen. Die folgende Funktion zum Beispiel setzt Französisch als Sprache für die Website wohingegen der WordPress-Adminbereich auf deutsch ausgegeben wird:

// WordPress Locale setzen
function set_locale_frontend($locale)
{
	if(is_admin()) return 'de_DE';
	else return 'fr_FR'
}
add_filter('locale', 'set_locale_frontend');

Das kann für Multisite-Übersetzungen sehr praktisch sein, wenn man den Adminbereich nicht in der Übersetzungssprache bedienen will.

Mit der Funktion load_textdomain() lässt sich wiederum eine weitere Übersetzung laden:

echo(__('Hallo Welt!', 'meine_text_domain')); // Bonjour tout le monde!

load_textdomain('medianotions', get_stylesheet_directory().'/languages/en_GB.mo');

echo(__('Hallo Welt!', 'meine_text_domain')); // Hello world!

Bezüglich erstellen und bearbeiten von Übersetzungsdateien ist das Plugin Loco Translate das Mittel der Wahl:

Loco-Translate

WordPress: robots.txt dynamisch anpassen

Die robots.txt wird in WordPress dynamisch erzeugt. Die einfachste Möglichkeit diese anzupassen ist, eine statische robots.txt in das Root-Verzeichnis der WordPress-Installation anzulegen. Die andere, flexiblere Möglichkeit ist in der functions.php mit folgendem Filter zu arbeiten:

// robots.txt anpassen
function robots_mod( $output, $public )
{
	if($public)
	{
		$output .= "Allow: /*.js$\n";
		$output .= "Allow: /*.css$\n";
	}
	
	return $output;
}
add_filter('robots_txt', 'robots_mod', 10, 2);

Damit ist es möglich die Ausgabe der robots.txt mit einer eigenen Logik zu verknüpfen:

// robots.txt anpassen
function robots_mod( $output, $public )
{
	if($_SERVER['HTTP_HOST']=='hide-from-search-engines.com') $output = "Disallow: /\n";
	
	return $output;
}
add_filter('robots_txt', 'robots_mod', 10, 2);

Performance-Tipp: Die robots.txt wird von Suchmaschinen zum Teil sehr oft aufgerufen. Falls das verwendete Caching-Plugin die robots.txt nicht abdeckt und man keine dynamische Anpassung benötigt, bietet es sich an die robots.txt als statische Text-Datei im Webroot-Verzeichs zu hinterlegen.

PHP: Mit strpos_all() alle Vorkommnisse in einem String finden

Mit dieser Funktion lassen sich alle Vorkommnisse in von $needle in $haystack finden. Zurückgegeben wird ein Array mit den Positionen:

function strpos_all($haystack, $needle)
{
	$lastPos = 0;
	$positions = array();

	while (($lastPos = strpos($haystack, $needle, $lastPos))!== false) {
	    $positions[] = $lastPos;
	    $lastPos = $lastPos + strlen($needle);
	}

	return $positions;
}

// Aufruf
$str_positions=strpos_all('a', 'abcd ab abcdefg abcde');

Website-Zoom mit jQuery und CSS

Mit der CSS-Eigenschaft transform: scale() und etwas jQuery lässt sich ziemlich gut das ein- und auszoomen einer Website simulieren. Das ist für alle praktisch, die Ihren Benutzern entsprechende Buttons auf ihrer Website anbieten wollen. Hier unsere Lösung:

<!-- Trigger -->
<ul id="zoom_triggers">
	<li><a id="zoom_in">Vergrößern</a></li>
	<li><a id="zoom_out">Verkleinern</a></li>
	<li><a id="zoom_reset">Zurücksetzen</a></li>
</ul>

<script>
	jQuery(document).ready(function($)
	{
		// Zoom-Level setzen
		var zoom_level=100;

		// Click-Events
		$('#zoom_in').click(function() { zoom_page(10, $(this)) });
		$('#zoom_out').click(function() { zoom_page(-10, $(this)) });
		$('#zoom_reset').click(function() { zoom_page(0, $(this)) });

		// Zoom-Funktion
		function zoom_page(step, trigger)
		{
			// Nur zwei Schritte ein- beziehungsweise ausblenden
			if(zoom_level>=120 && step>0 || zoom_level<=80 && step<0) return;

			// Zoom berechnen / zurücksetzen
			if(step==0) zoom_level=100;
			else zoom_level=zoom_level+step;
			
			// Zoom per CSS setzen
			$('body').css({
				transform: 'scale('+(zoom_level/100)+')', // Zoom anpassen
				transformOrigin: '50% 0' // Ausgangspunkt für transform scale setzen
			});

			// Seitenbreite am Zoom anpassen
			if(zoom_level>100) $('body').css({ width: (zoom_level*1.2)+'%' });
			else $('body').css({ width: '100%' });

			// Trigger deaktivieren / aktivieren (per CSS entsprechend optisch kennzeichnen)
			if(zoom_level>=120 || zoom_level<=80) trigger.addClass('disabled');
			else trigger.parents('ul').find('.disabled').removeClass('disabled');
			if(zoom_level!=100) $('#zoom_reset').removeClass('disabled');
			else $('#zoom_reset').addClass('disabled');
		}
	});
</script>

PHP: file_put_contents() via FTP mit ftp_file_put_contents()

Mit dieser Funktion lässt sich ein PHP-String als Datei via FTP-Verbindung sichern:

function ftp_file_put_contents($remote_file, $file_string)
{
	// FTP-Zugangsdaten
	$ftp_server="mein-ftp-server.de"; 
	$ftp_user_name="mein-benutzername"; 
	$ftp_user_pass="mein-passwort";

	// Temporäre Datei aus dem Filestring erstellen
	$local_file=fopen('php://temp', 'r+');
	fwrite($local_file, $file_string);
	rewind($local_file);       

	// FTP-Verbindung aufbauen
	$ftp_conn=ftp_connect($ftp_server); 

	// FTP-Login
	@$login_result=ftp_login($ftp_conn, $ftp_user_name, $ftp_user_pass); 

	// FTP-Upload
	if($login_result) $upload_result=ftp_fput($ftp_conn, $remote_file, $local_file, FTP_ASCII);

	// Fehlerprüfung
	if(!$login_result or !$upload_result)
	{
		echo('

FTP-Fehler: Datei konnte nicht geschrieben werden.

'); } // FTP-Verbindung beenden ftp_close($ftp_conn); // Datei-Handle Temporäre-Datei schließen fclose($local_file); } // Aufruf ftp_file_put_contents('meine-datei.txt', 'Dieser Inhalt wird in die Textdatei geschrieben.');

PHP: XSS-Attacken auf bestehenden Websites verhindern

Eine bestehende, eventuell komplexere Website nachträglich vor Cross-Site-Scripting-Attacken (XSS) zur sichern, kann sich als sehr aufwändig erweisen. Mit diesem PHP-Skript, dass bei jedem Aufruf der Website vor allen anderen Funktionen ausgeführt werden sollte, lassen sich die meisten Angriffsszenarien entschärfen.

function xss_protect($string)
{
	// nur Strings prüfen
	if(!is_string($string)) return $string;

	// eventuelle Kodierung berücksichtigen
	$string=urldecode($string);

	// Ausführbaren Code entfernen
	$string=strip_tags($string);
	$string=htmlspecialchars($string);		
	$string=filter_var($string, FILTER_SANITIZE_STRING);		

	return $string;
}
if(is_array($_GET)) $_GET = array_map("xss_protect", $_GET);
if(is_array($_POST)) $_POST = array_map("xss_protect", $_POST);
if(is_array($_REQUEST)) $_REQUEST = array_map("xss_protect", $_REQUEST);
$_SERVER['REQUEST_URI'] = array_map("xss_protect", $_SERVER['REQUEST_URI']);
$_SERVER['REDIRECT_QUERY_STRING'] = array_map("xss_protect", $_SERVER['REDIRECT_QUERY_STRING']);
$_SERVER['QUERY_STRING'] = array_map("xss_protect", $_SERVER['QUERY_STRING']);

HTML: Automatische Vervollständigung (Autocomplete) von Formularen deaktivieren

Bei Formularen mit sensiblen Daten ist es sinnvoll die automatische Vervollständigung (Autocomplete) durch den Browser zu unterbinden. Das kann mit dem Attribut autocomplete erreicht werden:

<!--  Autocomplete für das gesamte Formular deaktivieren -->
<form action="mein-formular.php" method="post" autocomplete="off">

<!--  Autocomplete für ein einzelnes Feld deaktivieren -->
<input type="text" name="IBAN" value="<?=$_POST&#91;'IBAN'&#93;?>" autocomplete="off">

WordPress: Menüeinträge im WordPress-Admin ausblenden

Wer bestimmte Menüeinträge im WordPress-Admibereich ausblenden möchte, weil die Funktionen nicht gebraucht werden, kann dies mit folgender Aktion in der functions.php umsetzen:

// Menüeinträge ausblenden
function modify_menus()
{
	// remove_menu_page( 'index.php' );                  // Dashboard
	// remove_menu_page( 'edit.php' );                   // Posts
	// remove_menu_page( 'upload.php' );                 // Media
	// remove_menu_page( 'edit.php?post_type=page' );    // Pages
	remove_menu_page( 'edit-comments.php' );             // Comments
	// remove_menu_page( 'themes.php' );                 // Appearance
	// remove_menu_page( 'plugins.php' );                // Plugins
	// remove_menu_page( 'users.php' );                  // Users
	// remove_menu_page( 'tools.php' );                  // Tools
	// remove_menu_page( 'options-general.php' );        // Settings
  
}
add_action( 'admin_menu', 'modify_menus', 999 );

In diesen Beispiel werden die Kommentare aus dem Menü entfernt.

WordPress: Browser und OS als CSS-Klassen im Body-Tag

Zum Glück benötigt man als Web-Entwickler Browser-Weichen mittlerweile nicht mehr so oft wie früher. Trotzdem kommt es immer noch vor, dass Darstellungsunterschiede angepasst werden müssen. Mit diesen beiden Funktionen in der functions.php lassen sich die wichtigsten Browser und Betriebssysteme als CSS-Klassen in den Body-Tag einbinden:

// Client-Eigenschaften bestimmen
function detect_client_properties()
{
	// Client: Browser
	if(!isset($_SESSION['CLIENT_BROWSER']))
	{
		if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7')) $browser='ie_7';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 8')) $browser='ie_8';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 9')) $browser='ie_9';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 10')) $browser='ie_10';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') and strpos($_SERVER['HTTP_USER_AGENT'], 'rv:11')) $browser='ie_11';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome')) $browser='chrome';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')) $browser='safari';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox')) $browser='firefox';
		else $browser=false;

		if($browser) $_SESSION['CLIENT_BROWSER']=$browser;
		else $_SESSION['CLIENT_BROWSER']=false;
	}		

	// Client: Betriebssystem
	if(!isset($_SESSION['CLIENT_OS']))
	{
		if(strpos($_SERVER['HTTP_USER_AGENT'], 'Macintosh')) $os='mac';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Windows')) $os='win';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone')) $os='ios';
		elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'iPad')) $os='ios';
		else $os=false;

		if($os) $_SESSION['CLIENT_OS']=$os;
		else $_SESSION['CLIENT_OS']=false;
	}

	// Client: Mobile
	if(!isset($_SESSION['CLIENT_IS_MOBILE']))
	{
		if(wp_is_mobile()) $_SESSION['CLIENT_IS_MOBILE']=true;
		else $_SESSION['CLIENT_IS_MOBILE']=false;
	}
}
add_action('init', 'detect_client_properties', 0);

// Body-CSS-Klassen ergänzen
function additional_body_classes($classes)
{
	// Browser
	if($_SESSION['CLIENT_BROWSER']) $classes[]=$_SESSION['CLIENT_BROWSER'];

	// Betriebssystem
	if($_SESSION['CLIENT_OS']) $classes[]=$_SESSION['CLIENT_OS'];

	// Mobile
	if($_SESSION['CLIENT_IS_MOBILE']) $classes[]='mobile';

	return $classes;
}
add_filter('body_class', 'additional_body_classes', 99);

Auf ähnliche Weise lassen sich auch weitere CSS-Klassen im Body-Tag einfügen, zum Beispiel die aktuelle Sprache bei mehrsprachigen Websites oder aktuelle Kategorien, Templates, Parent-Seite usw.

WordPress: Eigene Bildgrößen definieren

Mit diesen beiden Filteraufrufen in der functions.php lassen sich eigene Bildgrößen für die WordPress-Medien definieren. Mit der ersten Funktion add_image_sizes($sizes) wird die neue Bildgröße angelegt und mit der zweiten Funktion add_image_sizes($sizes) zur Bildgrößenauswahl hinzugefügt:

// Bildgrößen: Eigene Größen definieren
function add_image_sizes($sizes)
{
	add_theme_support('post-thumbnails');
	add_image_size('content_width', 800, 500, true);
}
add_filter('init', 'add_image_sizes');

// Bildgrößen: Eigene Namen definieren
function set_image_sizes($sizes)
{
	// Bildgrößen zur Auswahl hinzufügen
	$custom_image_size_names=array(
		"content_width" => __("Inhalt")
	);

	// Vorhandene Namen ergänzen
	return array_merge($sizes, $custom_image_size_names);
}
add_filter('image_size_names_choose', 'set_image_sizes');

Eigene Bildgrößen definieren in WordPress

PHP: HTTP / HTTPS bestimmen

Update 26. Mai 2014: Der Server-Port für HTTPS-Verbindungen muss je nach Server-Konfiguration nicht zwingend 443 sein.

So lässt sich mit PHP bestimmen ob eine Website über HTTP oder HTTPS aufgerufen wird:

// HTTP / HTTPS bestimmen
if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS']!='off' or $_SERVER['SERVER_PORT']==443) $protocol='https';
else $protocol='http';

WordPress: Shortcodes in Zusammenfassungen und Widgets ausführen

Mit diesen beiden Filteraufrufen in der functions.php werden Shortcodes auch in Beitrags­zusammen­fassungen und Widgets ausgeführt:

// Shortcodes in der Zusammenfassung ausführen
add_filter('the_excerpt', 'do_shortcode');

// Shortcodes in Widgets ausführen
add_filter('widget_text', 'do_shortcode');

Tipp: Syntax-Highlighting für WordPress mit PRISM

syntax-highlighting-fuer-wordpress-mit-prism

PRISM ist wohl eines der besten Syntax-Highlighting-Tools und lässt sich leicht in WordPress integrieren:

functions.php

function my_theme_resources()
{
    // Prism laden | http://prismjs.com
    wp_enqueue_style('prism-css', get_stylesheet_directory().'/libs/prism/prism.css');
    wp_enqueue_script('prism-js', get_stylesheet_directory().'/libs/prism/prism.js');
}
add_action('wp_enqueue_scripts', 'my_theme_resources');

WordPress-Texteditor

<pre><code class="language-php">
// PHP-Beispiel-Code
$prism=true;</code></pre>

WordPress: P-Tags um Shortcodes entfernen

Mit dieser kleinen Funkton in der functions.php lassen sich die P-Tags um und die BR-Tags nach Shortcodes entfernen, hier mit Filter für den Post-Inhalt und den Advanced Custom Fields WYSIWYG-Editor:

function shortcode_paragraph_fix($content)
{ 
    // Suchen und Ersetzen Strings festlegen
    $array = array (
        '<p>[' => '[', 
        ']</p>' => ']', 
        ']<br />' => ']'
    );

    return strtr($content, $array);
}
add_filter('the_content', 'shortcode_paragraph_fix');
add_filter('acf/load_value/type=wysiwyg', 'shortcode_paragraph_fix');

Alternativ lässt sich die Funktion manuell auf Inhalts-Strings anwenden die Shortcodes enthalten.

Gravity Forms: deutsche Lokalisierung für die Datumsauswahl (Datepicker)

Für alle die ein Gravity-Forms Datumsfeld (Datepicker) verwenden und diesen aber nicht mit der englischen Lokalisierung belassen wollen, gibt es eine einfache Lösung. Gravity Forms nutzt den jQuery-Datepicker mit Lokalisierungen für viele Sprachen. Also einfach jQuery-Datepicker laden und die entsprechende Lokalisierungsdatei mit wp_enqueue_script() im Theme einbinden:

function my_theme_resources()
{
    // jQuery UI Datepicker-Lokalisierung laden
    wp_enqueue_script('jquery-ui-datepicker-de', get_stylesheet_directory().'/libs/jquery.ui.datepicker-de.min.js', array('jquery-ui-datepicker'));
}
add_action('wp_enqueue_scripts', 'my_theme_resources');

WordPress: Beitragsdatum außerhalb des Loops

So lässt sich das Datum eines Beitrags auch außerhalb der WordPress-Loop entsprechend der Datumskonfiguration in PHP abrufen:

$datum=get_the_time(get_option('date_format'), $post->ID);

Sticky-Header mit jQuery

Mit dieser kleinen JavaScript/jQuery-Funktion lässt sich der Website-Header in einen Sticky-Header verwandeln. Beim Scrollen über eine bestimmte Position wird dynamisch eine .sticky CSS-Klasse hinzugefügt, der dann per CSS beliebige Eigenschaften zugewiesen werden können. Natürlich funktioniert das auch mit beliebigen anderen HTML-Elementen.

JavaScript/jQuery

jQuery(document).ready(function($) {

    function sticky()
    {
        var window_top=$(window).scrollTop();
        var top_position=$('body').offset().top;
        var element_to_stick=$('#header');
        
        if (window_top > top_position) {
            element_to_stick.addClass('sticky');
        } else {
            element_to_stick.removeClass('sticky');
        }
    }
    $(window).scroll(sticky);
    sticky();
    
});

CSS

#header.sticky
{
    position: fixed;
}

WordPress: nach Dateinamen in den Medien suchen

WordPress berücksichtigt leider keine Dateinamen bei der Suche in den Medien.

WordPress: Nach Dateinamen in den Medien suchen

Mit dieser PHP-Funktion in der functions.php lässt sich die Mediensuche erweitern:

// Nach Dateinamen in der Mediathek suchen
function posts_search_media_filenames($search, $a_wp_query) 
{
    global $wpdb, $pagenow;

    // Only Admin side && Only Media Library page
    if ( !is_admin() && 'upload.php' != $pagenow ) return $search;

    // Original search string:
    // AND (((wp_posts.post_title LIKE '%search-string%') OR (wp_posts.post_content LIKE '%search-string%')))
    $search = str_replace(
        'AND ((', 
        'AND (((' . $wpdb->prefix . 'posts.guid LIKE \'%' . $a_wp_query->query_vars['s'] . '%\') OR ', 
        $search
    ); 

    return $search;
}
add_filter('posts_search', 'posts_search_media_filenames', 10, 2);