When sending HTML-mails through PHP you'll see that some email-clients (like: gmail) will strip al the styles you defined in an external stylesheet or in a style-tag.

You can't expect the users of your application will define all the styles inline (some WYSIWYG-editors have that functionality), so it would be nice if there was a way to grab the HTML, set the CSS and just get the HTML but with all styles defined inline.

So here is CSSToInlineStyles, this class enables you to do this.

How does it work?

Well, it's pretty straight forward. After setting the HTML (and CSS), the class will read the CSS build an array that contains all the rules sorted by their specifity.

The HTML will be loaded as a DOMDocument.

When that's done, each rule will be looped. The CSS-selector will be converted into a XPath-query. If the query returns an element a style-attribute will be added, all defined CSS-rules will be added into this style attribute.

So, get the class and enjoy.

Dit artikel gaat over: , , , , , , . Convert CSS to inline styles with PHP werd geschreven door Tijs Verkoyen.
Er zijn nog geen reacties, reageer als eerste.

When scrapping HTML-pages it can be usefull to get elements based on CSS-selectors. Therefore I wrote a nifty function that builds a XPath-query that can be used to select the elements in a DOMXPath-document.

The function can be found below:

<?php
/**
 * Convert a CSS-selector into an xPath-query
 *
 * @return    string
 * @param    string $selector    The CSS-selector
 */
function buildXPathQuery($selector)
{
    // redefine
    $selector = (string) $selector;

    // the CSS selector
    $cssSelector = array(    // E F: Matches any F element that is a descendant of an E element
                            '/(\w)\s+(\w)/',
                            // E > F: Matches any F element that is a child of an element E
                            '/(\w)\s*>\s*(\w)/',
                            // E:first-child: Matches element E when E is the first child of its parent
                            '/(\w):first-child/',
                            // E + F: Matches any F element immediately preceded by an element
                            '/(\w)\s*\+\s*(\w)/',
                            // E[foo]: Matches any E element with the "foo" attribute set (whatever the value)
                            '/(\w)\[([\w\-]+)]/',
                            // E[foo="warning"]: Matches any E element whose "foo" attribute value is exactly equal to "warning"
                            '/(\w)\[([\w\-]+)\=\"(.*)\"]/',
                            // div.warning: HTML only. The same as DIV[class~="warning"]
                            '/(\w+|\*)?\.([\w\-]+)+/',
                            // E#myid: Matches any E element with id-attribute equal to "myid"
                            '/(\w+)+\#([\w\-]+)/',
                            // #myid: Matches any E element with id-attribute equal to "myid"
                            '/\#([\w\-]+)/'
                        );

    // the xPath-equivalent
    $xPathQuery = array(    '\1//\2',
                            '\1/\2',
                            '*[1]/self::\1',
                            '\1/following-sibling::*[1]/self::\2',
                            '\1 [ @\2 ]',
                            '\1[ contains( concat( " ", @\2, " " ), concat( " ", "\3", " " ) ) ]',
                            '\1[ contains( concat( " ", @class, " " ), concat( " ", "\2", " " ) ) ]',
                            '\1[ @id = "\2" ]',
                            '*[ @id = "\1" ]'
                        );

    // return
    return (string) '//'. preg_replace($cssSelector, $xPathQuery, $selector);
}
?>

In a post that will be published in the near future you 'll see why I really needed it.

Dit artikel gaat over: , . CSS Selector to XPath-query werd geschreven door Tijs Verkoyen.
Er zijn nog geen reacties, reageer als eerste.

23 januari 2010

Listenr.tv

Listenr.tv is een website waarop je je favoriete muziek kan bekijken.

Why, o why?

Ik luister graag naar muziek, ik ontdek ook graag nieuwe muziek. Daarvoor gebruik ik Last.fm.

Naast naar muziek luisteren kan je via de muziekzenders TMF, Jim of MTV ook heel wat muziek leren kennen door ernaar te kijken. Helaas voor de mensen (zoals ik) die geen mainstream hiphop, boenk-boenk liefhebbers zijn kan je op deze zenders enkel terecht tijdens de thema-uurtjes en daar spelen ze dan enkel de gekende muziek.

Daarom leek het me leuk en handig om de kracht van Last.fm en YouTube te combineren om voor iedereen een persoonlijke muziekzender te maken.

