Złoty pierścionek, podwędził Bronek.. :P

Dla klienta S4, przygotowaliśmy w Epeironie nową stronę produktową. Osobiście macałem w niej palce, gdyż byłem odpowiedzialny za stworzenie mechanizmu prezentacji obrączek w formie obracanej na elipsie kolekcji.

Żałuję jedynie, że klient nie zgodził się na pierwotną wersję, która moim zdaniem prezentowała się ładniej, ale o gustach się nie dyskutuje. Zapraszam – http://www.obraczki.com.pl/ – jeżeli planujecie ślub lub zaręczyny będzie w sam raz :P

Osadzanie fontów w aplikacji actionscript 3

ActionScript 3 pozwala na osadzanie (embedding) fontów bezpośrednio w aplikacji. Co by się zbytnio nie rozwodzić oto działające rozwiązanie:

public class Epeiron2 extends Sprite {
[Embed(source="c:/windows/fonts/AstalametPure.ttf", fontFamily="AstalametPure")]
 
private var fontTemp:String;
 
var format:TextFormat = new TextFormat();
format.font='AstalametPure';
 
textField1:TextField=new TextField();
textField1.defaultTextFormat=format;
}

Zauważcie, że w wersji beta metatag Embded był umieszczany poza klasą, w sekcji package. Obecnie jednak należy go umieszczać tak jak na przykładzie powyżej.

Linia:

private var fontTemp:String;

może budzić zdziwienie ale jest konieczna właśnie w tym miejscu – ponieważ osadzony plik jest przypisywany do najbliższej zmiennej.

Można także zabudować font, nie podając ścieżki do niego, ale jego nazwę. Oczywiście taka nazwa musi być zarejestrowana w systemie:

[Embed(systemFont="Astalamet Pure", fontFamily="AstalametPure")]

O banialukach w stylu “osadzanie fontów powoduje zwiększenie objętości pliku swf” nie będę pisał :)

Mars napada

W słoneczny styczniowy dzień, ktoś w Epeironie rzucił hasło aby coś zrobić z naszą WiecznieWBudowie stroną WWW. Jako, że miałem akurat mniej obowiązków, od słów przeszliśmy do czynów..

I tak powstała nowa wspaniała StronaWBudowie. Przy tej okazji pobawiłem się pierwszy raz na poważnie z ActionScript 3 i flexem. Obrońcy miasta, na barykady! http://epeiron.com/

Selektywne cachowanie w SMARTY

System szablonów Smarty posiada wbudowane cachowanie stron. Mechanizm ten znakomicie przyspiesza działanie serwisów, które muszą działać pod dużym obciążeniem. Dzięki możliwości sprawdzania, które fragmenty strony pozostają w pamięci podręcznej, można radykalnie zmniejszyć liczbę zapytań do bazy danych jak i odciążyć PHP od parsowania szablonów.

Problem może jedynie stworzyć sytuacja, w której chcemy aby fragment strony pozostawał nie cachowany – może to być np. aktualne notowania, dynamiczna reklama czy cokolwiek innego. Jeżeli chcielibyśmy taki fragment strony dołączać za pomocą funkcji {include}, to niestety i ona będzie podlegać cachowaniu.

Zamiast jednak używania {include}, możemy wykorzystać funkcję {insert}, która z poziomu szablonu wywoła wskazaną (w parametrze name) funkcję PHP i umieści w szablonie rezultat działania funkcji. Po szczegóły zapraszam do dokumentacji, a poniżej podaję przykład gotowego rozwiązania.

Tworzymy funkcję w PHP, która będzie zwracała przetworzony przez Smarty, wskazany w parametrze szablon:

function insert_nocache($PARAMS,$smarty) {
 
//wyłączamy cachowanie
$smarty->caching = 0;
 
//pobieramy i zwracamy przetworzony szablon
return $smarty->fetch($PARAMS['file']);
}

A tutaj już sposób wywołania tej funkcji z poziomu szablonu:

..tutaj część która jest cachowana..
{insert name=nocache file='plik_bez_cachowania.tpl'}
..i tutaj dalsza część która jest cachowana..

Brak obrazka tła na przyciskach w IE6

Problem: przycisk formularza wyświetla się w standardowy sposób, pomimo ustawienia w stylu obrazka dla tła tego przycisku.

Rozwiązanie: w IE nie wystarczy ustawić li tylko styl background-image, ale dodatkowo należy ustawić jakiś kolor tła background-color. Bez tego drugiego, obrazek nie zostaje wyświetlony (IE6, Windows XP SP2). Ot taka kolejna humoreska na temat przeglądarki Internet Explorer.

Open Power Driver – rozszerzenie do PDO

Udostępniony od wersji 5.1 języka, PHP Data Objects (PDO) – uniwersalny interfejs baz danych – wprowadził nową jakość w komunikacji z bazami danych. Oczywiście już wcześniej istniały inne rozwiązania abstrakcji baz danych, jednak PDO zostało wbudowane na stałe do języka, zdobywając przez to swoich gorących zwolenników jak i zażartych przeciwników.

