Så gjorde vi det mobila Almedals­programmet

Text:

Att utveckla för mobila webbläsare är, de många moderna funktionerna till trots, på många sätt som att resa tillbaka till slutet av 1990-talet. Mobilernas begränsningar gällande minne, processor, skärmupplösning och framförallt överföringshastighet påminner om den plats skrivbordsdatorer befann sig på när de fortfarande kommunicerade via uppringningsmodem.

Den stora skillnaden utöver storleken är att mobila webbläsare inte kör fax-fanfaren varje gång de kopplar upp.

För mig, som vanligtvis är bortskämd med bandbredd, har det varit en stor utmaning och väldigt lärorikt att få almedalssajten att köra i en komfortabel hastighet. I vissa telefoner är den kanske inte riktigt där än, i andra är det efter en hel del optimering faktiskt riktigt snabbt.

Så mitt viktigaste tips efter att ha pysslat med det här är att ta bort allt som inte är absolut nödvändigt. Stryk den där roliga funktionen som bara hälften av alla kommer använda.

Allt utöver det nödvändigaste gör sajten långsammare, mer svårnavigerad och kostar dyrt ur användbarhetssynpunkt.

Hantera datan

Eftersom vi gillar Wordpress väldigt mycket har vi använt det till publiceringen på almedalen.fokus.se. För att hantera den stora mängden innehåll i almedalsprogrammet på ett strukturerat sätt gjorde vi egna taxonomier. Jag har tidigare skrivit om det här, men det tål att upprepas.

Sätt upp dina taxonomier i functions.php:

 false, 'label' => 'Plats', 'query_var' => true, 'rewrite' => true ) );
	register_taxonomy( 'organizer', 'post', array( 'hierarchical' => false, 'label' => 'Arrangör', 'query_var' => true, 'rewrite' => true ) );
	register_taxonomy( 'organisation', 'post', array( 'hierarchical' => false, 'label' => 'Organisationstyp', 'query_var' => true, 'rewrite' => true ) );
}
?>

Nu kan vi utöver inläggsetiketter även sortera innehåll efter plats, arrangör och organisationstyp. Detta är i enlighet med »stryk det«-principen inte utgjort som navigeringsmöjligheter för användaren, men som strukturerad data är det superanvändbart i en massa andra sammanhang. Till exempel behövs det till Kart- och Twitter-integrationen.

Eftersom man måste kunna kolla alla evenemang, framförallt de som ännu inte har ägt, och evenemangen använder publiceringsdatumet (post_date) som tidsangivelse behöver vi få Wordpress att visa opublicerade inlägg. Återigen i functions.php:


Detta trollar om alla inlägg till att ha "publish" som post_status, även om den egentligen är "future".

Nästa grej var att stoppa in all data från Gotlands kommun i vår egen databas. Wordpress har såklart en samling förnämliga funktioner för detta ändamål. Vi gjorde en plugin som kör ungefär den här koden (xml-strukturen beror såklart på vad det är för xml man stoppar in):

documents->textdocument;
	foreach($xml->document as $document){
		if($document->attributes() == $event_id){
			foreach($document->children() as $node){
				$event[ (string) $node->attributes() ] = (string) $node;
			}

			// Kolla om vi redan sparat inlägget och därför ska uppdatera det istället för att skapa det.
			$con = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
			if (!$con){ die(':(' . mysql_error()); }
			mysql_select_db(DB_NAME, $con);

			$result = mysql_query("SELECT post_id FROM wp_program WHERE event_id = $event_id");
			$row = mysql_fetch_row($result);
			$mypost['ID'] = $row[0];

			// Rubrik
			$mypost['post_title'] = $event[$nodes->title];

			// Ingress
			$mypost['post_excerpt'] = $event[$nodes->excerpt];	

			// Innehåll
			$mypost['post_content'] = $event[$nodes->content];

			// Plats
			$place = $event[$nodes->place];

			// Tags är en array
			foreach($event[$nodes->tags] as $tag){
				$tags[] = $tag;
			}
			$mypost['tags_input'] = $tags;

			// Kategori måste skapas om den inte finns
			$category = wp_create_category($event[$nodes->category]);
			$mypost['post_category'] = array($category);

			// Egna taxonomier
			$organizer = $event[$nodes->organizer]];
			$organisation = $event[$nodes->organisation]];

			// Diverse saker
			$mypost['comment_status'] = 'closed';
			$mypost['ping_status'] = 'closed';
			$mypost['post_status'] = 'publish';	

			// Kasta in inlägget
			$my_id = wp_insert_post($mypost);

			// Kasta in egna taxonomier till inlägget
			wp_set_post_terms($my_id, $place, 'place');
			wp_set_post_terms($my_id, $organizer, 'organizer');
			wp_set_post_terms($my_id, $organisation, 'organisation');

			// Gör en trevlig länk som vi kan klicka på för att se hur fint det blev!
			echo '

