Bootstrap 3.3 unter Concrete 5.6

Montag, 3. November, 2014

Meine Webseite verwendet Concrete 5 als CMS.
Auf aktuelle Version 5.7 kann man dummerweise nicht upgraden, weil man im Unterbau zuviel geändert hat. Toll. Ich will einige Komponenten trotzdem aktualisieren.

Ich hatte so die famose Idee, auf meiner Webseite Bootstrap auszutauschen
VON v3.0
AUF v3.3

Der Konflikt besteht darin, dass das Backend mit Bootstrap 2 arbeitet und mit jQuery v1.7 daherkommt.

Bootstrap 3.3 braucht nun aber mind. jQuery 1.9. Mit vermeintlich gutem Gewissen habe ich die letzte 1-er Version von jquery heruntergeladen. Und mit jQuery 1.11 läuft wiederum das Bootstrap 2 Backend nicht mehr sauber.

Ein Teufelskreis ;-)

Erschwerend kommt hinzu, dass C5 das jQuery innerhalb

Loader::element('header_required');

irgendwo lädt (damit werden mehrere Html-Header Zeilen per echo rausgeschrieben).

Entweder man modifiziert Originale (davon rate ich per se ab), macht Custom-Elemente - oder ersetzt es in seinem Template. Letzters habe ich gemacht - mit Hilfe der ob_ Funktionen wird der Content abgegriffen und darin der Pfad zum jQuery File ersetzt.

        // 2014-11-01 hahn
        // HACK to use bootstrap 3.3 in live mode and concrete5 cms mode
        // --> load specific jquery version
        ob_start();
        Loader::element('header_required'); 
        $sHeadcontent = ob_get_contents();
        ob_end_clean();
        
        $u = new User();
         if (!$u->isRegistered()) {
             $sHeadcontent=str_replace(
                     '/concrete/js/jquery.js', // or '/updates/concrete[version]_updater/concrete/js/jquery.js',
                     $this->getThemePath() . '/js/jquery_1.11.1.js',
                     $sHeadcontent
             );
         }
        echo $sHeadcontent;
        // ENDE jquery HACK

Eine andere Folge des jQuery Updates war die Inkompatibilität mit colorbox (Addon Lightboxed Image - 0.9.2).
Durch Aktualisieren der Dateien unter

[webroot]/packages/lightboxed_image/blocks/lightboxed_image

mit den aktuellen colorbox-Sourcen lief auch das wieder.

Update:
Eine andere Variante (die Auswirkung auf alle Themes hätte) wäre, die Datei concrete/elements/header_required.php in das Verzeichnis elements zu kopieren und dort anzupassen. So kommt man auch ohne die ob_-Funktionen aus.

weiterführende Links:

Html5 Audio: schnelles Wiederholen eines Sounds

Donnerstag, 1. Mai, 2014

Kürzlich hatte ich etwas zur Wiederholung von loopenden HTML5 Audios geschrieben. Beim Schreiben der elektronischen Osterkarte kämpfte ich noch mit einem anderen Audio-Problem: Mit Klick auf ein Element sollte ein Sound wiedergegeben werden. Im Onclick Event eines Bildes wird nachfolgende Funktion aufgerufen. Diese holt aus einem Spielfeld-Array die Information, ob es ein neu aufgedecktes Feld ist und spielt einen entsprechenden Sound durch Ansteuern eines (in der Seite bereits vorhandenen) Audioobjektes:

function clickimage(oLink) {
    (...)
    iClickCounter++;
    var oAudio = false;
    var oField = aFields[oLink.id];
    (...)
    if (oField["active"]) {
        // scream yeah!
        (...)
        oAudio=document.getElementById("audioclickok");
        oAudio.currentTime=0;
        oAudio.play();
        (...)
    } else {
        // oh no!
        (...)
        var sSoundid=oField["done"]?"audioclickremoved":"audioclickfailed";
        oAudio=document.getElementById(sSoundid);
        oAudio.play();
        (...)
    }
    (...)
}

Hey es spielt! Aber eher schlecht als recht. Bei mehrfachen Klicks gibt es äusserst unschöne Effekte. Es hakt - die Wiedergabe ist nicht synchron.