De website kan je op twee manieren benaderen.

  1. Voor de Last.fm gebruiker: Meld je aan met je Last.fm-account en op basis van je favoriete artiesten stelt Listenr.tv een playlist samen.
  2. Voor de gebruiker zonder Last.fm: Ofwel bekijk je de clipjes op de homepage of je klikt door op je favoriete genre.

Zodra je een playlist hebt gekozen kan je beginnen kijken naar jouw favoriete muziek.

Veel plezier!

Dit artikel gaat over: , , , , . Listenr.tv werd geschreven door Tijs Verkoyen.
Er zijn al 6 reacties.

13 januari 2010

De Lijn (deel 2097558)

Kan er iemand (liefst iemand met een beetje verstand in zijn hoofd) van De Lijn mij uitleggen welk nut de eindhalte in Wondelgem heeft?

Omdat het zo'n schitterend weer is waag ik mij niet op de baan met de moto. Daarom neem ik 's avonds Lijn 1 richting Evergem. Ofwel hebben ze bij De Lijn iets tegen mij of ik slaag er altijd in op een tram terecht te komen die slechts tot Wondelgem rijdt.

Na de eindhalte van Wondelgem moet ik slechts 2 haltes verder afstappen. Met de tram is dat iets van een 5minuten, tot aan de eindhalte (slechts 1 halte verder dan de mijne) is het volgens mij nog iets van een 2minuten rijden.

ARF

Als jullie nu eens altijd tot aan de eindhalte van Evergem rijden, dan hoef ik nooit meer 20min te staan wachten in Wondelgem om dan nog 5minuten op de tram te zitten.

Of begrijp ik het weer niet zo goed?

Dit artikel gaat over: , . De Lijn (deel 2097558) werd geschreven door Tijs Verkoyen.
Er zijn al 2 reacties.

13 november 2009

Music maestro

Christophe vraagt 5 oppeppende liedjes. Bij deze:

  1. Sabaton - 40:1 clip
  2. Amon Amarth - Guardians Of Asgaard featuring LG Petrov clip
  3. Samael - Slavocracy clip
  4. Amberian Dawn - River Of Tuoni clip
  5. DragonForce - Heroes of Our Time clip

Maar zie vooral: http://metalchannel.verkoyen.eu.

Dit artikel gaat over: , . Music maestro werd geschreven door Tijs Verkoyen.
Er is al 1 reactie.

28 oktober 2009

MySQL Slow Log Parser

Als je al eens in aanraking komt met grote projecten dan kan de Slow Query Log een hele openbaring zijn. In deze log komen alle queries die langer duren dan een ingesteld aantal seconden en een minimum aantal rijen moet verwerken.

The slow query log consists of all SQL statements that took more than long_query_time seconds to execute and required at least min_examined_row_limit rows to be examined.

Maar omdat alle trage queries hierin terechtkomen is het niet altijd makkelijk om uit te maken welke nu juist de queries zijn die je best aanpakt.

Via de mensen van Openminds had ik vernomen dat er een script was die deze log gaat parsen en je kan vertellen welke queries juist aandacht vragen.

Het script analyseert de log door te gaan kijken welke queries er meerdere keren voorkomen. Daarbij vervangen ze de variabele data zodat je een goed beeld krijgt.

Hoe installeer je het script:

  • download het script
  • open een terminal en verplaats het script naar /usr/bin met onderstaand commando:
    sudo mv path/to/download /usr/bin/mysql_slow_log_parser
  • Maak het script uitvoerbaar met onderstaand commando:
    sudo chmod +x /usr/bin/mysql_slow_log_parser
  • Gebruik het script:
    mysql_slow_log_parser path/to/slow_query.log

Kleine disclaimer: Wil je je database en queries tot in de puntjes optimaliseren? Neem dan een specialist onder de arm, zij kunnen je bijstaan met raad en daad. Een database-specialist weet beter dan welke tool ook hoe je database of queries kan optimaliseren

Dit artikel gaat over: , , , , . MySQL Slow Log Parser werd geschreven door Tijs Verkoyen.
Er zijn nog geen reacties, reageer als eerste.

26 oktober 2009

Kriega R32: Review

