Even tussendoor

Ceci n’est pas un original.

Ik wacht op een nieuw product van Google dat gelijkaardige sites toont. Niet op basis van inhoud maar op basis van styling. That ought to be fun!


Even tussendoor

Ok, one more time: sites kopiëren doen we niet! Knoop het in uw oren, daar bij Ghibli in Rillaar.


PHP, PDO en geen resultaten

Verschillende versies, verschillende kenmerken. Verschillende redenen tot frustratie. Neem aan dat de volgende query voor de juiste waarde van :x (bijvoorbeeld 10) drie rijen teruggeeft.


SELECT a, b, c FROM Abc WHERE a < :x AND b > :x

Neem nu aan dat je volgende code gebruikt om die rijen op te halen in PHP, met behulp van PDO:


$sql = "SELECT 'AbcClass', a, b, c FROM Abc WHERE a < :x AND b > :x";
$statement = $pdo->prepare($sql);
$statement->bindParam(':x', 10);
$results = array();
if ($statement->execute()) {
    while ($result = $statement->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE)) {
        $results[] = $result;
    }
}

Hoeveel rijen zal je terugkrijgen? Het antwoord: het hangt af van de versie van PHP die je gebruikt. Op mijn computer is dat 5.2.0 en daar krijg ik de 3 rijen terug die ik verwacht. Op de server die me met het probleem confronteerde is dat echter 5.2.6 (rejoice: een betaalbare Belgische host met een degelijke PHP 5 installatie; pigs do fly). En wat blijkt, sinds PHP 5.2.1, wordt in dit voorbeeld 10 enkel de eerste keer aan :x gebonden.

Dus moet het dit worden:


$sql = "SELECT 'AbcClass', a, b, c FROM Abc WHERE a < :x AND b > :y";
$statement = $pdo->prepare($sql);
$statement->bindParam(':x', 10);
$statement->bindParam(':y', 10);
$results = array();
if ($statement->execute()) {
    while ($result = $statement->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE)) {
        $results[] = $result;
    }
}

Misschien zal ik toch eens de tijd moeten nemen om PHP op mijn computer te updaten om dit soort toestanden in de toekomst te vermijden.

Dit artikel werd opgenomen in ontwikkeling.


Even tussendoor

Werken met HTML en JavaScript in Adobe AIR heeft alvast één fantastisch voordeel: je moet rekening houden met WebKit en enkel WebKit. Denk dus lekker aan volledige ondersteuning voor transparante PNGs, meerdere achtergrondafbeeldingen en border-radius. Oh, en dat alle mogelijke selectors in CSS werken — van attribute selectors tot adjacent sibling selectors — zorgt ervoor dat ik ze eens kan gebruiken buiten jQuery.

Maar vergeet voorlopig text-shadow maar als je op Windows werkt.


Morse: de betere Gmail Notifier

Gmail is leuk. Zolang ik een internetverbinding heb kan ik altijd aan mijn e-mail. Gmail Notifier is ook leuk, want zo word ik automatisch verwittigd wanneer er nieuwe e-mails zijn. Maar je kan slechts één account in de gaten houden en ondertussen beschik ik over vier Gmail-accounts; 2 normale en 2 via Google Apps. Tijd voor iets beters dus. Tijd voor Morse.

Morse screenshot

Ik wilde al een tijdje wat nuttigs maken met Adobe AIR en dat is Morse geworden. Het is de bedoeling om Morse gratis te verspreiden, maar aangezien ik de enige ben die er tot nu toe wat mee heeft gespeeld, zou de applicatie nog wat getest moeten worden door anderen. Personen die de dingen wat anders aanpakken dan ik, vooral met Windows werken (de applicatie is momenteel vooral afgestemd op Windows) en niet panikeren als de applicatie zou ontploffen.

Update: gebruikers van OS X mogen me nu ook iets laten weten. Als je Sifter eens wil uittesten mag je dat ook vermelden.

Jij misschien? Reageer dan hier of stuur me een e-mail. Uw hulp zou welkom zijn.

Dit artikel werd opgenomen in ontwikkeling, software.


Even tussendoor

Soms geloof ik niet in toeval.


Drie opties; minstens één te veel

Tabelnamen in MySQL zijn niet noodzakelijk case insensitive. Zo komt de tabel POSTS niet per se overeen met de tabel posts. Op Windows wel. En op OS X ook. Maar op Unix niet. Tenzij je de lower_case_table_names variabele aanpast. Deze heeft 3 mogelijke opties: 0 (default op Unix), 1 (default op Windows), 2 (default op OS X).

Wacht, is dat nu geen overkill? Ofwel zijn de namen case sensitive, ofwel niet. Toch?

