Donnerstag, 29. März 2012

Even more new SenSEO features

New SenSEO version brings some more new features.

Check for Last-Modiefied header

Google says: "Make sure your web server supports the If-Modified-Since HTTP header. This feature allows your web server to tell Google whether your content has changed since we last crawled your site. Supporting this feature saves you bandwidth and overhead."

Webmaster Guidelines

  • Check for Content-Type header
  • Find alternative sitemap.xml path in robots.txt
  • Improved highlight feature
  • Some bugfixes


The features will be available with the next SenSEO version 2.4.

If you find bugs or have suggestions please post them at Get Satisfaction.

New SenSEO feature: Compare inspect results

With the new version of SenSEO you are able to save an inspect result and compare it with the result of an other page.

Compare inspect results

The feature will be available with the next SenSEO version 2.4.

If you find bugs or have suggestions please post them at Get Satisfaction.

New SenSEO feature: Pages crawler

The pages crawler extracts all URLs from sitemap.xml and crawls these URLs. It ranks the pages based on the first keyword in keywords metatag.

Klick image to view screenshot:



The ranking takes these rules into account:

  • URL contains main keyword: +1
  • Title exists: +1
  • Title contains main keyword: +1
  • Description exists: +1
  • Description contains main keyword: +1

The crawling result is rendered into a table and will be available as an CSV export. For each page you can directly jump into the SenSEO inspect or components view.

The feature will be available with the next SenSEO version 2.4.

If you find bugs or have suggestions please post them at Get Satisfaction.

Sonntag, 5. Februar 2012

New SenSEO version is coming

In the next days I will finish work on a completely refactored version of SenSEO.

SenSEO will bootstrap

SenSEO will no longer integrate into Firebug but will be, what Mozilla calls, a bootstrapped add-on.

Bootstrapped add-ons are a special kind of add-on that developers can choose to use instead of normal add-ons in order to allow users to install and use the add-on without needing to restart the application.

New features will come along



Some preview screenshots

SenSEO preview

SenSEO preview

SenSEO preview

The refactored code in most cases is based on web technologies - don't nail me down on that, but this should make it easier to publish SenSEO on other platforms also.

SenSEO for Chrome

If you find bugs (there will be some, the code is brand new), please report them on getsatisfaction.com/senseo.

Montag, 24. Oktober 2011

Mini-Suchmaschine mit Frontend-Technologien

Die SenSEO-Extension bekommt ein neues Feature "Analyze all pages". Hiermit soll es möglich sein, mit einem Klick die gesamte Website zu crawlen und sämtliche Seiten anhand vorgegebener Keywords zu bewerten. Dieses Crawlen und Bewerten wird ausschließlich mit Frontend-Technologien implementiert. Die nachfolgende Grafik zeigt die geplanten Schritte.

Mini-Searchengine

Der Anfang ist bereits geschafft. Mit diesem Prototypen (läuft nur im Firefox) ist es möglich, aus dem Markup einer vorgegebenen Seite sämtliche Links zu extrahieren. Es können lediglich Seiten von sensational-seo.com angegeben werden, da die Same Origin Policy nur Seiten der selben Domain für die Analyse zulässt.

Das Markup wird mit der XMLHttpRequest API abgerufen und mit der evaluate Function der Firefox XPath JavaScript API geparst.

Da die API lediglich DOM Dokumente https://developer.mozilla.org/en/DOM/document verarbeitet, wird die als String gelieferte XMLHttpRequest Response vorher einem iFrame als Inhalt zugewiesen. Der folgende Code macht dies möglich.

// create iframe
var responseTextIframeElement = document.createElement('iframe');
responseTextIframeElement.setAttribute('width', '0');
responseTextIframeElement.setAttribute('height', '0');
responseTextIframe = document.body.appendChild(responseTextIframeElement);
responseTextIframe.contentWindow.document.write(responseText);
var responseXML = responseTextIframe.contentWindow.document;
// clear iframe
responseTextIframe.parentNode.removeChild(responseTextIframe);
mse.Crawler.gotPageContentByUrl(responseXML);


Möchte man ohne XMLHttpRequest API arbeiten, kann man einem zuvor erzeugten iFrame auch einfach den URL als scr-Attribut zuweisen.

// create iframe
var responseTextIframeElement = document.createElement('iframe');
responseTextIframeElement.setAttribute('width', '0');
responseTextIframeElement.setAttribute('height', '0');
responseTextIframe = document.body.appendChild(responseTextIframeElement);
responseTextIframe.addEventListener('load', function(e) {
var responseTextIframe = this;
var responseXML = responseTextIframe.contentWindow.document;
// clear iframe
responseTextIframe.parentNode.removeChild(responseTextIframe);
// this is not the best sollution
mse.Crawler.gotPageContentByUrl(responseXML);
}, false);
responseTextIframe.src = url;


Die Extrahierung der href-Attribute aus sämtlichen Anker-Tags übernimmt dann der folgende Code.

