Rate mal mit Shopware

Die älteren werden sich erinnern: Rate mal mit Rosenthal war eine Quizsendung im ZDF. Ich würde das gerne wieder aufleben lassen.

Wo findet man in Shopware die Einstellmöglichkeit, dass Filter sich automatisch aktualisieren (Live reload, AJAX reload oder wie auch immer man das nennen will)?

  • Einstellungen – Grundeinstellungen – Storefront – Filter / Sortierung
  • Artikel – Kategorien
  • Einstellungen – Caches / Performance – Einstellungen – Allgemein – Filter

„Einstellungen – Caches / Performance – Einstellungen – Allgemein – Filter“ ist so richtig wie nicht intuitiv.
Und während sich in „Einstellungen – Caches / Performance – Einstellungen – Allgemein – Kategorien“ Sachen finden, die sich auch in „Einstellungen – Grundeinstellungen – Storefront – Kategorien / Listen“ hat man diese nicht ganz unwichtige Option nicht doppelt und dreifach untergebracht.

Templatevererbung und Namespaces in Shopware

Ihr wollt einen Block in einem Shopware-Template ändern und erweitert daher das Eltern-Template:

{extends file="parent:frontend/listing/text.tpl"}

So weit so bekannt. Wollt ihr jetzt aber in diesem Template Snippets aus dem Elterntemplate ohne Namespace verwenden führt das dazu, dass ein neues Snippet im Namespace eurer neuen Datei (hier also „frontend/listing/text”) angelegt wird.

{s name='ListingActionsCloseOffCanvas'}{/s}

Um das zu verindern müsst ihr einen evtl. gesetzten globalen Namespace nach dem vererben erneut setzen oder den gewünschten Namespace bei jedem Snippet mit angeben.
Also entweder so:

{extends file="parent:frontend/listing/text.tpl"}
{namespace name="frontend/listing/listing"}

Oder so:

{s namespace='frontend/listing/listing' name='ListingActionsCloseOffCanvas'}{/s}

Dynamische Snippets in Smarty

Für den Fall, dass man aus einer Smarty-Variable ein Snippet zaubern will:

{$namespace = "frontend/language"}
{$name = $lang.locale}
{""|snippet:$name:$namespace}

Konkretes Beispiel:
Man hat den locale einer Sprache (z.B. de_DE), möchte aber ganz gerne „Deutsch“ im Frontend ausgeben. Mit dem Code oben geht genau das, Smarty gibt jetzt den Inhalt des Snippets „de_DE“ aus dem Namespace „frontend/language“ aus. Der Namespace ist dabei wichtig, sonst funktioniert es nicht!

Man kann über den cat-Modifier außerdem noch den Namen erweitern, damit man als Snippet-Name nicht nur „de_DE“ in der Datenbank stehen hat:

{$name = "lang_"|cat:$lang.locale}

und bekommt damit lang_de_DE als Name.

$discardedLessThemes vs. Shopware: Es könnte so einfach sein

Ich mag das Theme-Konzept von Shopware ja eigentlich. Es gibt ein Bare-Theme, das außer HTML nichts enthält. Kein Styling, kein Javascript, einfach nur reines HTML.
Darauf aufbauend gibt es ein Responsive-Theme das, wie der Name schon sagt, responsive ist und über Variablen im Backend farblich auch ein bisschen angepasst werden kann. Das ist für den Wohnzimmerhändler sicherlich toll und man sieht auch mittlerweile unzählige Shops, die das Responsive-Theme nutzen und außer Logo und Farbe nichts geändert haben. Kann man machen, ist dann halt kacke.

Für unsere Ansprüche ist das natürlich nichts. Wir haben ein komplett selbst gestaltetes Theme, das auch nach allen Regeln der Kunst umgesetzt werden soll. Und da es so ganz anders ist als das Default-Theme wäre es natürlich gut, wenn man nicht den ganzen CSS-Ballast, den das Responsive-Theme mitbringt, rumschleppen müsste.