Mi osobiście to rozwiązanie się podoba. Należy tutaj zaznaczyć, że PDO nie jest abstrakcją na składnię zapytań, ale jedynie sposób na zunifikowaną komunikację z różnymi bazami danych. Innymni słowy udostępnia zestaw standardowych metod do łączenia, odpytywania, pobierania wyników (itp.) bazy, niezależnie od jej rodzaju.

PDO posiada jednak kilka braków, które programistów posiadających już własne rozwiązania, mogą zniechęcać do korzystania z tego rozwiązania. Najważniejszą z nich jest brak wbudowanego cachowania wyników – choć również brak konsoli debuggera może być dokuczliwy. Oba te “niedociągnięcia” eliminuje biblioteka Open Power Driver, stanowiąca część większego projektu Open Power Board.

Kropka i przecinek czyli liczby w PHP i MySQL

Być może napotkaliście kiedyś problem z reprezentacją liczb naturalnych w PHP i MySQL. Otóż MySQL jako punkt dziesiętny stosuje zawsze kropkę, w PHP zależy to natomiast od ustawionej lokalizacji.

Tym samym, jeżeli w PHP ustawimy lokalizację, w której punkt dziesiętny nie jest kropką (na przykład polską), wstawiając takie liczby do zapytania SQL otrzymamy błąd SQL:

setlocale(LC_ALL ~LC_NUMERIC,'pl_PL'); //lub setlocale(LC_ALL,'plk_PLK') na systemach Windows
$result=5/2;
mysql_query('UPDATE table SET value='.$result);

You have an error IN your SQL syntax; CHECK the manual that corresponds TO your MySQL server version FOR the RIGHT syntax TO USE near ‘5’ at line 1

Rozwiązanie problemu jest oczywiście bardzo proste. Możemy wybrać, wśród dostępnych kategorii, jakich funkcji ma dotyczyć ustawienie lokalizacji.

setlocale(LC_TIME,'pl_PL'); //lub setlocale(LC_TIME,'plk_PLK') na systemach Windows
$result=5/2;
mysql_query('UPDATE table SET value='.$result); //teraz będzie ok

Oto lista wszystkich dostępnych opcji dla setlocale. Dla każdej z nich można ustawić inną lokalizację:

  • LC_ALL for all of the below
  • LC_COLLATE for string comparison, see strcoll()
  • LC_CTYPE for character classification and conversion, for example strtoupper()
  • LC_MONETARY for localeconv()
  • LC_NUMERIC for decimal separator (See also localeconv())
  • LC_TIME for date and time formatting with strftime()
  • LC_MESSAGES for system responses (available if PHP was compiled with libintl)

Trzeci wymiar w CSS?

Taki o to efekt uzyskałem przypadkiem podczas projektowania formularza na jedną ze stron:

Zapewne dla wielu osób nie jest to nadzwyczajnego, ja jednak poczułem się jakbym dostał na urodziny nową zabawkę. Okazuje się, że przeglądarki renderują taki efekt, gdy ustawimy border obiektu o grubości większej niż 1px. Wystarczy teraz dobrać odpowiednie kolory i już możemy się cieszyć wypukłymi lub wklęsłymi obiektami, bez użycia choćby grama grafiki :)

border-top:5px solid #aaaaaa;
border-bottom:5px solid #aaaaaa;
border-left:10px solid #e3e3e3;
border-right:10px solid #f8f8f8;

Obsługa klawiszy shift i ctrl w javascript.. na żywym przykładzie :)

Pewną bolączką webowych interfejsów użytkownika, jest brak niektórych możliwości jakie można na co dzień spotkać w interfejsach systemów operacyjnych. Jednym z takich brakujących elementów, jest możliwość wybierania myszką wielu pozycji z listy, wspomagając się klawiszami SHIFT i CTRL. Pora więc nadrobić braki i wykonać mechanizm implementujący taką funkcję na stronie WWW. Jak się okaże, nie jest to nic trudnego.

Zacznijmy od utworzenia kodu HTML naszej listy wyboru. Kolejne elementy listy będą umieszczone na oddzielnych warstwach, chociaż nic nie stoi na przeszkodzie aby były to inne elementy, na przykład wiersze tabeli lub wypunktowania. Wszystkie elementy zgrupujemy na warstwie głównej, co ułatwi nam automatyczne przypisywanie do nich zdarzeń. Nasz kod może wyglądać w ten sposób:

<div id="ListaDiv">
<div><input type="checkbox"> Opcja nr 1</div>
<div><input type="checkbox"> Opcja nr 2</div>
<div><input type="checkbox"> Opcja nr 3</div>
<div><input type="checkbox"> Opcja nr 4</div>
</div>

