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:

Webseite umgestellt auf Concrete 5

Dienstag, 11. März, 2014

Wer ab und an auf meiner Webseite war, wird es bemerkt haben: sie sieht nun anders aus. Die bisherigen Inhalte sind (zumeist) noch da, haben aber eine neue URL.

Ich habe meine Webseite auf das CMS Conrete 5 umgestellt.

Wer eine alte Adresse ansurft …
… sei es, er wählt einen Bookmark, einen nunmehr veralteten Link aus einem Forum oder dem noch nicht aktualisierten Suchindex einer Suchmaschine, der kommt auf eine Umleitungsseite.
Diese Umleitungsseite kennt das Mapping von der alten zur neuen URL. Suchmaschinen werden sofort mit einem 30x auf die neue Seite umgeleitet (Google hat übrigens so sehr schnell gelernt!); andere Benutzer bekommen einen Hinweis und den neuen Link angeboten.

Apache-Rewrite Regel für alte Seiten:

RewriteRule ^(axel.*).html$ /(...)/redirector_phpcms.php [PT,QSA]

Wenn das Redirect-Skript einen Bot erkennt, dann gibt es statt der Hinweis-Seite ein 301:

// ----- Bots ein 30x senden
if ($sNewUrl){
    if (
            stripos($_SERVER["HTTP_USER_AGENT"], "spider")>0
            || stripos($_SERVER["HTTP_USER_AGENT"], "bot")>0
            || stripos($_SERVER["HTTP_USER_AGENT"], "wget")>0
            (...)
       ){
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: $sNewUrl");
       }
}

Warum das Ganze?
Bisher habe ich einen Parser verwendet, dessen Entwicklung seit einer gefühlten Ewigkeit eingestellt ist. Securitymässg ist das keine so tolle Ausgangslage.
Die Wahl fiel deshalb auf Concrete 5, weil ich bereits andere Webseiten damit umgesetzt habe und das Benutzerinterface beim Bearbeiten ganz nett und angenehm finde.

Was blieb gleich?
Die visuelle Menüstruktur blieb weitestgehend identisch. Die neue Webseite wurde aufgeschaltet, als ich ca. 95% der Inhalte und Funktionen drin hatte. Nur mit neuen URLs halt. Was fehlt, sind Fotos und VB-Script- und einige veraltete Javascript-Seiten.
Was sonst so gleich blieb:

  • Statistik erfolgt weiterhin mit Piwik
  • die Suche ist immernoch die von Sphider
  • mein bisheriger HTML5-Audioplayer ist integriert (AMC Player)
  • RSS News zu div. Themen werden im Hintergrund aktualisiert

Um meine Inhalte übernehmen zu können, brauchte ich unbedingt den Ersetzungsmechanismus aus dem bisherigen Parser. Dafür habe ich eine PHP-Klassse (mit Hilfe der Originalvorlage) geschrieben.

Was ist neu?
Neben dem Unterbau und den URLs (eben wg. des neuen CMS)

  • werden Elemente von Bootstrap 3 genutzt: Menüs, Icons, Tabellen und andere Elemente nutzen dieses Framwork.
  • das Layout wurde etwas frischer.
  • Seiten können Tags haben. Mit Klick auf einen Tag kommt man zu einer Suchseite, die Seiten aufzeigt, die denselben Tag verwenden.
  • Seiten-Inhalte zu verwalten ist für mich einfacher. Davon habt ihr zwar nichts direkt, aber ihr profitiert davon.

weiterführende Links

  • Concrete 5 (CMS; Opensource)
  • Matomo.org (Statistik-Tool; früher: Piwik)
  • Bootstrap (HTML-Framework)
  • http://www.sphider.eu/ - Sphider (PHP-Suchmaschine - Anm.: hat bekannte Sicherheitslücken und wird nicht mehr weiterentwickelt)
  • AMC Player (HTML5 Audioplayer für surround und stereo)
  • RSS-News (im Menü rechts dann eine Rubrik wählen)

Fundstück: Diskette

Mittwoch, 19. Februar, 2014

Es ist sooo lange her, dass ich meine ersten Programmzeilen geschrieben habe. Das war zu meinen Schulzeiten an einem 8 Bit Computer namens Z9001 und muss so 1987 herum gewesen sein.