Weil sind wir doch mal ehrlich: Shopware 5 und damit die Grundlage des Responsive-Themes ist von 2015, der letzte Commit auf das Repo von pocketgrid, welches das Responsive-Theme nutzt, ist sogar noch ein Jahr länger her. Mittlerweile haben wir echtes CSS Grid und es wäre fahrlässig, das nicht zu nutzen.

Nur: Der Weg von

zu

ist ganz schön steinig und unnötig beschwerlich.

Vom Bare-Theme erben

Funktioniert total gut. Also bestimmt. Wenn man einen frisch installierten Shop hat ohne ein einziges Plugin. Das dürfte aber eher die Ausnahme sein. Schon bei einem Shop, der lediglich das PayPal-Modul installiert hat, scheitert das Kompilieren des Themes:

Während der Bearbeitung von Shop "Demoshop" ist ein Fehler aufgetreten: variable @tabletViewportWidth is undefined in file custom/plugins/SwagPaymentPayPalUnified/Resources/views/frontend/_public/src/less/_modules/index/sidebar.less in sidebar.less on line 11, column 30 09| } 10| 11| @media screen and(min-width: @tabletViewportWidth) { 12| .paypal--sidebar { 13| .unitize(margin-bottom, 20); 14|

Öh ja, das ist so semi-gut. Kann man prinzipiell nachrüsten, sobald man aber noch ein paar komplexere Plugins am Start hat wie beispielsweise die Advanced Promotion Suite knallt es auch bei den Farbwerten, die man eigentlich über das Backend konfigurieren kann (aber eben nicht beim Bare-Theme).

$discardedLessThemes beim Responsive-Theme

Also vom Responsive-Theme erben. Seit Shopware 5.4 gibt es da die Möglichkeit, sowohl in den Vererbungspfad des CSS/LESS als auch das Javascripts einzugreifen. Für LESS/CSS mittels discardedLessThemes, für das Javascript mittels discardedJavascriptThemes.

Da also das Responsive-Theme eintragen und kompilieren und alles ist super. Natürlich nicht. Auch hier hat man die Rechnung ohne die Plugin-Autoren gemacht. Direkt als erstes fliegt einem wieder der Tablet-Viewport um die Ohren. Hat man sich dafür ein eigenes LESS-File angelegt knallt zumindest in unserem Fall das Amazon-Pay-Plugin. Und zwar mehrfach aufgrund des Zugriffs auf jetzt nicht mehr vorhandene Definitonen aus dem Bereich der Buttons. Also auch hier eigene LESS-Files anlegen und leere Definitionen dort eintragen.
So geht das Spielchen, das einem Marathon gleicht, munter weiter, bis alle Plugins, die noch nichts davon gehört haben, dass die Vererbung mittlerweile abschaltbar ist, zufrieden gestellt sind. Erst dann hat man für einen Shop mit diversen Plugins auch endlich eine wirklich CSS-freie Darstellung. Also quasi Bare-Theme ohne die Probleme mit den fehlenden Farbdefinitionen.

Nur: CSS-frei ist das ganze deswegen noch lange nicht, da sorgt schon jedes Plugin dafür, dass da wieder ein bisschen was zusammen kommt, aber zumindest lässt sich so der Umfang des CSS schon mal auf ca. 2500 Zeilen reduzieren, während der gleiche Shop mit Responsive-Theme auf 25.000 Zeilen kommt. Es ist noch ein weiter Weg…

Alexa und FRITZ!Box – und es bewegt sich doch…

Basierend auf diesem Blogpost habe ich mir eine Lösung für die AVM-DECT-Steckdosen FRITZ!Dect 200 gebastelt. Das ganze war als reine Fingerübung gedacht, da es aber immer wieder Nachfragen gibt, hier Details zur Umsetzung.

Das ganze läuft auf einem Uberspace als Webserver. Nehmen wir mal an, der Uberspace-Name ist jarvis und läuft auf dem Server stark. Dieser Webspace ist dann über https://jarvis.stark.uberspace.de/ erreichbar. Wichtig: jarvis immer durch den Namen eures Uberspaces ersetzen (vergebt ihr beim Anlegen) und stark immer durch den Namen des Servers, auf dem euer Uberspace liegt (bekommt ihr nach dem Anlegen automatisch zugewiesen und ist auf dem Reiter ‘Datenblatt’ ersichtlich).

Wir verbinden uns per ssh und wechseln in das DocumentRoot, klonen dort das git-Repo und benennen den Ordner in was brauchbares um:

cd /var/www/virtual/jarvis/
git clone https://github.com/gaiterjones/amazon-alexa-php-hello-world-example
mv amazon-alexa-php-hello-world-example/ alexa

Als nächstes müssen wir mittels Symlink dafür sorgen, dass der Webserver ein anderes Verzeichnis als DocumentRoot benutzt:

ln -s alexa/PAJ/www/Amazon/ jarvis.stark.uberspace.de

Abschließend brauchen wir noch die Datei, die mit der AVM-AHA-Interface spricht. Ich hab da schon mal was vorbereitet. Diese kommt in das folgende Verzeichnis:

/var/www/virtual/jarvis/alexa/PAJ/Application/Amazon/Alexa/Intent

Damit das funktioniert muss in Zeile 25 der Host geändert werden unter dem die FRITZ!Box aus dem Internet erreichbar ist. Außerdem ist den Zeilem 239 und 240 Benutzername und Passwort. Es ist zwingend notwendig, dass für die Anmeldung an der FRITZ!Box sowohl Benutzername als auch Passwort benötigt werden. Wenn das noch nicht der Fall ist muss man das entsprechend umstellen.
Auf jeden Fall sollte ein eigener User für die Kommunikation mit Alexa angelegt werden!

Jetzt loggen wir uns auf developer.amazon.com mit unserem Amazon-Developer-Account ein. Wer noch keinen hat registriert sich schnell einen, es muss sich dabei um den gleichen Account handeln der auch für Alexa hinterlegt ist, sonst steht der Skill anschließend nicht zur Verfügung.

Der Skill basiert auf dem Custom Interaction Model, deshalb ist auch ein Codewort erforderlich. Wenn man direkt die Smart Home Skill API verwendet benötigt man das nicht, damit habe ich mich aber nicht beschäftigt, da man dafür zwingend alles als AWS Lambda ARN hosten muss. Damit kann sich gerne AVM auseinandersetzen.

Unser Skill hat den Invocation Name ‘fritzbox’, das Intent Schema sieht so aus:

{
  "intents": [
    {
      "intent": "FritzBox",
      "slots": [
        {
          "name": "trigger",
          "type": "TRIGGER"
        },
        {
          "name": "state",
          "type": "STATE"
        },
        {
          "name": "action",
          "type": "ACTION"
        },
        {
          "name": "device",
          "type": "DEVICE"
        }
      ]   
    }
  ]
}

Die Slots so:

Und die Sample Utterances so:

FritzBox schalte {trigger} {state}
FritzBox liste meine {device} auf
FritzBox ich brauche die Liste der {device}
FritzBox ich brauche die {device} Liste
FritzBox wie ist die {action} von {trigger}
FritzBox nach dem {action} von {trigger}
FritzBox nach den {action} zu {trigger}

Wichtig ist beim SSL-Zertifikat die Option ‘My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority’ zu wählen, sonst läuft es nicht.

Im Testbereich können wir jetzt beliebige Test durchführen, z.B. ‘sag fritzbox schalte Bad ein’. Die Antwort sollte in etwa so aussehen:

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "Bad wurde eingeschaltet"
    },
    "card": {
      "text": "Bad wurde eingeschaltet",
      "title": "FRITZ!Box",
      "image": {
        "smallImageUrl": "https://jarvis.stark.uberspace.de/alexaCardImage.php?size=small&image=default",
        "largeImageUrl": "https://jarvis.stark.uberspace.de/alexaCardImage.php?size=large&image=default"
      },
      "type": "Standard"
    },
    "shouldEndSession": true
  },
  "sessionAttributes": {}
}

