Schlagwort: Wordpress

JQuery UI dialog in WordPress

23. August 2011 - JavaScript, wordpress

Für ein eiliges Kundenprojekt mußten  die Sponsoren eines gespendeten Fahrzeugs auf der Sponsorenliste hervorgehoben werden. Standard war bei der Sponsorengruppe: per Popup. Ich habe mich dann für den jQuery UI dialog entschieden und hier sind meine Erfahrungen dazu.

English summary: In the following I wrap up my experiences with jQuery UI dialog in a WordPress environment.

Solide Grundlage zur Lösung der Anforderung ist wie oft ein Plugin. Hier bringt man den php Code unter und kann die Javascript Programme so eintüten, dass sie nicht auf jeder Seite geladen werden.

Die ersten Zeilen des Plugins sehen etwa so aus:


if ( !class_exists('xxxxSponsoren') ) {
class xxxxSponsoren{
         function xxxxSponsoren() {
                add_action('wp_print_scripts', array (&$this,'sponsoren_scripts'));
                add_action('wp_print_styles', array (&$this, 'sponsoren_styles'));

         }
         function sponsoren_scripts() {

           if (is_page('sponsoren')) {
             wp_register_script('show_sponsoren', WP_PLUGIN_URL.'/sponsoren/js/show_sponsoren.js', array('jquery', 'jquery-ui-core', 'jquery-ui-dialog'),false,true);
             wp_enqueue_script('show_sponsoren');
          }
         }
         function sponsoren_styles() {
            if (is_page('sponsoren')) {
              wp_register_style('nf_dialog',WP_PLUGIN_URL.'/sponsoren/css/jquery-ui-1.8.16.custom.css');
              wp_enqueue_style('nf_dialog');
           }
         }
.....

Die grundlegenden Javascript Dateien jquery , jquery-ui-core, jquery-ui-dialog sind in WordPress vorhanden und werden automatisch in die Seite inkludiert, wenn man beim Registrieren der eigenen js Datei (hier: show_sponsoren.js) die Abhängigkeiten angibt.

Seltsamerweise trifft das für die Stylesheets nicht zu, und ohne diese ist das Ergebnis sehr schrecklich und entmutigend.  Das WordPress Stylesheet zum UI Dialog ist vollkommen unbrauchbar. Im Internet gibt es verschiedene Quellen , z.B. http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css oder auch Einzelhinweise zum css.

Um es kurz zu machen: man braucht

  • das gesamte css zu UI und nicht nur das für den Dialog (d.h. anstelle von 3k css 32k css)
  • und alle icons dazu (sonst sieht es ebenfalls schrecklich und entmutigend aus)

Am Ende habe ich mir von http://jqueryui.com/ das gesamte Bundle geholt und das css mitsamt den Icons lokal im Plugin abgelegt; die Version ist  jquery-ui-1.8.16.custom.css

Netterweise sah das Ergebnis bei jedem css Versuch anders aus. Im letzten Fall ist der Dialog orange. Wenn man gezielt ein css-Theme auswählen möchte, sollte man das css von Google holen. Dort sind alle Themes erhältlich. Das „Orangene“ ist ui-lightness 🙂

Der Rest ist einfacher: man legt die anzuzeigenden Daten unsichtbar mit display: none und einer passenden id (hier: id=“spon_li“) auf der Webseite ab und braucht dann nur noch ein kurzes js Script (hier:show_sponsoren.js)


jQuery(document).ready(function() {
     jQuery("[title*=danken]").click(function() {
     jQuery("#spon_li").dialog({
        width: 600,
        resizable: true,
        title: 'Die Sponsoren für unseren neuen Transporter',
        position: 'center'
});

return false;
});

In der zweiten Zeile wird ein Bild gesucht (und hoffentlich auch  gefunden), dessen ‚title=‘ den String „danken“ enthält. Wenn man auf dieses Bild clickt wird der Dialog aktiviert, hier mit Optionen wie einem Titel, einer Position usw.

WordPress: farbige Hintergründe und Hintergrundbilder auf Seiten und im Editor

8. April 2011 - tinymce, wordpress

Der Kunde erstellt seine Seiten selbst und wünscht ein einfaches Verfahren für farbige Hintergründe und Hintergrundbilder auf seiner Website.

English Summary: Though WordPress claims to be a CMS, some basic functions are not yet supported. If a customer demands background color or background images on pages, you have to add some php functionality…

Manchem grausts, aber wenn der Kunde es so will: Farbe muß her und auch Bilder.

Die Lösung war: beim Anlegen einer Seite wird der Dialog bei „Seite erstellen“  um ein paar Felder für die Hintergrundfarbe, das Bild und die Behandlung des Bildes (kacheln z.B.) erweitert.

Wie das geht,  steht in diesem Artikel:

WordPress image uploaders in admin

Die Einstellungen speichere ich in einer eigenen Tabelle in der Datenbank, alternativ kann man das auch über die custom fields lösen.

Die Templates für die Seiten müssen nun so erweitert werden, dass beim Aufruf einer Seite per style Farben und Bilder passend ausgegeben werden. Dazu muß man im Template die richtige Stelle erwischen. Bei meinen Seiten war die: <div id=main ….. >.

An dieser Stelle wird die Funktion nf_background() aufgerufen. Sie holt die Informationen aus der Datenbank und verwandelt sie in style= Befehle für html.


<?php
 /*
  Template Name: Seite_ohne_Kommentare
  */
 ?>
 <?php
 get_header();
 $bg_style='';
 if ( function_exists('nf_background') ) {
  $bg_style=nf_background();
  //echo "<p> bg: $bg_style</p>";
 }?>
 <div id="main"<?php echo $bg_style;?>>
         <div id="col1">

Hier ist ein Listing dazu:


function nf_background() {
 global $wpdb;
 global $post;
 $bcolor=false;
 $bimage=false;
 $bimage_pos=false;
 $bimage_beh=false;
 $style_string="";
 $bcolor = $wpdb->get_var($wpdb->prepare("SELECT hintergrundfarbe FROM stueckinfo WHERE post_id = %s and valid='yes'",$post->ID));
 if (!empty ($bcolor)) {
 if (preg_match('/^[0-9A-Fa-f]{6}$/',$bcolor)) {
 $bcolor ="#".$bcolor;
 }

}
 $bimage = $wpdb->get_var($wpdb->prepare("SELECT hintergrund_bild_link FROM stueckinfo WHERE post_id = %s and valid='yes'",$post->ID));
 if (!empty ($bimage)) {
 $bimage_pos = $wpdb->get_var($wpdb->prepare("SELECT hintergrund_bild_position FROM stueckinfo WHERE post_id = %s and valid='yes'",$post->ID));
 $bimage_beh = $wpdb->get_var($wpdb->prepare("SELECT hintergrund_bild_behandlung FROM stueckinfo WHERE post_id = %s and valid='yes'",$post->ID));
 }
 if ((!$bcolor) && (!$bimage)) return "";
 $style_string="style=\"";
 if ($bcolor) $style_string .= " background-color: $bcolor; ";
 if (!$bimage) {
 $style_string .="\"";
 return $style_string; }
 else {
 $style_string .=" background-image: url($bimage);";
 if ($bimage_pos) {
 switch ($bimage_pos) {
 case 1:
 $style_string .= "background-position: top left;";
 break;
 case 2:
 $style_string .= "background-position: top center;";
 break;
 case 3:
 $style_string .= "background-position: top right;";
 break;
 case 4:
 $style_string .= "background-position: center left;";
 break;
 case 5:
 $style_string .= "background-position: center center;";
 break;
 case 6:
 $style_string .= "background-position: center right;";
 break;
 case 7:
 $style_string .= "background-position: bottom left;";
 break;
 case 8:
 $style_string .= "background-position: bottom center;";
 break;
 case 9:
 $style_string .= "background-position: bottom right;";
 break;
 }
 }
 if ($bimage_beh) {
 switch ($bimage_beh) {
 case 1:
 $style_string .= "background-repeat: no-repeat;";
 break;
 case 2:
 $style_string .= "background-repeat: repeat;";
 break;
 case 3:
 $style_string .= "background-repeat: repeat-x;";
 break;
 case 4:
 $style_string .= "background-repeat: repeat-y;";
 break;
 }
 }
 $style_string .="\"";
 return $style_string;
 }

}

So far, so good. Leider muß jetzt aber auch noch tinymce mitspielen, weil man sonst die Seiten nicht richtig gestalten kann. Dafür sorgt dann dieses jQuery Script:


jQuery(window).load(function () {make_my_background();
 });

jQuery(document).ready(function() {
 jQuery('#hintergrundfarbe').click( function() {
 make_my_background();
 });
 jQuery('#hintergrund_bild_link_uebernehmen').click( function() {
 make_my_background();
 });
 jQuery('#hintergrund_bild_position_uebernehmen').click( function() {
 make_my_background();
 });
 jQuery('#hintergrund_bild_behandlung_uebernehmen').click( function() {
 make_my_background();
 });
 });

function make_my_background() {
 if (jQuery('#valid').attr('checked')){ // Anzeige nur wenn das valid -Häkchen gesetzt wurde
 var tf=jQuery('#hintergrundfarbe').val();
 if (tf != '') jQuery('#content_ifr').contents().find("body#tinymce").css("background-color",tf);
 var ti=jQuery('#hintergrund_bild_link').val();
 if (ti != '') {
 ti="url("+ti+")";
 jQuery('#content_ifr').contents().find("body#tinymce").css("backgroundImage",ti);
 var tp=jQuery('#hintergrund_bild_position').val();
 if (tp != '') {
 var bpos='';
 tp *=1;
 switch (tp) {
 case 1: bpos="top left";
 break;
 case 2: bpos="top center";
 break;
 case 3: bpos="top right";
 break;
 case 4: bpos="center left";
 break;
 case 5: bpos="center center";
 break;
 case 6: bpos="center right";
 break;
 case 7: bpos="bottom left";
 break;
 case 8: bpos="bottom center";
 break;
 case 9: bpos="bottom right";
 break;
 }
 if (bpos != '') {
 jQuery('#content_ifr').contents().find("body#tinymce").css("backgroundPosition",bpos);
 //alert("bgpos: "+ bpos);
 }
 }
 }
 var tb=jQuery('#hintergrund_bild_behandlung').val();
 //alert("bg_tb: "+ tb);
 if (tb != '') {
 var bbeh='';
 tb *=1;
 switch (tb) {
 case 1: bbeh="no-repeat";
 break;
 case 2: bbeh="repeat";
 break;
 case 3: bbeh="repeat-x";
 break;
 case 4: bbeh="repeat-y";
 break;</span>

}
 if (bbeh != '') {
 jQuery('#content_ifr').contents().find("body#tinymce").css("backgroundRepeat",bbeh);
 //alert("bgbeh: "+ bbeh);
 }
 }
 }
 }

Die Hauptfunktion make_my_background()  ist wie die php Funktion aufgebaut, bezieht ihre Daten aber nicht aus der Datenbank sondern aus den oben erwähnten Zusatzfeldern, die ja beim Gestalten der Seite zur Verfügung stehen.

Interessant ist, wo man die Styles hinpacken muß:

jQuery('#content_ifr').contents().find("body#tinymce").css("background-color",tf);

jQuery(document).ready hat bei mir nicht funktioniert. Da war der tinymce iframe noch nicht anwesend, deswegen

jQuery(window).load(function ()

Die anderen Funktionen dienen dazu, dass man bei dynamisch veränderten Farben oder Bildern die Wirkung im Editor gleich beurteilen kann.

Und so könnte es  aussehen:

WordPress media uploader in admin

30. März 2011 - JavaScript, wordpress

(Anmerkung 1/2013: Für WordPress > 3.4  siehe http://www.it-in-a-box.com/2013/01/wordpress-3-5-neuer-media-uploader-in-admin/)

(Anmerkung 11/2012: wenn ihr zu diesem Thema dazu Fragen habt und mehr (oder bessere) Informationen braucht, schreibt mir einen Kommentar)

Per heute (WordPress 3.4) gibt es leider immer noch kein offizielles Interface  für den WordPress Media Uploader, mit dem der tinyMCE Editor „angereichert“  ist. Wenn man eine ähnliche Funktionalität (die vorgestellte Lösung gilt nur für Bilder)  im admin einsetzen will, muss man etwas hacken. Dazu benötigt man ein paar Zeilen Javascript.

English Summary: As of today (WordPress 3.4), there is no WordPress supported interface to the WordPress media uploader (supplement to tinyMCE). To use it anyway in your admin pages (this solution only works for images), you need to write a few lines of Javascript.

Der erste Ansatz für den Hack stand bei Matt. Leider funktionierte dort das Rückschalten nicht: wenn man den neuen zusätzlichen uploader verwendet hatte, konnte man in tinyMCE keine Bilder mehr laden.

Ein verbessertes Script ist dieses:

jQuery(document).ready(function() {

window.original_send_to_editor = window.send_to_editor;
 window.send_to_editor_clone1 = function(html){  // ohne html bekommt die Funktion den falschen frame
 jQuery('#bild_link').val(jQuery('img',html).attr('src'));
 tb_remove();
 };
 window.send_to_editor_clone2 = function(html){
 jQuery('#hintergrund_bild_link').val(jQuery('img',html).attr('src'));
 tb_remove();
 };

 jQuery('#content-add_media').click(function() {
/*jQuery('#add_image').click(function() { wordpress bis 3.2 */
 window.send_to_editor=window.original_send_to_editor;
 tb_show('', 'media-upload.php?type=image&TB_iframe=true');
 return false;
 });

jQuery('#bild_link_button').click(function() {
 window.send_to_editor=window.send_to_editor_clone1;
 tb_show('', 'media-upload.php?type=image&TB_iframe=true');
 return false;
 });
 jQuery('#hintergrund_bild_link_button').click(function() {
 window.send_to_editor=window.send_to_editor_clone2;
 tb_show('', 'media-upload.php?type=image&TB_iframe=true');
 return false;
 });
 });

Und so sieht es aus:

 

Die WP- Funktion „window.send_to_editor“ wird gespeichert und beim Klick auf einen der Upload-Buttons (IDs #bild_link_button bzw. #hintergrund_bild_link_button) durch eine neue Funktion ersetzt. In der neuen Funktion wird die Thickbox  mit dem bekannten Upload-Dialog aufgerufen. Anschließend holt man aus dem iframe der Thickbox den Namen des Bildes und trägt ihn in das Textfeld ein.

Wenn man den Uploader im tinyMCE nutzen will, wird die alte „window.send_to_editor“ Funktion wieder hergestellt (Click-Event auf #content-add_media)

Nachteil: es ist ein Hack und kann bei der nächsten WP Version nicht mehr funktionieren. Inklusive WP 3.4 ist aber alles ok.

Für jeden Uploader musste ich oben im Script eine neue Funktion definieren . JS Gurus werden das sicherlich verbessern können 🙂

Noch mal zur Übersicht:

#bild_link_button und #hintergrund_bild_link_button  sind die IDs der „Upload“ Buttons
#bild_link und #hintergrund_bild_link sind die IDs der Textfelder darüber , in die der Link  hineingeschrieben wird

#content-add_media ist die ID des WordPress Upload Buttons über dem Editor

bis Version 3.2 hiess diese ID #add_image