Tredje gången gilt. Börjar bli en rolig tradition det här med att komma runt SVDs betalvägg. Nu har de börjar slänga in flera olika funktioner med snarlika namn och lite annat roligt trixande – ingen mer for-loop då alltså.
Istället så spinner vi vidare på det reguljära uttrycket (tack igen, @Wibron!), och laddar in en extern fil – så slipper man uppdatera det där bokmärket om och om igen. Filen ligger på GitHub – kom gärna med en “pull-request” om ni upptäcker att mönstret har ändrats eller om ni vill förbättra den.
Lär i alla fall fungera fram tills att SVD gör allt för stora ändringar.
Och som vanligt, ett bokmärke (dra och släpp länken till bokmärkesfältet): Läs artikel.
Notera att detta är mest som en rolig sak, garanterar inte alls att det här fungerar för alltid. Och är du en frekvent SVD-besökare som absolut inte vill ha något med betalväggen att göra, då är det bästa alternativet att rensa alla kakor för webbplatsen.
Idéer på hur man gör det här på ett bättre och/eller mer effektivt sätt? @olssonm heter jag på Twitter.

Uppdaterad 17/5 2013: Än en gång har SVD ändrat i sin betalvägg. För den allra nyaste, och förhoppningsvis sista, metoden för att komma runt betalväggen, läs Kom runt SVDs paywall – för sista gången.
Svenska Dagbladet verkar visst ha fixat sin betalvägg något (som var lite väl vek, som jag skrev om senast), nu kan man inte längre komma runt den genom att endast köra:
svd_pw_close();
Nu har de börjat trixa med en slumpmässig sträng som läggs till i funktionen, så nu ser den ut på följande sätt:
svd_pw_close_298718();
Det blir ju lite krångligare nu när det finns ett slumpmässigt element inblandat; strängen slumpas t.o.m. mellan sidladdningar (alltså inte beroende av någon cookie som man kan läsa av eller liknande).
Hur löser vi det här nu då? Då strängen slumpas, så kan vi så klart gå igenom varje möjlig variant (som tur är består strängen endast av siffror, för stunden):
for (var i = 999999; i >= 0; i--) {
if(typeof(window['svd_pw_close_' + i]) == 'function') {
window['svd_pw_close_' + i]();
}
};
Här har du ett smidigt bokmärke som du kan använda (dra och släpp i bokmärkesfältet): Läs artikel
En annan variant är att köra hela innehållet i svd_pw_close_xxx();, alltså:
jQuery(window).unbind("scroll", svd_pw_prev_scr);
jQuery("#page").css("height", "auto");
jQuery(".svd_pw_alert_box").animate({
top: -500,
}, 500, function () {
jQuery("#svd_pw_alert").hide();
jQuery("#svd_pw_curtain").hide();
jQuery("body").removeClass("svd_pw_freeze");
});
Även till denna får du ett trevligt litet bokmärke: Läs artikel
Sist men inte minst, man kan även rensa alla cookies för domänen. Se t.ex. det här bokmärket från en på Stackoverflow.
Mycket bättre SVD! Men lite till kan ni allt. Men tyvärr så kommer betalväggen förmodligen alltid att kunna kringgås så länge som det förlitas på javascript på klienten.
Uppdaterad 13/5 2013: Patrik Wibron (@wibron) var snäll nog att dela med sig av en kodsnutt som är betydligt mer effektiv (och snyggare) än den gamla for-loop:en här ovanför:
for (d in window) {
var r = /svd_pw_close\d/i,
method = d.match(r);
if (method) window[d]();
}
Även den får ett behändigt bokmärke: Läs artikel.
För modiga Linux-användare:
[ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo *Click*
Bör absolut inte provas på OS X…
Via Stackoverflow
Nyhetsbrev, eller “Mailing lists”, är kanske inte lika vanliga idag som förr. Men Wes Mason sammanställer varje vecka ett fantastiskt matnyttigt sådant där han samlar länkar om nyheter i PHP-världen. Även intressanta projekt och artiklar finns med.
Programmera digitala robotar med Javascript. Väldigt kul, beroendeframkallande och lärorikt.
Jag nämde i mitt tidigare inlägg om att PHP fortfarande är störst “microramverket” Flight som jag har använt mig av en hel del på sistone.
Likt Flask, Sinatra och för all del Slim – är Flight ett enkelt ramverk som är gjort för att byggas vidare på helt efter tycke och smak.
Flight är väldigt “barebone” i standardutförande, du får inte så mycket mer en enkla metoder att route:a trafik och ett mycket grundläggande template-språk. Men med php-activerecord och Twig så blir Flight en perfekt start för både små och mellanstora webbapplikationer.
Börja med att sätta upp en struktur liknande det här:

Nu ska vi använda composer för dra in Flight, php-activerecord och Twig till vårt projekt. Alla finns på Packagist, så skapa en composer.json-fil som ser ut ungefär så här:
{
"require": {
"twig/twig": "1.*",
"mikecao/flight": "dev-master",
"php-activerecord/php-activerecord": "dev-master"
}
}
Dra sedan ner composer till ditt projekt:
$ curl -s http://getcomposer.org/installer | php
Och installera modulerna (notera att du måste ha Git installerat):
$ php composer.phar install
Släng också in en .htaccess-fil (om du använder Apache):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Nu borde du ha allt installerat i /vendor, och vara redo för att skriva lite PHP!
Skapa en index.php i projektmappen och inkludera composer:ns autoload.php. Testa sedan att med Flight skapa et route till /test:
<?php
include dirname(__FILE__) . '/vendor/autoload.php';
Flight::route('/test', function(){
echo "hello world!";
});
Flight::start();
På localhost/test (eller hur du nu har din miljö uppsatt) bör du kort och gott se “hello world!”.
Nu kommer det roliga, att få alla delarna att leka snällt med varandra. Börja med att konfigurera upp Twig:
<?php
/**
* Initiate Twig, and register to Flight
*/
$loader = new Twig_Loader_Filesystem(dirname(__FILE__) . '/views');
$twigConfig = array(
// 'cache' => './cache/twig/',
// 'cache' => false,
'debug' => true,
);
Flight::register('view', 'Twig_Environment', array($loader, $twigConfig), function($twig) {
$twig->addExtension(new Twig_Extension_Debug()); // Add the debug extension
});
På detta vis når vi nu Twig via
<?php
Flight::view()->display('template.html', $data);
Testa så att allt fungerar genom att skapa en mall och lägg den i din views-mapp.
<?php
// template.html
hello {{name}}!
// index.php
Flight::route('/hello', function(){
$data = array(
'name' => Flight::request()->query->name
);
Flight::view()->display('template.html', $data);
});
localhost/hello?name=Marcus borde ge “hello Marcus!”.
Nu var det php-activerecord också. Om du har använt CodeIgniter eller Lithium så är chanserna stora att du har använt något derivat av php-activerecord, så du borde känna igen syntaxen – det är anledningen till att jag brukar köra på det. Men om du föredrar något annat ORM, kör för all del på det istället. För att ladda in det i Flight gör vi på följande vis:
<?php
/**
* Initiate ActiveRecord
*/
ActiveRecord\Config::initialize(function($cfg) {
$cfg->set_model_directory('./models');
$cfg->set_connections(
// mysql://
array('development' => 'mysql://username:password@localhost/database')
);
$cfg->set_default_connection('development');
});
För det här testet kan vi använda en väldigt enkel users-tabell:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(255) COLLATE utf8_swedish_ci NOT NULL,
`surname` varchar(255) COLLATE utf8_swedish_ci NOT NULL,
`email` varchar(255) COLLATE utf8_swedish_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci AUTO_INCREMENT=1 ;
Sätt också upp en user-modell i /models:
<?php
class User extends ActiveRecord\Model {
}
Nu borde du enkelt kunna skapa en ny användare genom:
<?php
$user = new User();
$user->firstname = 'Marcus';
$user->surname = 'Olsson';
$user->email = 'trash@thedumpster.com';
$user->save();
print_r(User::last());
// User Object
// (
// [...]
// [attributes:ActiveRecord\Model:private] => Array
// (
// [id] => 1
// [firstname] => Marcus
// [surname] => Olsson
// [email] => trash@dumpster.com
// )
// [...]
// )
Det var allt egentligen – du har nu grunden för att snabbt kunna skapa en riktigt bra webbapplikation. Om du undrar varför vi satte upp /controllers i början är det för att man inte ska behöva ha allt i sin index.php – utan man kan mappa en route till en controller och metod, likt:
<?php
// index.php
Flight::path(dirname(__FILE__) . '/controllers');
Flight::route('/', array('IndexController', 'index'));
// controllers/indexController.php
class IndexController {
public function __construct() {}
public static function index() {
echo 'Hello world!';
}
}
Hela den här guiden finns på GitHub för den som är intresserad, och jag är mer än intresserad av att höra vad du tycker om Flight, och andra microramverk för den delen.
Kollade igenom lite statistik på W3techs över de vanligaste server-side språken i bruk idag. PHP är fortfarande överlägset störst. 78.7% av alla webbplatser drivs av PHP, och inte nog med det – språkets popularitet har dessutom ökat, upp från 72,5% i mars 2012.
PHP har aldrig tidigare varit ett sådant spännande språk att arbeta med, nya ramverk hittar nya lösningar på problem. Och ramverk som Slim och Flightphp gör det enkelt och snabbt att sätta upp nya projekt så att man istället kan fokusera på det viktiga. Även i själva PHP-core händer det en rad ändringar och förbättringar.
Flera nya tjänster och plattformar som t.ex. Fortrabbit och Pagoda Box har gjort det enkelt att driva, underhålla, testa och lansera sina applikationer med enkla och smarta metoder.
PHP är ofta något av ett hånat – kanske till och med ett ibland hatat språk, med ibland viss rätt. Men med det faktumet att nästan vem som helst kan snabbt och enkelt få ut hello world! på ett par minuter på vilket webbhotell som helst – det är nästintill oslagbart.
Därmed är det inte sagt att andra språk är dåliga, eller ens sämre (Python är ett språk som jag verkligen gillar). Men PHP får oförtjänt mycket smuts kastat på sig.
Det här problemet uppkommer jämt och ständigt, hur skriver man benämningen på den utvecklaren som arbetar med de delarna av webben som användaren använder?
Jag har sett en rad olika alternativ, där frontendutvecklare och frontend-utvecklare förmodligen är de två vanligaste, följt av front end-utvecklare. Men vad är egentligen rätt?
För att reda ut det här så behöver vi börja med den engelska delen, “front end”.
I engelskan så slår man inte alls ihop ord lika ofta som i svenskan, och man kan följa de här skrivreglerna för att se vad som är rätt. Under “Rule 1” ser man att:
To check whether a compound noun is two words, one word, or hyphenated, you may need to look it up in the dictionary. If you can’t find the word in the dictionary, treat the noun as separate words.
Efter en sökning på wiktionary så ser man att alla tre formerna, front-end, front end och frontend, visserligen återfinns. Men endast front end listas som en icke-alternativ form. Därför bör man se den som det rätta.
Även på Merriam Webster så står front end med beskrivningen:
1: a unit in a computer system devoted to controlling the data communications link between terminals and the main computer and often to the preliminary processing of data
2: a software interface (as a graphical user interface) designed to enable user-friendly interaction with a computer
Där frontend endast rättar till front end.
Det var den engelska delen, den svenska är betydligt lättare – i svenskan skriver man som bekant ihop utländska ord med ett svenskt med hjälp ev ett bindestreck, t.ex. helpdesk-medarbetare.
Rätt torde således vara front end-utvecklare.
Uppdaterad 27/9-2012
Upptäckte en intressant sak i sökresultaten dessutom:

LOLCODE is an esoteric programming language inspired by the language expressed in examples of the lolcat Internet meme.
Lite kod saxat från Wikipedia-sidan:
HAI
CAN HAS STDIO?
PLZ OPEN FILE "LOLCATS.TXT"?
AWSUM THX
VISIBLE FILE
O NOES
INVISIBLE "ERRROR!"
KTHXBYE
Och om man vill testa lite i en Javascript-tolk: fullvolume.co.uk.
Via Ella Källman (@fruktparty)
Som jag tidigare har skrivit så är programmering verkligen mitt stora intresse – ofta är det själva problemlösningsaspekten jag gillar extra mycket.
De senaste två veckorna har jag för min nuvarande arbetsgivare Prognosia (notera att jag inte har något att göra med den nuvarande webbsidan att göra – där kommer du dock snart att hitta något vackert!) där jag ställdes inför en rad intressanta problem som jag var tvungen att lösa.
För applikation jag byggde så skulle jag hämta data från en server (hade självklart tillåtelse att hämta och använda datan) som inte erbjöd ett API – så jag var tvungen att använda cURL för att posta data, hämta HTML:en och gå igenom DOM:en för att få hem den datan som är relevant.
SQL-frågan som körs vid varje cURL-anrop är dock ett väldigt tungt sådant, och jag behöver ny data var 10:e sekund – applikationen skulle dessutom kunna köras på oändligt många klienter samtidigt. Detta blir självfallet ett problem då om applikationen körs på exempelvis 50 klienter samtidigt, och postar samt hämtar data var 10:e sekund (300 anrop i minuten) – jag vill självklart inte sänka målservern, det gör ingen populär.
Hur man (eller i alla fall jag) vanligtvis skulle hämta datan:

Så för att inte sänka målservern fick jag köra på den här varianten:

Så långt är frid och fröjd. Men då kommer nästa problem. För att få vår egna servrar att hämta data var 10:e sekund så går det inte att använda sig av cron-jobb – de går endast att köra varje minut som lägsta interval (går visserligen att lägga det som ett bakgrundjobb med en “sleep”). Men dessutom tyckte jag att det vore smidigt om ingen data hämtades om inga klienter körde applikationen.
Så jag designade applikationen på det här viset:

Kort förklarat: på klientsidan genererar jag ett unikt ID (eller i alla fall strängkombination av siffror och bokstäver med ett par miljoner olika kombinationsmöjligheter), skickar det ID:t till servern – och om ID:t kommer från “huvudklienten”, hämta datan från målservern och skriv datan till en JSON-fil. Som svar på anropet kommer också JSON-formaterad data som talar om status och en rad andra parametrar.
Om statuskoden exempelvis är 2 (som betyder sekundär klient), läses av JSON-filen av varje sekund (jag vill ju att alla klienter ska vara någorlunda synkade), eller om statuskoden är 1 (huvudklient) räcker det att läsa JSON-filen när anropet till den egna servern är slutförd.
I JSON-filen som datan skrivs till sätter jag också en tidsstämpel när den skrevs, och vilket ID klienten hade som huvudklient vid det tillfället. Då kan jag lätt se om jag behöver byta huvudklient (om den användare vars klient är huvudklient stänger sin webbläsare exempelvis), vilket i det här fallet görs om filen är äldre än 20 sekunder.
JSON-filen med data läses in på klienten via AJAX, och datan renderas med mustache.js – snabbt, snyggt och elegant.
Resultatet är en applikation (som endast används internt) som jag faktiskt är lite extra nöjd med – just för att det var en rad intressanta problem som var tvugna att lösas.
Har du någon idé på hur jag skulle kunna ha löst det här annorlunda, eller egna lösningar på andra problem som du är extra nöjd över? Hojta till på Twitter!
Att blogga må vara lätt, ännu lättare är det att hitta en plats att blogga på. Wordpress finns på Wordpress.com, Google har Blogger och sedan finns det en hel drös med mindre aktörer och t.o.m. tidningar som tillhandahåller egna bloggplattformar.
Men jag är lite märklig, jag nöjer mig inte med den enkla vägen. Jag gillar när saker och ting fungerar på mitt sätt, och erbjuder en möjligheten till att gå utanför ramarna.
Wordpress är förmodligen det bloggverktyget som flest människor känner till, och som flest webbplatser använder. Möjligheterna med Wordpress är oändliga, och skulle du springa på ett problem så är du bara en Google-sökning ifrån lösningen. Likaså med insticksmoduler (eller “plugins”). Men Wordpress är stort och “bloated” – en vanlig användare använder förmodligen inte mer en 10% av vad Wordpress är kapabelt till.
2006 skapade jag min första Wordpress-blogg, en egenhost:ad sida där jag hade min resedagbok i (under tiden jag studerade i Japan), därefter har det blivit otaliga fler – bland annat så använde jag det tidigare här på marcusolsson.me (och ännu tidigare på marcus-olsson.com) som jag började blogga på 2009.
Ganska omgående kände jag dock att Wordpress inte alls passade min typ av bloggande. Att göra ändringar var irriterande, plugins som man ville använda fungerade inte riktigt så som jag ville – och ofta var kodkvalitén så dålig i dem att det var lättare att skriva ett eget plugin än att ändra i dem. Därefter följde flera år med en närmast tvångsaktig idé att hitta ett bloggverktyg som jag verkligen gillar.
Först ut var Chyrp. Exakt hur jag hittade dem vet jag inte, men gillade deras webbsida (samma då som nu) så jag tänkte att man kanske skulle ge dem en chans…? Tyvärr så var dokumentationen nästintill obefintlig, och communityt likaså – men jag fick igång en fungerande blogg som jag var hyfsat nöjd med, men skapelsen fick aldrig hamna på den världsvidda webben – jag hade fått upp ögonen för något nytt och spännande.
(Chyrp.net)
Posterous tyckte jag till en början verkade vara det perfekta bloggverktyget – och man behöver inte bry sig om att host:a den själv. Ungefär samtidigt kom även Tumblr (som har rönt större framgångar än Posterous) som jag testade ett tag. Men de här molntjänsterna var nästintill omöjliga att anpassa till hur man själv ville ha dem, och i alla fall då hade de ett riktigt dåligt gränssnitt för att ändra i CSS:en om man ville göra en sådan enkel sak.
Squarespace.com var en annan molntjänst som i alla fall bjöd på ett stort antal alternativ på hur man kunde anpassa sin webbplats – men priset var för högt för min dåvarande budget, och 2008 så var det en ganska buggig, långsam och instabil tjänst (deras alldeles nyutkomna version 6 är riktigt bra dock).
(Squarespace)
Någon gång 2009 kom jag på den briljanta idén att skriva min egen plattform där jag själv kunde styra och ställa hur jag ville att saker och ting skulle fungera. Detta slutade i fiasko två gånger om. Den första versionen var någon typ av “mishmash” av ett eget MVC-ramverk inspirerat av det jag lärde mig när jag satt och hackade i Chyrp – resultatet var inte bra någonstanns. Något år senare och så använde jag ramverket Lithium och skapade en helt okej och väl fungerande plattform – men jag kom på nya idéer som jag ville ha med hela tiden, och ville gärna göra det möjligt för andra att använda och anpassa plattformen. Jag råkade ut för Wordpress-syndromet där 10% av koden var nödvändig, och resten var lull-lull (en tidig version ligger uppe på Github). Alldeles för tungt och onödigt att dra in ett helt PHP-ramverk för att publicera en (relativt) simpel blogg.
2012 var året då jag slutgiltligen skulle ta tag i problemet (jag såg det faktiskt som ett sådant), det blev ett frenetiskt experimenterade med olika språk, plattformar och ramverk. Jag hade blivit besatt av tanken att generera statiska html-sidor, snabbt skulle det gå. Jekyll, Octopress och Phrozn var ett par jag testade – men jag tyckte att de antingen hade för få features, eller för många som gjorde även dem bloated.
Men till sist – äntligen – så hittade jag SecondCrack av Marco Arment. Stundtals extremt buggigt, men otroligt simpelt och lättviktigt (cirka ett dussin filer för hela plattformen, exklusiva externa bibliotek så som Markdown) och dessutom har det en rad smarta funktioner så som publicering via Dropbox.
SecondCrack är långt ifrån perfekt, och jag har själv fått göra en rad ändringar för att få det så som jag vill, men nu sitter jag i alla fall med en plattform som jag är nöjd med – men hur länge det varar vet man aldrig.
Vad vill jag få sagt med den här texten egentligen då? Ingenting särskilt egentligen (tack för att du läste i alla fall) – bara att det är väldigt svårt att hitta en bloggplatform som passar mig.
Att göra ändringar i CSS:en kan vara irriterande då webbläsaren inte alltid känner för att hämta om CSS-filen. Detta kan vara väldigt problematiskt om man uppdaterar CSS:en på en sida som redan ligger live – hur kan man säkerhetsställa att alla användare ser uppdateringen omgående?
Ett väldigt bra knep är att lägga till en parameter på css-filen, likt:
<link rel="stylesheet" href="style.css?ver=1" />
När du sedan har uppdaterat CSS:en så uppdaterar du versionsnumret till exempelvis 2, sedan 3 o.s.v.
Har du ett projekt där du programmerar med PHP så kan man även på ett väldigt smart sätt utnjyttja funktionen filemtime(); (php.net) som talar om senast en specifik fil uppdaterades. Så här skulle ens PHP-kod kunna se ut:
$cssUpdateTime = filemtime('style.css');
$stylesheet = 'style.css?ver=' . $cssUpdateTime;
<link rel="stylesheet" href="<?= $stylesheet ?>" />
<!--
Ger något i stil med:
<link rel="stylesheet" href="style.css?ver=1345061074" />
-->
Så varje gång du uppdaterar CSS-filen så uppdateras “versionsnumret”, och besökarnas webbläsare tolkar det som en ny URL till CSS-filen som den måste hämta om.
var_dump() är PHP-utvecklarens bästa vän för att kika in i en variabel och se exakt vad den innehåller (objekt, sträng eller vad det nu är) – om man nu inte använder exempelvis Xdebug.
Men låt oss säga att man vill spara undan datan i en sträng, och inte bara dumpa ut den så fort som funktionen var_dump() körs – kanske för att undvika “Cannot modify header information - headers already sent”” – hur gör man då? Jo, som följande:
$variable = array(
'value1' => 1,
'value2' => 2,
'value3' => 3
);
// Startat "output buffer"
ob_start();
// Dumpar ut värdet av $variable
var_dump($variable);
// $result = datan i bufferten, och rensar upp
$result = ob_get_clean();
// Gör en massa andra saker
// Eka ut datan
echo("<pre>" . $result . "</pre>");
// Resultat
array(3) {
["value1"]=>
int(1)
["value2"]=>
int(2)
["value3"]=>
int(3)
}
Detta ska förmodligen dock användas sparsamt då det både blir förvirrande med allt för många förekomster i koden (när man inte har koll på om output bufferten är igång eller inte etc.) samt att påverkar prestandan något. Men för att underlätta jakten på buggar – varför inte?
En ny rolig sak som vi webbutvecklare har tillgång till i OS X Mountain Lion är notifikationer “till skrivbordet”.
Notifikationer via webbläsaren har funnits en längre tid (i alla fall i Chrome och Safari), men i och med Notification Center så får vi en rad nya möjligheter då man kan skicka notifikationer som likt Twitter, Mail.app och andra applikationer dyker upp på skrivbordet, och placeras snyggt och prydligt i Notification Center.

Här har jag satt upp ett demo. För kod, läs vidare.
Det hela är väldigt enkelt:
$(document).ready(function(){
if (window.webkitNotifications) {
console.log("Din webbläsare stödjer notifikationer");
} else {
console.log("Din webbläsare stödjer inte notifikationer... =( ");
}
function check_permission() {
if(window.webkitNotifications.checkPermission() === 0) {
return true;
} else {
return false;
}
}
$('.permission').click(function(e){
e.preventDefault();
window.webkitNotifications.requestPermission(check_permission);
});
$('.display').click(function(){
if(check_permission()) {
var message = 'Mitt meddelande'
var notification = window.webkitNotifications.createNotification(null,'En notifikation',message);
notification.show();
} else {
alert('Du måste ge tillåtelse att ta emot notifikationer');
}
});
});
Det fanns en märklig skillnad mellan Chrome och Safari som jag upptäckte, och det var att Safari kräver en callback på window.webkitNotifications .requestPermission() (därav check_permission-funktionen), annars verkar det inte vara några större skillnader.
Notera också att det inte går att köra notifikationer lokalt, direkt från en HTML-fil, utan det måste gå via en server – annars kommer du att råka ut för en “SECURITY_ERR: DOM Exception 18”.
Igen, för att se ett fungerade exempel och läsa mer, kika in den här sidan som jag har satt upp. Läs gärna också den här artikeln hos html5rocks.com som också visar hur man kan fylla en notifikation med egen html-kod. Dessa typer av notifikationer verkar dock inte placeras i Notification Center.
Kan tänka mig en hel del intressanta användningsområden för detta, live-bloggar vore ett, likaså en rolig och användbar funktion som Twitters webbklient skulle kunna använda sig av.
When you really want to run horrible javascript code
Helt fantastastisk.
Lithium (även känt som li3) är det ramverket jag oftast väljer då när jag ska göra en webbapplikation, då det är snabbt och enkelt att komma igång – och till skillnad från exempelvis CodeIgniter har du väldigt stor frihet hur man vill gå tillväga.
Nu på torsdag (26/7) 19:00 kommer chefsutvecklaren Nate Abele att hålla i en “webinar” där han går igenom vad som får Lithium att stå ut ifrån mängden, via Engineyard.
Ett hett tips till den som vill ta en titt på ett lite mindre känt php-ramverk.
Intressanta företag fortsätter att kontakta mig efter min bloggpost om att jag söker jobb, vilket är jättekul – en majoritet är förvisso i Stockholm, men har varit och träffat några här på hemmaplan.
Ett par märkliga förslag får man dock på köpet.
Inte mindre än tre personer har hört av sig med förslag på att jag ska utveckla en ny webbplats åt dem helt gratis de senaste två veckorna. Två av dessa har erbjudit mig en andel i sina företag (som de ännu inte startat), och de hade båda en idé som de “tror jättemycket på” och som garanterat skulle ge mig mycket pengar. Båda dessa drev redan framgångsrika företag inom andra brancher hävdade de – men vill nu sikta in sig på något annat. Om man redan driver ett framgångsrikt företag, kan man då inte offra den relativt lilla summan som det kostar att anlita en webbutvecklare?
Den tredje var nästintill ännu värre, han representerade en webbyrå som behövde ett par plugins till Wordpress åt en kund – om jag kunde leverera detta inom en vecka skulle han eventuellt erbjuda mig en intervju. Okej med arbetsprover – men kom igen?
Jag jobbar inte gratis, vilket jag tror och hoppas på att de flesta utvecklarna inte gör. Det råder knappast brist på jobb inom branchen, vi är inte desperata.
P.S. Jag skriver under inga omständigheter under en NDA om jag inte först har träffat dig.
Jag har tidigare skrivit om hur man kan spåra klick med Google Analytics, men den koden byggde på att man manuellt lade till en onClick-funktion på varje klick man vill spåra.
Den här koden däremot har jag skrivit specifikt för att spåra klick på utgående länkar, mest för att jag är nyfiken på om folk faktiskt klickar på alla de länkarna jag postar i mina blogginlägg. Att använda mig av onClick här var inget alternativ, då jag skriver mina blogginlägg med markdown, och det vore väldigt onödigt att skriva ut alla a-taggar manuellt. Plus att det är inte direkt vackert.
Koden är skriven i “ren” Javascript, då jag fortfarande försöker att inte dra in några Javascript-bibliotek i onödan på den här webbsidan.
Koden i sig är så enkel som den går att bli:
function trackClick(event) {
if(location.href.replace("http://").replace("https://").split("/")[0] !== this.href.replace("http://").replace("https://").split("/")[0]) {
_gat._getTrackerByName()._trackEvent('Outbound links', this.href);
}
}
window.onload = function() {
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', trackClick, false);
};
}
Notera att addEventListener inte fungerar för Internet Explorer 8 och lägre, utan man får använda sig av attachEvent('onclick', trackClick) istället – men då får man också problemet med att this refererar till window-objektet, och inte det elementet som användaren klickar på (a-taggen). I besöksstatistiken så ser jag dock Internet Explorer 8 står för mindre än 1,5% av besökarna – så jag förbiser dem för stunden (dåligt av mig, jag vet).
Statistiken finner du sedan i Google Analytics under Content -> Events.
Ser du något som inte stämmer, eller som kan göras bättre? Hojta till på Twitter!
Igår när jag skulle posta ett inlägg som innehöll många Youtube-klipp stötte jag på problemet att om man t.ex. via en iPhone gick in på sidan så såg iframe-elementen på tok för höga ut (blev svarta lister under och över själva klippet). Att anpassa en iframe på bredden är inte särskilt svårt med hjälp av CSS:
iframe {
max-width: 100%;
}
Men på höjden kan vara lite tuffare.
Man kan visserligen förlita sig helt på CSS för att anpassa t.ex. ett Youtube-klipp responsivt också, som i det här exemplet. Men då jag använder markdown för att posta min inlägg på den här bloggen så vill jag inte behöva lägga in en massa div-taggar i onödan. Vidare så försöker jag undvika att dra in bibliotek så som jQuery på sidan – så jag skrev det här mycket enkla skriptet som använder den klassiska “förhållningsregeln” (xa förhåller sig till ya så som xb förhåller sig till yb) från gymnasiematten:
function resizeFrames() {
var iframes = document.body.getElementsByTagName('iframe');
var mainDiv = document.getElementById('main');
var elementHeight;
var elementWidth;
var realHeight;
var realWidth;
for (var i = 0; i < iframes.length; i++) {
elementWidth = iframes[i].width;
elementHeight = iframes[i].height;
realWidth = mainDiv.offsetWidth;
realHeight = iframes[i].offsetHeight;
iframes[i].width = realWidth;
iframes[i].height = ((realWidth*realHeight) / elementWidth);
};
}
window.onload = function() {
resizeFrames();
}
Och som en liten bonus, om man använder en design som är “fluid” kanske man vill att funktionen ska exekveras varje gång som användaren ändrar storleken på webbläsarfönstret.
window.onresize = function() {
resizeFrames();
}
För att se ett demo “in action” kan du kolla in det här inlägget.
Värt att notera är att om man ökar och minskar webbläsarfönstret flera gånger så kommer till slut måtten att sluta stämma, då flyttal inte används – men det duger gott och väl till de flesta ändamålen.
Ser du något som inte stämmer, eller som kan göras bättre? Hojta till på Twitter!
När man skickar variabler till en funktion i PHP brukar man som bekant skriva likt på detta vis:
function addition($number1, $number2, $number3) {
}
Och om man vill att de variablerna ska ha ett standardvärde i funktionen:
function addition($number1 = 10, $number2 = 20, $number3 = 30) {
}
Dock så blir detta väldigt plottrigt efter ett tag, men det finns ett väldigt effektivt sätt att använda arrayer för samma syfte.
function addition($numbers = array()) {
$default = array(
'number1' => 10,
'number2' => 20,
'number3' => 30
);
$numbers += $default;
}
Nu skickar vi $numbers som en array istället. Och i och med
$numbers += $default; slår vi ihop de två arrayerna – och de nycklarna som saknar värde får ett från $default. Väldigt användbart i de fallen man skriver metoder som ska kunna ta emot många variabler, men vill samtidigt ha möjligheten att använda standardvärden (defaults). Snyggt, bra och enkelt.