var allLinksXpath = responseXML.evaluate('/html/body//a/@href', responseXML, null, XPathResult.ANY_TYPE, null);


In einem nächsten Schritt sollen all die Verlinkungen extrahiert werden, welche absolut (mit http Schema) auf die selbe Domain verweisen oder Seiten relativ referenzieren. Diese Verlinkungen werden mit der Local Storage API auf einem Stack abgelegt und sequentiell nach dem LILO-Prinzip (Last in, Last out) gecrawlt. Dabei wird die Bereinigung von Dubletten mit Hilfe des Canonical-Tag eine wichtige Rolle spielen. Im Local Storage wird neben der extrahierten URL also auch immer eine zweite kanonische URL abgelegt, welche durch einen entsprechenden Abgleich das doppelte Crawlen von Seiten verhindern soll.

Montag, 1. August 2011

Rendern von Seiten-Komponenten

Möchte man nur Teile einer Seite neu rendern, ohne den Rest der Seite zu verändern, bedient man sich häufig der DOM-Manipulation mit JavaScript. Sind an diesem Prozess dynamische Daten beteiligt, die auf dem Server gehalten werden, kommt auch noch XHR und JSON zum Austausch der Daten hinzu. Konkret ergeben sich daraus folgende Schritte, die für gewöhnlich als AJAX bezeichnet werden:

  1. Ein XHR-Request erfragt Daten vom Server, die dieser in einer Session hält
  2. Der Server sendet die angeforderten Daten im JSON-Format und der Client wandelt diese in JavaScript-Objekte
  3. Basierend auf den so entstandenen Objekten werden mit JavaScript Manipulationen am bestehenden HTML-Dokument vorgenommen


Einige Nachteile dieses Vorgehens

  • Der Ansatz funktioniert nur mit JavaScript - ohne JavaScript findet keine Veränderung des Dokuments statt
  • Eigens für die DOM-Manipulation muss JavaScript-Code geschrieben werden - auf eventuell bestehenden Code des Templatesystems auf dem Server kann nicht zurückgegriffen werden
  • Durch Punkt 2 besteht die Tendenz zum Duplizieren von Code in verschiedenen Sprachen auf Server- und Clientseite
  • Setzt man sehr massiv auf den oben beschriebenen Ansatz, sind für Suchmaschinen kaum verwertbare Inhalte verfügbar


Wie können diese Nachteile umgangen werden?

Die meisten Templatesysteme setzen das HTML-Dokument aus einer Kombination verschiedener Seiten-Komponenten zusammen - typisch hierfür sind ein Header-, Content- und Footer-Bereich - aber auch Navigation, Sidebar etc. bilden solche Komponenten. Oft werden dynamische Daten genutzt, um z. B. eine Navigation zu erzeugen, die Links zu neu erzeugten Seiten generiert, ohne weitere Veränderungen am Code vorzunehmen zu müssen.

Am Beispiel einer Kostenübersicht möchte ich demonstrieren, wie solch eine Komponente mit XHR nach jeder Veränderung des Warenkorbs ohne Neuladen der Seite aktualisiert werden kann. Der folgende Wireframe zeigt den schematisch Aufbau der Seite - links die zu aktualisierende Kostenübersicht, rechts der Bereich, über den Veränderungen am Warenkorb vorgenommen werden können.

Beispiel für eine Kostenübersicht


Schritt 1 - Der initial Request

Der initiale Request ruft die Seite das erste Mal vom Server ab. Angenommen, es befinden sich zu diesem Zeitpunkt bereits zwei Artikel im Warenkorb, dann würde die Kostenübersicht von einer Komponente erzeugt werden, die für jeden der zwei Artikel eine neue Tabellenzeile mit den zugehörigen Daten generiert. Zusammen mit den übrigen Teilen der Seite entsteht ein komplettes HTML-Dokument, welches über HTTP an den Browser ausgeliefert wird.

Initialer HTTP-Request


Soweit ist dies der klassische Ansatz, wie er von den meisten Frameworks verfolgt wird.

Schritt 2 - Ein Artikel wird hinzugefügt

Für das hinzufügen eines Artikels existiert ein Anker-Tag, welches einem Server-Script den neuen Artikel als GET-Paramter übergibt. Um das Neuladen der Seite zu verhindern, wird das Verhalten des Anker-Tags mit JavaScript unterbunden und statt dessen der Artikel über einen Webservice-Call mit XHR an den Server kommuniziert. Somit haben wir ein korrektes Verhalten für aktiviertes und deaktivertes JavaScript sichergestellt.