Eine Abhilfe wäre web-API. Oder man stehert die Wiedergabe ein und desselben Audiofiles über mehrere Audio-Objekte.

Oder: man setzt vor der Play-Methode die Abspielposition auf Null.

    (...)
        oAudio=document.getElementById(sSoundid);
        oAudio.currentTime=0;
        oAudio.play();
    (...)

Der Unterschied ist wirklich frappant!

Weiterführende Links

Frohe Ostern!

Donnerstag, 17. April, 2014

Es ist wieder Ostern und wieder gibt es eine animierte Grusskarte :-)
Wem es gefällt, kann diese mit einem eigenen Titel an Freunde versenden.

Es ist ein kleines Reaktionsspiel. Nach einer zufälligen Wartezeit wird ein Feld hervorgehoben, was schnellstmöglichst angeklickt werden muss. Es wird die Zeit zusammengezählt vom Anzeigen eines Feldes bis es angeklickt wurde.

2014-04-17-osterkarte-2014.png

Schöne Feiertage!
zur Osterkarte 2014

Wie es erstellt wurde?

  • Hintergrundmusik und Sounds wurden mit Magix Music Maker erstellt.
  • Grafiken / Fotos / Scans wurden mit Paint Shop Pro montiert bzw. nachbearbeitet
  • Die Spielsteuerung erfolgt mit Javascript - jQuery nimmt mir teilweise einige Arbeiten ab. CSS 3 animiert die Boxen.

Mit dem Webbrowser kann man die Sourcen einsehen - oder mich nochmal fragen.

Weiterführende Links:

Loopende Sounds mit Html5 Audio

Montag, 14. April, 2014

Ich bin dabei, eine e-Card vorzubereiten und habe einen loopenden Song erstellt. Wenn ich diesen mit dem Audio Tag mitsamt loop Attribut einbinde:

<audio title="Hintergrundmusik" preload="auto" controls="controls" loop="loop" 
	autoplay="autoplay"
	id="audioBgSound"
	>
	<source type="audio/ogg" src="/axel/download/easter2014-bg_2.0_.ogg" >
	<source type="audio/mp3" src="/axel/download/easter2014-bg_2.0_.mp3" >
</audio>

… so gibt es am Ende des Songs immer eine kurze Pause von ein..zwei Zehntel, bevor der Song von vorn beginnt. Das ist unschön, ich wollte eigentlich einen soften Übergang ohne diese Zwangspause.

Einen Evenlistener auf “ended” zu setzen, der die Position auf 0 (Anfang) setzt, hat genau denselben Effekt, wie das Loop Attribut.

Nun habe ich eine Krüppel-Lösung hergenommen.

Mit window.setTimeout wird eine Funktion forlaufend wiederholt. Diese prüft die Position und ob das Ende “fast” erreicht ist. Fast heisst hier: Länge des Audios ([audio].duration) minus etwas Luft. Ich hab mal 0.2 Sekunden gesetzt.

/**
 * sound hook
 * @returns {undefined}
 */
function soundtrigger() {
	oAudioBgsound = document.getElementById("audioBgSound");
	iPos = oAudioBgsound.currentTime;
	if (iPos>oAudioBgsound.duration - 0.2){
		oAudioBgsound.currentTime=0;
	}
	if (iPos > (oAudioBgsound.duration - 6)) {
		window.setTimeout("soundtrigger();", 50);
	} else {
		window.setTimeout("soundtrigger();", 5000);
	}
}

Es ist echt unschön, aber falls wer was besseres weiss…

weiterführende Links:

Linkchecker auf meiner Webseite

Freitag, 14. März, 2014

Hinweis: Dieser Artikel von 2014 ist veraltet. Als Linkchecker verwende ich nun den meinen ahCrawler

In meiner alten Webseite hatte ich in externen Linkchecker direkt als Link im HTML-Code.
Im neuen CMS ist das nicht mehr so. Alle Links verweisen auf die echte Zielseite. Aber ich habe weiterhin einen Linkchecker integriert - allerdings als Javascript-Löung.

So funktioniert es:

Alle Links zeigen auf die Zielseite.

<a href="http://example.com/">Beispiellink</a>