Und damit sollten sich die Steckdosen entsprechend schalten und abfragen lassen. Prinzipiell müsste das auch mit Thermostaten funktionieren, ich hab aber keine und kann das daher nicht testen oder implementieren.

Optimizing JPEG images – save 20% in file size

Optimizing your image file size is one of the low hanging fruits when it comes to page speed optimization for your website.

My current workflow for JPEGs looks something like this:

  • ‘Save for Web’ in Photoshop with 60% quality
  • Run through ImageOptim to reduce file size

Yesterday, Marc Thiele asked on Twitter:

In the unfolding discussion some folks stated that they use both JPEGmini and ImageOptim when it comes to JPEGs and that this would reduce the file size even more. Fortunately I had to add pictures to 50 new products today. Every product has three pictures from different angles, so this sums it up to 150 images in various sizes, 900 images in total, all JPEG.
So I gave it a try and here are the results (I bought JPEGmini for this test as 20 images on the lite version might not be enough to get reliable results, still, your mileage may vary).

‘Save for Web’

With just using ‘Save for Web’ the images had a total size of 84MB. Quite heavy.
photoshop

ImageOptim

Running these through ImageOptim saved nearly 10% and lowered the total size to 75.7MB.
imageoptim

JPEGmini

Using the ‘Save for Web’ images again (not touched by ImageOptim yet) results in 74.2MB.
jpegmini