Nach der Wende war mein erster Computer ein C-64 … im Studium mein zweiter ein PC. Nicht zuletzt wg. des Informatikkurses bin ich auf Turbo Pascal umgeswitcht und habe unter DOS programmiert. Mein DOS-Highlight war damals ein Freeware-Menüprogramm, das bei einem Programmaufruf aus dem Speicher verschwand - mit Mausunterstützung und Drag and Drop.

Und irgendwann begann MS Windows, sich durchzusetzen. Mein erstes Windows-Programm, was ich mit Delphi zu einem kompletten Projekt gemacht habe - das heisst: mit Installer und Hilfedatei und derlei Drumherum - war jenes auf diesem Plastik-Dings im Bild unten, Diskette genannt. Tja, damals hatte man an an einem Rechner diverse Schlitze, um um dieses Etwas einschieben zu können. Hach damals … *seufz*

2014-02-19-diskette.jpg

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…]

TWebbrowser meldet sich mit Trident Version 4

Donnerstag, 14. November, 2013

… obwohl der IE 10 installiert ist.

Aber mal von vorn: ich schreibe an einer Windows-Anwendung, in die ich die Komponente des Internet Explorer - eben TWebbrowser - einbinde, um Inhalte anzuzeigen. So kann man HTML und CSS zum Layouten verwenden. Klicks kann man mit seinem Programm abfangen und auswerten und so z.B. Klicks auf Links auf Routinen seiner Anwendung umbiegen.

Bei den Experimenten verhielt sich der Browser merkwürdig … bis ich per Javascript navigator.appVersion habe ausgeben lassen, was mir eine (uralte) Version 4 zum Vorschein brachte.

Natürlich war ich nicht der Erste auf der Welt, der auf dieses Problem stösst und die Suche in der unendlichen Müllhalde lies mich die Lösung finden. Welche da wäre: man muss in der Registry den Namen seiner Exe-Datei mit einer IE Version verknüpfen. Das kann man entweder in den Installer packen - oder falls es als portable Version funktionieren muss - beim Start der Anwendung ausführen.

Der Codeschnipsel, den ich in meine Anwendung gesetzt habe, sieht in Delphi so aus:

var 
    Reg: TRegistry;
begin
     Reg := TRegistry.Create;
     try
        Reg.RootKey := HKEY_CURRENT_USER;
        if Reg.OpenKey('Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION', True) then
        begin
             Reg.WriteInteger(ExtractFileName(paramstr(0)), 9999);
             Reg.CloseKey;
        end;
     finally
        Reg.Free
     end;
    (...)

Weiterführende Links

Mysql-connect sehr langsam?

Mittwoch, 28. August, 2013

Für Windows gibt es fixfertige Pakete für die Kombination Apache + Php + Mysql + X, wie z.B. XAMPP oder Wamp.

Für ein kleines Projekt habe ich auf eine solche zurückgegriffen und irgendwie war es langsam. Was genau langsam war, war nach einigem Debugging lokalisiert:

(...)
$iStart=microtime(true);
mysql_connect($hostname . ":" . $hostport, $username, $password);
echo microtime(true) - $iStart."s to open DB $database<br>";
(...)

Das mysql_connect() brauchte regelmässig 1 Sekunde - die anschliessenden Queries 0.00x Sekunden.

Ursache ist der Zugriff mit dem Hostnamen “localhost” auf die Loopback-Adresse. Wenn man den Mysql-Service auf eine IP-Adresse bindet, geht es massiv schneller. Konfiguriert wird dies in der my.ini im Installationsverzeichnis von Mysql. Oder man verbindet sich auf die IP-Adresse 127.0.0.1.
Ach, und unter Windows den Eintrag lower_case_table_names=2 nicht vergessen - daher schiebe ich es mal hinterher:

(...)
bind-address="127.0.0.1"
bind-address = ::1          # fuer ipv6
lower_case_table_names=2 
(...)

Nach Änderung der Konfiguration muss man den Mysql-Dienst neu starten, damit es wirksam wird.

Weiterführende Links:

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…]