Nun ist es so, dass ich in meinen Artikeln keinerlei externe Links verwende. Alle externen Links sind rechterhand platziert - in einem DIV namens “sbright” (”sb” für sidebar).
Alle Links in diesem Div - also nicht die auf der Seite insgesamt - werden geprüft, ob sie eine externe Referenz besitzen - falls ja, wird das Onclick Event umgebogen auf ein PHP-Skript inc_urlchecker.php. Diese Funktion nutzt jQuery:

/**
 * change external links in the sidebar: a linkchecker will be added
 * @returns {undefined}
 */
function initAddLinkchecker(){
    var sLink=false;
    $("#sbright a").each(function() {
        // do something with external links:
        if (this.href.indexOf("axel-hahn.de")<0){
            sLink=this.href;
            sLink="/axel/php/inc_urlchecker.php?url="+sLink;
            $(this).attr("onclick", "location.href='"+sLink+"'; return false;");
        }
    });
}

In jenem PHP-Skript wird der übergebene Link mit einem Http Head Request mittels Curl geprüft.

// from http://php.net/manual/en/function.get-headers.php
function get_headers_curl($url) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);

    $r = curl_exec($ch);
    $r = preg_split("/n/", $r);
    return $r;
}

Ist der Http-Response Code OK (200er und 300er Http-Statuscodes) wird der Besucher weitergeleitet. Wenn nicht, gibt es einen entsprechenden Hinweis im Webbrowser samt Entschuldigung, Fehlermeldung und Link zurück zur letzten Seite.

Ach so, und vom letzten Test eines Links wird der Response Header in eine (Sqlite) Datenbank geschrieben. Die sehe ich gelegentlich ein und weiss, welche Links ins Nirvana gehen.

Weiterführende Links:

Weihnachtskarten 2013

Samstag, 21. Dezember, 2013

Alle Jahre wieder…
Meine elektronische Weihnachtskarte ist online.

2013-12-21-weihnachtskarte.jpg

Die Karte hat als Motiv das Bundeshaus in Bern - was mir nicht neutral genug erschien, um es als versendbare Karte zu gestalten.
Aber mit dem Weihnachtsgruss von 2012 ginge dies (s. Link unten “Der schnellste Weihnachtsmann der Welt”).

Weiterhin gibt es eine Weihnachtskarte rein in Papierform:

2013-12-21-wkarte-papier.png

Weiterführende Links

  1. Weihnachtsgruss 2013 - Anm.: diese e-Card wurde vom Server gelöscht
  2. Weihnachtsgruss 2012 Der schnellste Weihnachtsmann der Welt
  3. Axels Blog Der schnellste Weihnachtsmann der Welt

Wie sowas entsteht?
[Weiterlesen…]

Browser-Surround-Test

Dienstag, 30. Juli, 2013

Mein letzter Browser Check auf Unterstützung von Surround-Wiedergabe von HTML5-Audiotags ist ca. 1 Jahr her.

Mehr oder minder zufällig habe ich die Problemkinder Firefox (Version 22) und Opera (Version 15) getestet: siehe da, in beiden kann nun 5.1 Audio wiedergegeben werden.

Yeah!

Firefox
Im Falle von Firefox war die zuletzt von mir getestete Version die Nr. 13.
canPlayType([MIME]) liefert auf Firefox 22:

  • audio/mp4 - “maybe”
  • audio/ogg - “maybe”

In surround werden sowohl OGG als auch AAC (Extension .m4a) wiedergegeben.

Opera
Opera hat mit der jetzigen Version 15 die Rendering Engine auf die des Chromium-Projektes gewechselt und verwendet für die Darstellung von Webseiten damit dieselbe, wie Google Chrome. In Opera 12 gab es vor 1 Jahr noch keinen Surround-Sound.
canPlayType([MIME]) liefert auf Opera 15:

  • audio/mp4 - “false”
  • audio/ogg - “maybe”

In surround wird OGG wiedergegeben; AAC kann nicht abgespielt werden.