ImageOptim after JPEGmini

Now adding another run of ImageOptim to the images already optimized by JPEGmini lowers the total size to 66.9MB. Thats more than 20% in file size saved without compromising image quality.
jpegmini-imageoptim

As far as I can tell it is not necessary to run the tools multiple times. At least in ImageOptim it is obvious that the latest version does this by itself. And I wasn’t able to spot any major changes on a second and third run with JPEGmini.

To give you the ability to compare the results, below are two images. The left one is the image just saved from Photoshop, the right one is the image after the whole optimization process.
photographer_ps photographer_optimized

Kundenservice? Not here. Not now.

Ich bin umgezogen. Irgendwann im Mai. Im Rahmen der Einrichtung der neuen Wohnung habe ich es geschafft, mir meine sämtlichen Plastikkarten zu bricken. Also von Kreditkarte über Packstation, Krankenkasse bis hin zu Payback. Topfmagnet vs. Karte ist halt keine so gut Idee. Wurde mir auch klar, als der Magnet sich von meinem Kleingeld magisch angezogen fühlte.

Also konnte ich direkt zwei Fliegen mit einer Klappe schlagen: Adressänderung und neue Karten anfordern. Bei der Bank habe ich angerufen. Da ging auch alles glatt. DHL und DAK habe ich eine E-Mail geschrieben. Wobei das nicht wirklich richtig ist. Ich habe das Kontaktformular benutzt, das auf deren Homepages angeboten wird. Bei beiden ist das jetzt 3,5 Wochen her. Seitdem ist nichts geschehen. Keine Bestätigung der Adressänderung, keine neuen Karten. Der Griff zum Telefonhörer also unvermeidlich.

Bei DHL wusste man nichts von einer Mail. „Das Kontaktformular geht über verschiedene Kanäle” war da die Aussage. Was auch immer das heißen mag. Vielleicht, dass man es sich betriebsintern so lange weiterleitet bis sich das Problem von selbst erledigt hat. Ich weiß es nicht. Eine neue Karte würde aber zwei Wochen dauern. Das ich schon mehr als drei Wochen warten würde, weil DHL die internen Prozesse nicht im Griff hat, wollte man nicht gelten lassen. Immerhin war die neue Adresse schon hinterlegt. Das liegt aber daran, dass man die bei DHL selbst ändern kann.