Jullie konden al lezen dat ik een nieuwe rugzak gekocht had in een van m'n vorige posts (http://blog.verkoyen.eu/blog/p/detail/kriega-r35). Ik beloofde toen ook om mijn ongezouten mening te geven, wel die kan je hieronder lezen.

1. Bestelling

Aangezien je de rugzak hier in België niet kan kopen via een winkel, heb ik  de Kriega R35 besteld via de webshop van Kriega. Het bestellen verliep vlot dus daar viel niets op aan te merken.

2. Levering

Ik vermoed dat er tussen het bestellen en de levering een 5dagen gepasseerd zijn. Naar mijn standaarden is dat vlot, maar ik bestel nu ook weer niet zoveel online. Wat me alleszins wel is bijgebleven is de verpakking, geen grote doos vol schuim, nee een propere nauw aansluitende plastiek.

3. Eerste rit & eerste indruk

Zonder overdrijven: SUPER!

De Kriega R35 is de grootste die je kan kopen, je zou er 35l in kwijt kunnen. Tijdens mijn eerste rit zat er relatief veel in (laptop, oude rugzak, schrift, losse papieren, doe, paraplu, gel, sleutels, …) en ik had nog ruimte over. Dus ruimte zat.

Het QuadLoc-systeem van Kriega ziet er speciaal uit maar dat is het helemaal niet. Je trekt de banden over je schouders zoals een normale rugzak, rits de twee riemen aan elkaar. Je kan dan eenmalig (lees: afhankelijk van de inhoud) de rugzak instellen door aan de rekkers bij de ringen te trekken de rugzak goed instellen. Hiermee zorg je ervoor dat de rugzak goed op je rug kleeft en op je heupen steunt in plaats van aan je schouders trekt.

Ik geef toe, het ziet er meer uit als een parachute, maar op de moto is het makkelijker dat de rugzak tegen je rug blijft hangen, zo kan daar geen wind tussen en worden je schouders niet uit de kom gerukt als je optrekt.

4. Eerste rit in de regen

Ik moet toegeven, in de regen met de moto rijden is vragen om nat te worden - hoewel het rijden niets is, het is het stilstaan waarvan je nat word - maar ik heb het liefst dat de zaken in mijn rugzak niet nat worden. Hoewel veel rugzakken pretenderen waterdicht te zijn is het tegengestelde meestal waar. Dus met een beetje een bang hart de rugzak aan en de moto op.

Thuisgekomen onmiddellijk gekeken of er niets nat was. Gelukkig was er niets nat, zelf geen drupje te bespeuren - hoewel de eerlijkheid me gebied om te vertellen dat mijn portefeuille zeiknat was omdat ik die in het zakje bovenaan had gestoken, wat van een gaas is gemaakt.

5. Coole features

  • Elke loshangend riempje heeft een soort van "lock"-systeem waardoor het niet hangt te flapperen als je aan het rijden bent.
  • Aan de zijkant zijn er zaken die doorlopen over de volledige hoogte van de rugzak. Ideaal om zaken in te steken die je niet veel nodig hebt.
  • Aan de voorkant is er een net waarin je allerlei zaken kwijtkan (schijfremslot, handschoenen). Je zou er ook een open helm in kwijtkunnen.
  • Zakjes in de riemen. In het stuk waarmee je de riemen verbindt zitten twee zakjes. Ideaal voor iPod of documenten.
  • Alle rekkers, ritsen, ... zijn vlot te bedienen met (winter-)handschoenen aan.

6. Minder cool

  • De rugzak glijdt af indien je rondloopt met maar 1 riem over je schouder.
  • Het zakje bovenaan is niet waterafstottend.
  • Het documenten-vakje in de rugzak had iets groter gemogen. Dan kon er vlot een laptop in.

7. Besluit

Een aanrader, zeker als je op zoek bent naar een rugzak waar een degelijke laptop in kan. Er is een apart vakje voor wat papieren in te steken, maar met een beetje geduw kan daar vlot een MacBook Pro 15" in.

Wat voor mij ook een overtuigend argument is: de rugzak is modulair. Je kan via de website nog extensies kopen die aan de rugzak kunnen bevestigd worden waarmee je het laadvermogen kan uitbreiden.

Dit artikel gaat over: , , . Kriega R32: Review werd geschreven door Tijs Verkoyen.
Er zijn nog geen reacties, reageer als eerste.