AMC-Player
Wann in welchen Versionen es genau in beiden Browsern gefixt wurde, weiss ich nicht … aber egal. Ich habe meinen Html5-Player - den AMC player - auf Version 0.15 aktualisiert (*), damit man ist im Firefox die Umschaltung auf Sourround freigegeben (für Opera mit Chromium-Engine war es verfügbar). Den Html5-Player mal wieder anzuschauen, habe ich eh schon zu lange vor mir hergeschoben.

UPDATE:

  • Der AMC-Player hat die Version 1 erreicht
  • Besuche zum Selbst-Ausprobieren meine “Testseite für unterstützte Audioformate”

Weiterführende Links

Ausgabe des Blogs wurde verbessert

Montag, 22. Juli, 2013

Ein paar Kleinigkeiten verbessert man immer mal wieder hier und da …

1) Microdata eingeführt

Naja, zumindest einmal rudimentär. Vielleicht können Suchmaschinen dann etwas genauer die Bloginhalte analysieren.
Die Anpassung erfolgte in den Template-Files unter
[Flatpress-Root]/fp-interface/themes/[Theme-Name]/*.tpl
anhand des Links [01] (s.u.).

2) Filtertyp und Wert anzeigen
Wenn man im Archiv Monat/ Jahr wählte oder aber eine der Kategorieen, so war funktionell die darauffolgende Ansicht korrekt, aber es wurde in Flatpress nicht ausgegeben, dass und welche Filteraktion gerade greift. Nun wird der Anzeigemodus eingeblendet:

2013-07-22-h2-nach-datum.png 2013-07-22-h2-archiv.png 2013-07-22-h2-artikel.png
[Weiterlesen…]

Osterkarte 2013

Dienstag, 26. März, 2013

Wieder einmal rechtzeitig: Meine animierte Osterkarte mit Sound ist am Wochenende fertig geworden.

2013-03-26-osterkarte.jpg

Osterkarte anzeigen

Chrome: Abspielen mancher Ogg Files nicht möglich

Dienstag, 22. Januar, 2013

Mehr durch Zufall habe ich festgestellt: manche meiner Stereo-Ogg Files lassen sich im Chrome mit dem html5 audio player gar nicht abspielen. Firefox spielte sie allesamt klaglos.

Ich habe zwar schon als Stereo-Quelle MP3 Dateien in verschiedenen Bitraten, aber alle Ogg Files, die daraus erstellt werden, gehen vorher durch ffmpeg und werden zu PCM WAV Dateien umgewandelt.

  • Die Quelle zum Encoden nach Ogg ist somit immer WAV mit 44.1 kHz.
  • Encoder ist immmer oggenc2 - also immer derselbe Encoder und denselben Parametern.

Also habe ich irgendwann die Suche nach Encoder-Problemen aufgegeben.

Soweit ich es debuggt habe, wird im Javascript-Code das Audio Objekt erfolgreich initialisiert. Auch die Methode play() wird erfolgreich aufgerufen. Chrome macht anschliessend - was man in der Entwicklerkonsole unter Netzwerk sieht - partial Requests auf das Audiofile. Und hier bleibt er hängen: “pending” steht da im Status.

2013-01-22-chrome-html5-ogg.png

Workaround:
Was ich gefunden hab: die URLs der Audiosourcen werden um ein “?” ergänzt - und schon funktionierts im Chrome.

also ALT:

<audio>
  <source src="/data/song_2.0_.ogg" type="audio/ogg">
  <source src="/data/song_2.0_.mp3" type="audio/mp3">
  (...)
</audio>

und NEU:

<audio>
  <source src="/data/song_2.0_.ogg?" type="audio/ogg">
  <source src="/data/song_2.0_.mp3?" type="audio/mp3">
  (...)
</audio>

… und das Javascript Snippet:
aSource ist ein Array mit den Keys src (eine URL des Audios) und type (MIME Type). Wenn kein “?” in der Audio-URL vorkommt, wird dieses angefügt.

s+='<audio>';
(...)
  sourcesrc=String(aSource.src);
  if(sourcesrc.indexOf("?")<0) sourcesrc+="?";
  s+='<source src="' + sourcesrc + '" type="'+aSource.type+'">';
(...)
s+='</audio>';
(...)
document.getElementById("divaudios").innerHTML=s;

weiterführende Links