Mehr als drei Wochen keine Reaktion und dann zwei Wochen Wartezeit für ein neues Plastikkärtchen. Geht nicht schlimmer? Klar geht das schlimmer. Nächster Anruf DAK:
Da die DAK-Karte keinen Magnetstreifen besitzt hatte ich denen ins Kontaktformular geschrieben, dass sie mir doch bitte mitteilen sollen, ob es der Karte schadet wenn man sie mit einem Magnet in Kontakt bringt. Genau das war meine Einstiegsfrage ins Gespräch:

Support:
Das kann ich Ihnen leider auch nicht sagen.
Ich:
Dann bringen Sie das doch bitte mal in Erfahrung.
Support:
Waren Sie in der Zwischenzeit beim Arzt und sie hat nicht funktioniert?
Ich:
Nein, ich dachte ihr seit in der Lage, innerhalb von drei Wochen eine E-Mail zu beantworten.
Support:
Äh, da kann ich jetzt nichts zu sagen. Ich schick Ihnen eine neue zu.
Ich:
Klären Sie doch erstmal, ob das wirklich nötig ist!
Support:
Das kann ich nicht.
Ich:
Es wird doch irgend jemand bei Ihnen im Haus geben, der diese Frage beantworten kann.
Support:
Äh… Moment.
(Geht also doch. Man will nur nicht. Man hört Rascheln im Hintergrund, keine Warteschleifenmusik. Sehr professionell.)
Support:
Ja, es schadet der Karte. Ich schick Ihnen also eine neue zu. Wie heißen Sie denn.
Ich:
Slovig
Support
Sowick?
(Die genaue Schreibweise war nicht zu ermitteln)
Ich:
Slovig. Siegfried, Ludwig, Otto, Vogel, Ida, Gustav.
Support:
Vorname?
Ich:
Matthias
Support:
Mit einfachem T?
Ich:
Mit doppelt-T und H.
Support:
In Berlin?
Ich:
Nein. Ich glaube, es ist einfacher, ich gebe Ihnen meine Versichertennummer.
Support:
Ja, das ist eine gute Idee.

Es gibt keinen Matthias Slovig mit genau dieser Schreibweise in Berlin. Die Supportmitarbeiterin hat es also tatsächlich geschafft, einen aus sechs Buchstaben bestehenden buchstabierten Nachnamen falsch ins Formular einzutragen. Warum sie nicht von sich aus nach der Versichertennummer gefragt hat wird ein ewiges Rätsel bleiben.

Support:
In Mainz also.
Ich:
Ja.
(Zumindest das fehlerfreie Eintippen eines Buchstabens und einer neunstelligen Nummer hat funktioniert.)
Support:
Ich schick die Karte dann raus.
Ich:
Welche Adresse haben Sie denn hinterlegt?
Support:
Am Schinnergraben 102.
Ich:
Verdammt noch mal! Ihr habt es also in diesen drei Wochen nicht mal geschafft, meine neue Adresse in Euer System zu übernehmen! Das kann es doch echt nicht sein!

Ich bin seit Geburt bei der DAK. Derzeit zahle ich monatlich einen hohen dreistelligen Betrag, damit ich zweimal jährlich meine Zahnreinigung selber zahlen darf *. Ich habe mich trotzdem nie mit dem Gedanken getragen, die Krankenkasse zu wechseln. Bis heute. Wenn das der Anspruch der DAK ist, den sie an ihren Kundendienst stellen (unfähige Hotline-Mitarbeiter, niemand, der E-Mails bearbeitet), dann muss ich mich ernsthaft fragen, ob das noch immer die Krankenkasse ist, bei der ich versichert sein möchte.
Sollte man jetzt auch noch ein neues Bild brauchen, weil man das alte verschlampt hat, werde ich das so lange ausfechten bis man mir eine Karte ohne Bild schickt, das ist sicher.

* Mir ist durchaus klar wie so ein Solidarsystem funktioniert. Kommentare diesbezüglich kann man sich also sparen. Danke.

Free these mobile contracts, Deutsche Telekom