In beiden Fällen wird dem Warenkorbsystem auf dem Server der ausgewählte Artikel hinzugefügt. Bei deaktiviertem JavaScript würde erneut ein HTML-Dokument mit dem neuen Artikel in der Kostenübersicht erzeugt und über HTTP an den Browser ausgeliefert werden. Das interessante Verhalten ergibt sich bei aktiviertem JavaScript. Nachdem der Webserivce-Call erfolgreich verarbeitet wurde, gilt es die Kostenübersicht zu aktualisieren. Beim klassischen AJAX-Ansatz würde die Response die neuen Warenkorb-Artikel enthalten und per DOM-Manipulation würde die Tabelle der Kostenübersicht um eine weitere Zeile ergänzt werden. Dies kann bei komplexeren Problemen schnell sehr aufwändig werden. Eine elegantere Lösung besteht darin, das HTML-Fragment der Kostenübersicht auf dem Server neu erzeugen zu lassen und anschließend das bestehende Fragment mit JavaScript durch das neu erzeugte zu ersetzten. Die folgende Grafik soll diese Lösung veranschaulichen.

Schaubild für HTML-Fragment


Welche Probleme gibt es hierbei zu lösen

Es muss eine Verbindung vom alten zum neuen HTML-Fragment hergestellt werden können. Am einfachsten ist dies mit einer Element-ID möglich, über welche das Fragment identifiziert und durch das neue ersetzt werden kann. Weiterhin muss das serverseitige Templatesystem/Framework eine entsprechende Funktionalität zum selektiven Neurendern von Seitenkomponenten bereitstellen. Komponentenbasierte Frameworks bieten hier die besten Chancen für einen solchen Support. Eine weitere Herausforderung stellt das Erzeugen und Entfernen von Event-Listenern auf Elemente des Fragments dar - auch hier sollte das Framework eine entsprechende Unterstützung bieten.

Hühnersuppe ala Mama

Bei Erkältung hilft nur eins - die Hühnersuppe ala Mama. Die Zubereitung ist einfach und der Erkältung fällt dann auch nix mehr ein.

Folgende Zutaten werden für eine große Portion Hühnersuppe benötigt (bei einer kleineren Portion die halbe Menge oder fertig abgepacktes Suppengemüse kaufen):

Hühnersuppe ala Mama

  • 1 großes Suppenhuhn vom Markt oder aus dem BIO-Laden
  • 250g Suppennudeln
  • 1 Kohlrabi
  • 1 Butterrübe
  • 1 Knolle Sellerie
  • 2 mittelgroße Möhren
  • 1 Stange Lauch
  • 1 Bund Petersilie
  • Salz
  • Gemahlener schwarzer Pfeffer


Das Huhn ggf. auftauen und dann mit viel Wasser und reichlich Salz in einem großen Topf bei halb aufgelegtem Deckel zum Kochen bringen. Danach auf mittlere Hitze zurückschalten und weiter kochen lassen.

Das Gemüse schälen und grob in größere Stücke zerteilen. Das Kleinschneiden kommt später. Beim Lauch gibt es zu beachten, dass auch die oberen, grünen Teile mitgekocht werden. Die Gemüsestücke zum Huhn in den Topf geben und ca. 20-30 Minuten gar kochen. Danach mit einer Schöpfkelle wieder aus dem Topf fischen (das Huhn kocht weiter), in eine Schüssel geben, klein schneiden und beiseite stellen. Je nach Geschmack nicht das gesamte Gemüse kleingeschneiden - von der Menge her ist das eher zu viel.

Wenn das Huhn nach 1-2 Stunden gar gekocht ist (das Fleisch sollte sich ganz leicht vom Knochen lösen lassen) aus dem Topf nehmen, die Haut und die Knochen entfernen und das Hühnerfleisch in kleine Stücke schneiden. Parallel dazu Wasser mit einer Prise Salz in einem separaten Topf zum Kochen bringen und die Suppennudeln darin nach Anleitung kochen. Die Nudeln danach in ein feinmaschiges Sieb abgießen und zusammen mit den Fleischstücken und dem geschnitten Gemüse zurück in den Topf geben.

Die Suppe mit Salz und Pfeffer abschmecken. Zum Schluss die Petersilie mit einem Wiegemesser klein schneiden und über die fertige Suppe streuen.

Ein paar Tipps

Suppe braucht viel Salz. Wenn trotzdem mal zu viel Salz an die Suppe gerät, hilft es, eine Kartoffel mitzukochen. Diese saugt das Salz auf und kann später weggeworfen werden.

Wer die Suppe nicht ganz so fett mag, kann sie auch erst erkalten lassen, dann in den Kühlschrank stellen und nach einigen Stunden die Schicht Fett abziehen, die sich auf der Suppe bildet.

Hühnersuppe läßt sich prima einfrieren. Größere Mengen am besten in Portionen aufteilen, da jedes erneute Aufkochen den Nudeln schadet.

Dienstag, 5. April 2011

SenSEO Infografik

Zum 200.000sten Download von SenSEO habe ich als kleines Dankeschön eine Infografik mit interessanten Fakten zur Firefox-Extension zusammengestellt.

SenSEO Infografik

Blog abonnieren

RSS 2.0 Feed

Suche

Kalender

Zurück Mai '12
Mo Di Mi Do Fr Sa So
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

Verwaltung des Blogs

Blogroll

Projects/Web

vCard

  • Nico Steiner
  • www.nicosteiner.de
  • Karlsruhe/Germany
  • Senior Frontend-Developer at 1&1