Następnie, poszczególnym Divom odpowiadającym kolejnym elementom naszej listy powinniśmy przypisać zdarzenie onclick tak aby reagowały na kliknięcie na nich myszką. Napiszemy więc funkcję przypisz(), która pobierze wszystkie Divy należące do listy i w pętli przypisze im handler zdarzenia onclick:

var ListKontenerID='ListaDiv';
 
function przypisz() {
 var x=document.getElementById(ListKontenerID).getElementsByTagName('div');
 for(var i=0;i&amp;ltx.length;i++) {
  x[i].onclick = klik;
  x[i].setAttribute('numer',i);
 }
}

Tutaj należą się dwa słowa wyjaśnienia. Zdarzenia dodajemy poprzez przypisanie elementowi nazwy funkcji, która obsłuży nasze kliknięcia. Zgodnie z specyfikacją DOM Level 2 powinniśmy to robić za pomocą metody addEventListener(), jednakże jak na razie ani Opera ani MSIE nie obsługują tego modelu zdarzeń.

Dodatkowo, w pętli numerujemy sobie poszczególne warstwy, tak abyśmy później szybko mogli stwierdzić, który w kolejności element listy został kliknięty. Numerację wykonujemy poprzez dodanie do Diva nowego atrybutu o nazwie “numer”.

Funkcję przypisz() powinniśmy wywoływać po załadowaniu strony, np. w zdarzeniu onload:

Zanim przejdziemy do właściwej obsługi zdarzenia onclick, utwórzmy jeszcze dwie funkcje pomocnicze, które będą nam zaznaczać i odznaczać wskazany element listy:

function zaznacz(obiekt) {
 obiekt.setAttribute('wybrany','wybrany');
 obiekt.className='podswietlony';
}
 
function odznacz(obiekt) {
 obiekt.setAttribute('wybrany','');
 obiekt.className='';
}

W tych funkcjach można zaimplementować dowolnie skomplikowane akcje; istotne jest aby pozostawić jedynie ustawianie i gaszenie atrybutu “wybrany”, który będzie wykorzystywany podczas obsługi zdarzeń. W przykładzie powyżej, wykonujemy dodatkowo jedynie ustawianie stylu “podswietlony” do wybranego elementu.

Po przygotowaniu terenu działań możemy przystąpić do implementacji najważniejszej funkcji przechwytującej zdarzenia. Jak się okazuje, sprawdzenie czy był wciśnięty klawisz shift lub ctrl jest banalnie proste: obiekt zdarzenia przechowuje właściwości o nazwie shiftKey oraz ctrlKey. Wystarczy więc sprawdzić jej stan podczas kliknięcia myszką i zależnie od wyniku podjąć odpowiednią akcję:

function klik(e) {
	if (!e &amp;&amp; event) {
		e=event;
		e.target=event.srcElement;
	}
 
	if (e.shiftKey &amp;&amp; PoprzedniNumer!=null) {
 
		var n1=e.target.getAttribute('numer');
		var n2=PoprzedniNumer;
 
		if (n1&gt;n2) { var tmp=n2; n2=n1; n1=tmp; }
		x=document.getElementById(ListKontenerID).getElementsByTagName('div');
 
		for(var i=n1;i&lt;=n2;i++) {
			zaznacz(x[i]);
		}
 
	} else if (e.ctrlKey) {
		if (e.target.getAttribute('wybrany')!='wybrany') {
			zaznacz(e.target);
		} else {
			odznacz(e.target);
		}		
 
	} else {
		x=document.getElementById(ListKontenerID).getElementsByTagName('div');
		for(var i=0;i&lt;x.length;i++) {
			odznacz(x[i]);
		}
 
		if (e.target.getAttribute('wybrany')!='wybrany') {
			zaznacz(e.target);
		} else {
			odznacz(e.target);
		}
	}
 
	PoprzedniNumer=e.target.getAttribute('numer');
 
	return false;
}

Działające demo można zobaczyć tutaj: detekcja klawiszy specjalnych w javascript.

Quirks mode aaaa!

Niech wszystkie diabli wezmą tego IE6! :)

Czym się różnią poniższe dwa pliki HTML?

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl">
<head></head>
<body>
<div style="width:300px;margin:0px auto;background-color:red;">
foo bar();
</div>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl">
<head></head>
<body>
<div style="width:300px;margin:0px auto;background-color:red;">
foo bar();
</div>
</body>
</html>

Proponuję sprawdzić jak renderują się one w przeglądarce Internet Explorer. Gdy zdarzy wam się zapomnieć o takich przypadłościach tej najbardziej popularnej przeglądarki, możecie stracić trochę czasu na rozwiązanie potencjalnych problemów :P

Dla leniuchów specjalnie screenshot:

Gdy już sprawdzicie efekt, możecie udać się na stronę microsoftu i trochę poczytać o CSS Enhancements in Internet Explorer 6.