To give you some context this starts last friday. I attended border:none, a conference for web professionals that took place in Nuremberg. My parents only live an hour north and so I took the opportunity and swung by their place. Also my brother is among the best german model railroaders, his work is known all over Europe and, thanks to his website, worldwide. His club ran their yearly exhibition on that same weekend and as I hadn’t seen it in action before I went there to have a look at his new South Africa layout. Of course I took some pictures and back at my parents uploaded them to my dropbox. Well, at least I tried.

My parents have DSL6000, that means 6016 kbit/s down and 576 kbit/s up. However, as the line is too long, they only can use a fraction of this. It took ages to upload only one picture. I put my phone in the pocket and went upstairs to see my other brother. There is no WIFI reception upstairs and when I unlocked my phone in the attic the upload was incredible fast. I was stunned. What happend? Due to the lack of a WIFI connection my iPhone 5S ‘dropped’ to LTE, which is available in the area. LTE, however, gives me something similar to DSL16000 and all 40 images and two videos got uploaded in less than 10 minutes. You would like to cancel the DSL6000 contract now, put a SIM into your router and use LTE from there on. There is, however, one problem and it has a name: The carriers.

The contracts offered by Deutsche Telekom (and all other carriers in Germany) don’t have a real flatrate, you get your bandwith limited when you hit a ridiculously low amount of data transfered. Remove this, Deutsche Telekom, or at least lift it up to something useful, 50GB or 100GB would do for the beginning. Free these mobile contracts! It’s your chance! And your obligation. Make Germany fast!

The Tripadvisor desaster

If your business model builds on user generated content – hell, don’t fuck with the users! Yes, I’m looking at you, TripAdvisor!

While researching hotels I not only rely on the HRS ratings but also look the hotel up on TripAdvisor for even more reviews. As this works pretty well I decided to give something back to the community by rating the hotels we stayed.

Signup is easy as you can use your Facebook login. Reviewing is also quite easy, however, your review goes to a pending queue, more commonly known as a black whole and this is where the fun begins. It stays there for some time. The FAQ says 24 to 48 hours, however mine are in the queue for more than 72 hours each. This is quite anoying, as they pile up while you write new reviews and don’t even know if they are helpful for the community, as nobody can read them. On the first review I thought this might be because I’m new to the platform but also with more reviews written nothing speeds up.

But here is what really sucks: Some of my reviews got deleted while pending. No word about why TripAdvisor trashed them, not even an email and there have been reviews for hotels that have only one review to date. And none of them was rude or anything like this, just honest reviews.

I wrote TripAdvisor about this five days ago but haven’t heard back yet. The contact form is also pretty hard to find and the issue ‘My review got deleted’ is not even an option to select.
So all of you who rely on user generated content: If I spend my time to improve your site, let me know what’s going on! Learn from the TripAdvisor desaster!

VX ConnectBot – ConnectBot on steroids

Most of the time ranting about something brings up better solutions. I was quite disappointed with ConnectBot as an alternative to Prompt and mentioned this in my first android review. @DarthMowl replied on Twitter and suggested VX ConnectBot.

Well, we are back in Canada and it’s raining again so I got some time to write about VX ConnectBot. It addresses most of the issues I criticized.

  • You can import keys. Just store the key on the device and import it with VX ConnectBot.
  • Bookmarks can be renamed, that however also works with ConnectBot, I just didn’t try a tap-and-hold on the bookmark before.
  • Terminal size can be changed by pinch gestures.

The problem with the arrow keys remains. However, there’s an app for that (sic!), Full Keyboard. Or any other keyboard extension on Android. However, I found none I’m comfortable with so I will stick with the default keyboard for the time being.

There are some more features that set VX ConnectBot apart from ConnectBot, what I love most is the ability to assign keystrokes to hardware buttons. So ‘Volume up’ now works as tab key and ‘Volume down’ as control key. With no more hardware buttons on the Nexus 4 that’s it for this device, but you can assign more buttons on other devices.