Ha, maar er is een ander gevolg van de gekozen optie: hoe wordt de tabelnaam opgeslagen. Lowercase? Zoals je hebt gespecifieerd bij het aanmaken van de tabel?

De 3 opties:

0 (Unix): naam opslaan zoals gespecifieerd, case sensitive vergelijking 1 (Windows): naam opslaan in lowercase, case insensitive vergelijking 2 (OS X): naam opslaan zoals gespecifieerd, case insensitive vergelijking

Kom dat zien. Even ervan uitgaan dat je een default installatie hebt op de 3 bovenstaande besturingssystemen en dat je volgende tabel maakt:


CREATE TABLE BLA(id int);

Dan zal deze query werken op Windows en OS X, maar niet op Unix:


SELECT * FROM bla;

Yup, this sucker bit me in the ass today.

Dit artikel werd opgenomen in ontwikkeling.


Active links in Django

Django. Django. Nog eens? Django! Het is een geweldig framework, maar bij ieder framework zal je moeten vaststellen dat je wat mist.

Het probleem

De link voor de huidige pagina moet verdwijnen of er tenminste anders uitzien. Django komt niet met een directe oplossing en de meest relevante andere oplossing werkt met hardcoded paths. De beste oplossing zou zijn om met named URLs te werken.

Stel je voor dat dit de URL patterns zijn:


urlpatterns = patterns('',
    url(r'^archive/(?P\d{4})/(?P\d{2})/(?P\d{2})/$’,
        ‘proj.app.views.archive_for_a_day’,
        name=’proj_app_archive_for_a_day’),
    url(r’^search/$’,
        ‘proj.app.views.search’,
        name=’proj_app_search’),
)

In mijn menu wil ik linken naar het archief voor een bepaalde dag en de zoekpagina. Maar als ik op één van die pagina’s ben wil ik dat het list item met de overeenkomstige link de class active krijgt. Zoiets:


<ul>
    <li{{ request|on_active_link:"proj_app_archive_for_a_day,active" }}>
        <a href="{%url proj_app_archive_for_a_day year,month,day %}">Archive</a>
    </li>
    <li{{ request|on_active_link:"proj_app_search,active" }}>
        <a href="{%url proj_app_search %}">Search</a>
    </li>
</ul>

De oplossing

Die volgt uit 2 eenvoudige template filters:

matches_url_pattern zal True teruggeven bij een match, waardoor die kan gebruikt worden met een {% if %} om de link te verwijderen on_active_link, uit bovenstaand voorbeeld, zal het tweede argument gebruiken als een class indien de naam van de URL pattern (het eerste argument) overeenkomt met het request path.

from django import template

register = template.Library()

@register.filter(name='matches_url_pattern')
def matches_url_pattern(value,args):
    return is_path_a_match_for_named_url(value, args)

@register.filter(name='on_active_link')
def on_active_link(value,args):
    parts = args.split(',')
    if is_path_a_match_for_named_url(value, parts[0]):
        return ' class="%s"' % parts[1]
    return ''

def is_path_a_match_for_named_url(request, named_url):
    from django.core.urlresolvers import get_resolver, Resolver404
    resolver = get_resolver(None)
    path = request.path
    tried = []
    match = resolver.regex.search(path)
    if match:
        new_path = path[match.end():]
        for pattern in resolver.urlconf_module.urlpatterns:
            try:
                sub_match = pattern.resolve(new_path)
            except Resolver404, e:
                tried.extend([(pattern.regex.pattern + '   ' + t) for t in e.args[0]['tried']])
            else:
                if sub_match:
                    return pattern.name == named_url
    return False

De laatste functie vergt het meeste uitleg. is_path_a_match_for_named_url gebruikt code die overgenomen is van de RegexURLResolver. Deze kan bepalen welk URL pattern met het huidige request path overeenkomt, maar biedt in de huidige versie geen mogelijkheid om de naam van dat pattern te achterhalen. Vandaar deze kopie die wel kan checken of de naam van het gevonden pattern overeenstemt met de gegeven parameter.

Het resultaat

Stel nu dat ik ben beland op /search/. De HTML zal er als volgt uitzien:


<ul>
    <li>
        <a href="/archive/2008/07/21/">Archive</a>
    </li>
    <li class="active">
        <a href="/search/">Search</a>
    </li>
</ul>

Een mooiere oplossing voor dit probleem zal de filters vervangen door tags en geen expliciete verwijzing naar de request variabele nodig hebben.

Dit artikel werd opgenomen in ontwikkeling.


Even tussendoor

This page contained an embedded video. Click here to view it.

Even tussendoor

Nee. Dit is geen echte verbetering.



You are viewing a mobilized version of this site...
View original page here

How do you rate mobile version of this page?

Mobilized by Mowser Mowser