'. $event_id .'=>' . $my_id . '

';
		}
	}
}
?>

Det hela är ganska okomplicerat och finns väl dokumenterat i Codex.

Det enda speciella vi gjorde här var en databastabell som håller koll på vilka evenemang som sparats, och därför ska uppdateras istället för att skapas.

Slutligen fixade vi så att alla inlägg kommer kronologiskt i loopen. Vanligtvis brukar hemsidor visa det senaste först, men ett kalendarium bör nog oftast visa det första först. Den här raden vänder uppochner på allting och ska köras innan loopen.


Fixa gränssnittet

När all data är i ordning är det dags att bygga något som interagerar med den. Sajten bygger i hög grad på javascript-ramverken jQuery, jQTouch och Touchscroll.

JQuery behöver ingen närmre introduktion. Det har blivit de-facto standarden för att skriva enklare javascript och finns buntat med Wordpress.

JQTouch är en jQuery-plugin tänkt att tillhandahålla behändiga funktioner för just pekskärms-baserade apparater. Det gör det onekligen smidigt att anpassa interaktion för Android och iPhone, men det är också rätt tungt och svåröverskådligt. Kanske hade det varit enklare att skriva den begränsade mängd funktionalitet vi i slutändan använde själva? Men det är absolut ett imponerande ramverk som jag råder alla att testköra.

Touchscroll är ett ramverk som förhindrar webbläsarens default-scrollning och hittar på sin egen. På så vis kan man runda några av iPhone-Safaris stökiga begränsningar som superslö scroll, och förbud mot absolut positionering av element. Efter iOS4-uppdateringen känns den dock betydligt långsammare, eller så är det bara hjärnspöken.

Att integrera dessa ramverk med Wordpress är mest en fråga om att ha välstrukturerad html i temat, men vi hade vissa problem med att få jQTouch och Touchscroll att fungera ihop.

Komprimera och optimera

Vi har lagt stor möda på att få ner storleken på sidan. Almedalsprogrammet är i år större än någonsin, och den blotta mängden evenemang gjorde att storleken på sidan initialt var omkring en megabyte, typ enbart text och html, vilket är helt sjukt.

De flesta webbläsare, även mobila, stödjer gzip-komprimering. När vi komprimerade all html krympte sidan till runt 200kb, vilket ändå är för stort. Vi minifierade css javascript, och gzippade även javascriptet, detta reducerade storleken till 140kb.

Det visade sig också finnas en hel del effektivisering att göra i markupen. Genom att ta bort element som mest hade semantisk och estetisk funktion, och försöka åstadkomma samma sak med css istället sparades ytterligare 10kb, dessutom gjorde det Touchscroll mycket mer responsivt.

Inget av den optimering vi gjort har vi kommit på själva, det bygger på tips och tricks från vänliga själar. Och vi kommer fortsätta att försöka pressa ned storleken och upp hastigheten, så om ni har något grymt optimeringsknep på lager, langa på det, vi skulle bli superglada!

Avslutningsvis

almedalen
Det som har varit roligast att göra är »spara favoriter«-funktionen. Dels för att den blev ganska elegant om jag får säga det själv, men framför allt för att den verkligen löser ett problem.

Med så många evenemang i kalendariet behövs det desperat ett sätt att vaska fram guldkornen, och det bästa sättet att göra det är såklart genom att använda almedalsbesökarnas kollektiva intelligens.

Så jag vill verkligen uppmana alla att ta en titt på kalendariet, registrera en användare och spara favoriter.

Tillsammans kan vi skapa den definitiva guiden till evenemangen du inte får missa!