<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Блогът на Гонзо</title>
	<atom:link href="http://greatgonzo.net/feed" rel="self" type="application/rss+xml" />
	<link>http://greatgonzo.net</link>
	<description></description>
	<lastBuildDate>Thu, 04 Aug 2011 22:18:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Качване на файлове с cURL към Lighttpd</title>
		<link>http://greatgonzo.net/pages/2196.html</link>
		<comments>http://greatgonzo.net/pages/2196.html#comments</comments>
		<pubDate>Thu, 04 Aug 2011 22:16:31 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[cURL]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Lighttpd]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2196</guid>
		<description><![CDATA[Днес се сблъсках с един проблем, решението на който, макар и лесно, въобще не беше очевидно. Трябваше да направим така, че когато потребителя изпрати файл към сървъра, PHP да го изпрати на друг сървър, на който инструмент, написан на Java, [...]]]></description>
			<content:encoded><![CDATA[<p>Днес се сблъсках с един проблем, решението на който, макар и лесно, въобще не беше очевидно. Трябваше да направим така, че когато потребителя изпрати файл към сървъра, PHP да го изпрати на друг сървър, на който инструмент, написан на Java, да го обработи, и ако всичко е ОК, нашето PHP да си запише резултата. Първото нещо, което ви хрумва сигурно е &#8222;По-сложно не можеше ли?&#8220;. Сигурно може, не сме се постарали достатъчно. А и важното е за потребителя да става лесно.</p>
<p>Ако потърсите примери за качване на файлове с PHP и cURL, ще намерите много, и кодът между тях не се различава. Общо взето изглежда така:</p>
<pre><code>&lt;?php
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
    curl_setopt($ch, CURLOPT_URL, _VIRUS_SCAN_URL);
    curl_setopt($ch, CURLOPT_POST, true);
    $post = array(
        "file_box"=>"@/path/to/myfile.jpg",
    );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    $response = curl_exec($ch);
?>
</code></pre>
<p>Този пример е от първия резултат при търсене в Google по въпроса. Обаче при мен той не сработи. Отсрещната страна непрекъснато връщаше <code>417 Expectation Failed</code>. И кво не ти харесва сега? Кои точно очаквания останаха неизпълнени? <span id="more-2196"></span></p>
<p>Пробвах какво ли не &#8211; разни допълнителни параметри към cUPL, добавях променливи към POST данните, опитах допълнително да подам <code>Content type</code>&#8230; Не става!</p>
<p>Значи проблема не е в заявката, а в отсрещната страна. Потърсих дали някой друг не е срещал подобен проблем, и се оказа, че да, проблемът е в отсрещния уеб сървър, който ползва Lighttpd. Значи, cURL праща заглавка <code>Expect: 100-Continue</code> към отсрещния сървър и очаква от него или да отговори със <code>100 Continue</code>, или нищо да не отговори, при което cURL да продължи с изпращането на данните. Да де, ама разработчиците на Lighttpd са сметнали, че е най-добре да отговорят с <code>417 Expectation Failed</code>. Проблемът има две решения. Едното е да накарате cURL да не изпраща заглавката, като добавите празна такава:</p>
<pre><code>curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
</code></pre>
<p>Другата възможност е да накарате Lighttpd да се държи прилично. След настоятелите молби на потребители на тоз уеб сървър е добавена конфигурационна променлива, която да промени поведението при получаване на заглавка <code>Expect: 100-Continue</code>. Просто в конфигурацията трябва да добавите този ред:</p>
<pre><code>server.reject-expect-100-with-417 = "disable"
</code></pre>
<p>Аз използвах второто решение и смятам от сега нататък да добавям този ред на всички сървъри с Lighttpd, до чиято конфигурация имам достъп. Това ще спести доста време на други като мен да се чудят защо пращането на файлове с cURL или Flash не работи.</p>
<p>И двете решения на проблема са описани в системата за следене на бъгове на Lighttpd:</p>
<p><a href="http://redmine.lighttpd.net/issues/1017">http://redmine.lighttpd.net/issues/1017</a></p>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2196&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2196.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Web Widgets &#8211; уеб приложения за инсталиране</title>
		<link>http://greatgonzo.net/pages/2190.html</link>
		<comments>http://greatgonzo.net/pages/2190.html#comments</comments>
		<pubDate>Mon, 01 Aug 2011 19:45:02 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[BlackBerry WebWorks]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Nokia]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[RIM]]></category>
		<category><![CDATA[Symbian Web Runtime]]></category>
		<category><![CDATA[web widgets]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2190</guid>
		<description><![CDATA[От известно време се интересувам от възможностите да се създават приложения за мобилни устройства с помощта на отворени уеб стандарти. Разнообразието от платформи за мобилни устройства е доста по-богато отколкото за настолни системи, което прави създаването на приложения за всички [...]]]></description>
			<content:encoded><![CDATA[<p>От известно време се интересувам от възможностите да се създават приложения за мобилни устройства с помощта на отворени уеб стандарти. Разнообразието от платформи за мобилни устройства е доста по-богато отколкото за настолни системи, което прави създаването на приложения за всички тях доста трудоемко &#8211; видях например обява за работа, в която се търсеха програмисти за 5 различни платформи. За това си мисля, че вместо да се хвърля огромен ресурс за създаването на много приложения за различни платформи, в повечето случаи би било много по-добре да се направи едно уеб-приложение, което да работи на всички платформи.</p>
<p>За това след като разучих възможностите на някои JavaScript API-да и HTML5 Offline Storage, реших да пробвам дали ще се справя и с пакетирането на web widget.<span id="more-2190"></span></p>
<h2>W3C Widgets / Opera Widgets</h2>
<p>Web widget всъщност представлява zip архив, който съдържа в себе си HTML, JavaScript, CSS и други компоненти на едно уеб-приложение. След като потребителят изтегли пакета на своето устройство, било то мобилен телефон или компютър, приложението се инсталира локално и при зареждане файловете се зареждат от файловата система, а не от мрежата. По този начин дори и да имате нужда от огромни библотеки и още 200k ваш JavaScript, това не е проблем за потребителя, защото той ще ги изтегли гарантирано само веднъж.</p>
<p><a href="http://www.w3.org/TR/widgets-apis/">W3C Widgets</a> е официалната спецификация и както повечето други спецификации на W3C се развива доста бавно. Това обаче не е пречка пред Vodafone и Opera, който в сътрудничество са създали имплементация на текущото състояние на описанието. Най-лесният начин да пробвате за какво става дума е да отворите Opera и да отидете на <a href="http://widgets.opera.com/">http://widgets.opera.com/</a>. Opera отваря .wgt файловете и ви дава възможност да ги инсталирате локално на компютъра, като дори създава връзки за стартиране в менюто с програми. На мобилен телефон нещата стоят малко по-различно. Vodafone предлагат свой мениджър за S60 (предполагам преинсталиран на техните телефони), който включва в себе си runtime компонент от Opera. Освен това можете да инсталирате Opera Widget Manager &#8211; наличен е за всички платформи, за които е наличен и Opera Mobile. Така направих и аз &#8211; недостатък е, че мениджъра на Opera не слага икони за стартиране в общото меню с приложения, а трябва първо да стартирате мениджъра.</p>
<p>Това, което аз исках да направя, е всъщност доста просто приложение &#8211; специфичен хронометър, който да има обратен брояч от 5 минути до 0 и втори обикновен хронометър. Работата е там, че ветроходните регати имат особена стартова процедура, защото няма как яхтите да се подредят на стартовата линия и да чакат стартовия сигнал. Вместо това съдията на регатата подава зрителни и звукови сигнали 5 минути преди старта, 4 минути минути преди старта, 1 минута преди старта и сигнал за самия старт. През това време яхтите се въртят привидно хаотично зад стартовата линия и се стремят така да преценят своята и на съперниците си траектории, та да се окажат с максимална скорост преди стартовата линия и в най-изгодна позиция. За това на шкипера на яхтата му е необходимо да знае точно колко време остава до старта, и да измери за колко време изминава разстоянието от някаква изходна позиция до стартовата линия.</p>
<p>И така, набързо скалъпих един HTML файл със всичкия необходим JavaScript и CSS вътре в него. Няма нищо секси в кода на самия хронометър, важното беше просто да работи. По-интересно ми беше самото пакетиране на web widget-а и дали ще има особености в работата на скрипта.</p>
<p>След като имах &#8222;приложението&#8220;, дойде ред на пакетирането. Както споменах вече, всичко което трябваше да направя, беше да създам един XML файл с описанието на джаджата, да архивирам файловете и да променя разширението на WGT. Ето моя config.xml:</p>
<pre><code>&lt;?xml version='1.0' encoding='UTF-8'?>
&lt;widget defaultmode="fullscreen" modes="application">
    &lt;widgetname>Sailing Chronometer&lt;/widgetname>
    &lt;description>
        Simple chronometer for measuring
        the start time sequence of sailing races.
    &lt;/description>
    &lt;network>public&lt;/network>
    &lt;width>360&lt;/width>
    &lt;height>480&lt;/height>
    &lt;author>
    	&lt;name>Milen Petrinski - Gonzo&lt;/name>
    	&lt;link>http://greatgonzo.net&lt;/link>
    &lt;/author>
    &lt;id>
    	&lt;host>greatgonzo.net&lt;/host>
    	&lt;name>sailingchronometer&lt;/name>
    &lt;/id>
    &lt;icon>icon_128.png&lt;/icon>
    &lt;icon>icon_64.png&lt;/icon>
    &lt;icon>icon_32.png&lt;/icon>
    &lt;icon>icon_16.png&lt;/icon>
&lt;/widget></code></pre>
<p>Няма да обясняван значението на всяко поле, ако имате съмнения, най-добре прегледайте <a href="http://dev.opera.com/articles/view/opera-widgets-specification-fourth-ed/#config_xml">документацията на сайта на Opera</a>. Тук е мястото да спомена, че документацията на сайта на Opera всъщност се различава от тази на W3C. Opera развиват технологията с по-бързи темпове, като в последната версия на Opera Mobile за Android имат поддръжка и за някои <a href="http://www.wacapps.net/web/portal/wac-2.0-spec">WAC 2.0 Device APIs</a>. </p>
<p>Освен това трябваше да направя и иконка за джаджата. За това използвах <a href="http://dev.opera.com/articles/view/icon-creator-tutorial/">Icon Creator</a> &#8211; приложение от Opera, чрез което лесно можете да се създават икони, като се комбинира изображение или някой от вградените символи, и фон със или без преливка и ефект на отблясък. За самата икона използвах <a href="http://findicons.com/icon/94046/chronometer?id=94046">изображение на хронометър</a>, лицензирано под GPL. Освен размерите, препоръчани на сайта на Opera, направих и размери като за iPhone, защото нищо не пречи същия HTML файл да се зареди от уеб и да се сложи връзка на началния екран. За целта добавих и manifest файл, за да може файла да се кешира като HTML5 offline приложение. Пробвах го на Android, стана, приложението работи дори и без връзка към мрежата.</p>
<h2>Symbian Web Runtime Widgets</h2>
<p>Nokia са били така добри да предвидят в Symbian всичко необходимо за създаване на приложения само чрез стандартни уеб технологии. Но естествено са го направили по свой начин. Всъщност техните пакети се различават от тези на W3C / Opera по формата на XML файла и по това, че всички файлове трябва да са поставени в директория със същото име като самия пакет. А, и естествено разширението и mime-типът на файла е различен, нищо, че пак е обикновен zip архив.</p>
<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;!DOCTYPE plist PUBLIC "-//Nokia//DTD PLIST 1.0//EN"
    "http://www.nokia.com/NOKIA_COM_1/DTDs/plist-1.0.dtd">
&lt;plist version="1.0">
	&lt;dict>
		&lt;key>DisplayName&lt;/key>
		&lt;string>SailingChronometer&lt;/string>
		&lt;key>Identifier&lt;/key>
		&lt;string>net.greatgonzo.sailingchronometer&lt;/string>
		&lt;key>MainHTML&lt;/key>
		&lt;string>index.html&lt;/string>
		&lt;key>Version&lt;/key>
		&lt;string>0.1&lt;/string>
		&lt;key>AllowNetworkAccess&lt;/key>
		&lt;false/>
		&lt;key>MiniViewEnabled&lt;/key>
		&lt;false/>
	&lt;/dict>
&lt;/plist></code></pre>
<p>Nokia са се погрижили разработчиците, ползващи HTML и JavaScript да разполагат съ същите възможности за достъп до системата както и разработчиците на &#8222;native&#8220; приложения. За целта те предлагат <a href="http://www.developer.nokia.com/Resources/Tools_and_downloads/Other/Nokia_Platform_Services/">Nokia Platform Services</a> &#8211; набор от API-та за достъп до телефона от WRT widgets. </p>
<p>Но за момента аз нямах нужда да се задълбавам в тази материя, още повече, че ако едно приложение разчита на тези API-та, то става не по-малко native от приложение, написано на Qt.</p>
<p>За да си улесня живота с пакетирането на два различни формата, си написах прост скрипт, с който да автоматизирам малко процеса:</p>
<pre><code>#!/bin/bash

# W3C Widget / Opera Widget
zip sailingchronometer.wgt config.xml index.html icon_*.png

# Nokia Web Runtime Widget
mkdir sailingchronometer
cp info.plist index.html icon.png sailingchronometer/
zip sailingchronometer.wgz sailingchronometer/*
rm -rf sailingchronometer
</code></pre>
<h2>BlackBerry WebWorks</h2>
<p>Съвсем случайно попаднах на <a href="http://docs.blackberry.com/en/developers/deliverables/27268/Code_sample_Creating_a_BB_Widget_config_document_834683_11.jsp">страничка</a>, показваща как да се пакетират приложения, използващи HTML, JavaScript и CSS за телефони BlackBerry. От RIM са използвали за основа W3C Widgets, като са разширили XML манифеста с допълнителни неща, които са сметнали за необходими. Това поне на пръв поглед изглежда доста добре, защото би трябвало да посволи едно и също приложение да работи и на телефон BlackBerry (почти) без изменеия. Дали наистина е така не мога още да кажа, защото нямам достъп до такова устройсто, за да тествам резултата.</p>
<p>RIM също като Nokia <a href="http://docs.blackberry.com/en/developers/subcategories/?userType=21&#038;category=BlackBerry+WebWorks+for+Smartphones">предлагат доста допълнителни API</a> за достъп до всички ресурси на телефона, което прави възможно разработването на всякакви приложения само с HTML и JavaScript.</p>
<p>Ето и връзки към приложението и пакетите:</p>
<ul>
<li><a href="http://greatgonzo.net/sailingchronometer/">Sailing Chronometer</a></li>
<li><a href="http://greatgonzo.net/sailingchronometer/sailingchronometer.wgt">Sailing Chronometer Opera Widget</a></li>
<li><a href="http://greatgonzo.net/sailingchronometer/sailingchronometer.wgz">Sailing Chronometer Symbian WRT Widget</a></li>
</ul>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2190&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2190.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Анатомия на едно мобилно уеб приложение, част трета: JavaScript Event Driven Architecture</title>
		<link>http://greatgonzo.net/pages/2180.html</link>
		<comments>http://greatgonzo.net/pages/2180.html#comments</comments>
		<pubDate>Tue, 14 Jun 2011 21:06:12 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[five corners]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2180</guid>
		<description><![CDATA[Това е третата публикация, в която разказвам как направих клиент за Foursquare използвайки само уеб технологии. В първите две разказах как работи GeoLocation API в съвременните браузъри и как не се справих в разбирането на oAuth. В тази публикация ще [...]]]></description>
			<content:encoded><![CDATA[<p>Това е третата публикация, в която разказвам как направих клиент за Foursquare използвайки само уеб технологии. В първите две разказах <a href="http://greatgonzo.net/pages/2151.html">как работи GeoLocation API</a> в съвременните браузъри и <a href="http://greatgonzo.net/pages/2163.html">как не се справих в разбирането на oAuth</a>. В тази публикация ще се опитам да ви разкажа как приложих на практика представената от <a href="http://blog.rstankov.com/">Радослав Станков</a> концепция <a href="http://www.slideshare.net/rstankov/javascript-eventdriven-architecture">Event Driven JavaScript Architecture</a>.</p>
<p>На <a href="http://openfest.org/">OpenFest 2010</a> Радо изнесе доста интересна лекция, в която чрез примери показа как вместо да викаме функции, можем да накараме различните части от JavaScript приложението да си говорят чрез различни дефинирани от нас събития. И най-хубавото е, че това става чрез любимата ми библиотека jQuery и HTML5 data атрибути. И така след първия прототип се отдадох на преправяне на приложението. Малко доразвих идеята на Радо, като разделих събитията на групи според естеството им, а за групиране използвах префикс.<span id="more-2180"></span></p>
<p>Започнах от функциите, които получават данни от 4sq. Щом се получават данни, имената на събитията следва да са <code>data:нещоси</code>. Така имах две събития: <code>data:venues</code> когато получа списъка с близки обекти, и <code>data:user</code> когато извлека данните на текущея потребител. За всяко от тях написах функция, която да показва данните в страницата, манипулирайки DOM. За да укажа какви събития предизвикват контролите (демек разните бутони / линкове), използвах атрибути <code>data-action</code> със стойности <code>action:нещоси</code> според нуждата. Но вместо да прикрепям отделна функция, което да обслужва onclick събитието на всеки бутон, делегирах функция за всички елементи с атрибут data-action чрез подходящ селектор. Допълнителните данни, които са необходими, също поставих в data атрибути. Нещо не се получи да си предам само данните, така че за да не се боря с event обекта, си предадох направо DOM елемента, който генерира събитието. <del datetime="2011-06-14T20:56:32+00:00">По-натам ще оправим този не толкова сексапилен код.</del> Явно все пак предаването на данните от <code>data-</code> атрибутите се е получило.</p>
<p>В случай, че се случи някаква грешка, възможните събития са <code>error:http</code> и <code>error:other</code>. В първия случай трябва да обслужа специално случая, когато прокси-скрипта върне статус 401 &#8211; това значи, че потребителя не се е аутентикирал, и се налага да го пренасоча към 4sq. Във всички останали случаи просто показвам съобщението за грешка.</p>
<p>След като свърших с преправянето, JavaScript кодът имаше две обособени и в голяма степен независими части. Първата е един обект, в който е затворена всичката функционалност, свързана с Foursquare. Другата част остана по-разхвърляна &#8211; в нея се извършва манипулирането на DOM и се обработват действията на потребителя. Самия код можете да разгледате <a href="/fivecorners/fivecorners.js">тук</a> &#8211; това е работещата версия, която търпи промени от време на време. Доволен съм от резултата &#8211; мога безпрепятствено да променям всяка от двете части на приложението &#8211; мога да реструктурирам обекта, отговарящ за връзката със сървъра, без да пипам частта, отговорна за интерфейса, както мога да променя изцяло интерфейса, без да се налага да правя промени в кода за връзка със сървъра.</p>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2180&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2180.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Responsive web design &#8211; защо критиците му просто не схващат идеята</title>
		<link>http://greatgonzo.net/pages/2172.html</link>
		<comments>http://greatgonzo.net/pages/2172.html#comments</comments>
		<pubDate>Sat, 23 Apr 2011 08:34:07 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[mobile web]]></category>
		<category><![CDATA[responsive design]]></category>
		<category><![CDATA[адаптивен дизайн]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2172</guid>
		<description><![CDATA[Поводът да напиша това е размяната на няколко съобщения в Twitter с Константин Данков след като той сподели една статия от миналата година. Откакто Итън Маркот описа приложението на CSS media queries за създаване на уеб-сайтове, подходящи за всякакви екрани [...]]]></description>
			<content:encoded><![CDATA[<p>Поводът да напиша това е размяната на няколко съобщения в Twitter с <a href="http://dankov.name/">Константин Данков</a> след като той сподели <a href="http://www.cloudfour.com/css-media-query-for-mobile-is-fools-gold/">една статия</a> от миналата година. Откакто Итън Маркот <a href="http://www.alistapart.com/articles/responsive-web-design/">описа</a> приложението на CSS media queries за създаване на уеб-сайтове, подходящи за всякакви екрани и устройства, някои хора видях в нея заплаха за дълго пропагандираната идея, че мобилния уеб е напълно различен от досегашния, доминиран от настолните компютри, и съответно изисква съвсем отделни сайтове. Срещу всяка статия, показваща как да се прилагат идеите на Итън Маркот бяха написани по две, критикуващи техниките на адаптивния дизайн и изтъкващи недостатъците. И за някои неща са прави.</p>
<p>За да обясня защо смятам, че атаптивния дизайн Е единствения уеб-дизайн, ще ви разкажа аз стигнах до същите основни похвати. Когато започнах да пиша в този блог тъкмо се беше появил Asus EeePC. Първата версия беше със 7 инчов екран с разделителна сподобност 800&#215;480. И тъй като много ми харесваше тази джаджа и се чудех дали да не си купя, исках съответно сайтът ми да е използваем и на нейния екран. Да, ама повечето (почти всички) сайтове се правят за екрани 1024&#215;768 пиксела и това важи и за темите за WordPress. Така че едно от първите неща, които направих с темата на моя блог беше да я направя да се свива и разпъва според размера на браузъра. Но бях ограничил ширината до 1200 пиксела, защото при по-големи ширини редовете ставаха твърде дълги и нечетими. След това заедно със стиловете за печат добавих и стилове за hendheld устройства. Това трябваше да осигури подходящ изглед за мобилни телефони и PDA устройства. Работата е там, че Apple повлякоха крак още с първия iPhone и всички мобилни браузъри след него не се съобразяват със стиловете за hendheld медия, а лъжат че са настолни браузъри, за да покажат колко добре се справят със съществуващите сайтове.<span id="more-2172"></span></p>
<p>След време обаче научих, че в CSS3 е предвиден начин стиловете, които браузъра ползва, да бъдат подбирани не само по типа медия, но и по нейните характеристики. Първото нещо, което направих, беше да насоча стиловете за hendheld и към screen медия, ако ширината на браузъра е по-малко от 800 пиксела. След това седнах и написах <a href="http://greatgonzo.net/pages/56.html">кратка статия</a> за това.</p>
<p>Да, ама от време на време като разпъна прозореца на браузъра върху всичките 1650 на 1050 пиксела на домашния монитор и много се дразнех на празните бели полета от двете страни на сайта. А с повечето сайтове положението е още по-зле, защото са с едно 200 пиксела по-тясни. И реших, че медийните заявки могат да се използват и за <a href="http://greatgonzo.net/pages/604.html">адаптиране на дизайна към много големи екрани</a>. Накрая имах сайт, който е ползваем на малкия екран на мобилен телефон и в същото време се възползва максимално (макар и не по най-добрия начин) от пространството на голям настолен монитор. А, и след няколко месеца в A List Apart излезе статията на Итън Маркот.</p>
<p>След този дълъг и надявам се не много скучен увод да видим къде критиките към responsive дизайна издишат.</p>
<blockquote><p>
Скоростта е от голямо значение за мобилните потребители, а адаптивния дизайн товари сайта с големи картинки или неща, които остават скрити.
</p></blockquote>
<p>Сама презумпция, че обемът на трафика е от съществено значение само за мобилните потребители е абсолютно погрешна. В България може и да има съществена разлика в скоростите, защото не навсякъде има 3G покритие и мобилния интернет все още е екстра, докато доставчиците предлагат скорости над 5 мегабита, но по света съвсем не е така. </p>
<p>Често се изтъква факта, че ако даден елемент е скрит в стиловете за малки екрани, голямата картинка за фон все пак се зарежта. Ама не се прави така бе, хора! Ако фонът е поставен в стил, който важи само за големи екрани, браузърът на мобилния телефон няма да тегли картинката.</p>
<blockquote><p>
Медийните заявки не оптимизират съдържанието за мобилните потребители и те пак трябва да свалят пълния размер на сайта.
</p></blockquote>
<p>А защо смятате, че обикновения сайт трябва да е претрупан с неща, които не са пряко свързани с основното съдържание на страницата и само отвличат вниманието на потребителите от това, заради което са дошли на сайта? Защо е допустимо да отрупате страницата с реклами и освен това да накарате потребителя да цъка найсе пъти през междинни рекламни страници и банери, отварящи се върху основното съдържание?</p>
<p>Ако един обикновен, настолен ако щете, сайт не е фокусиран върху основната цел, заради която потребителите го посещават, как очаквате мобилния вариант да остане фокусиран?</p>
<blockquote><p>
Адаптивния дизайн не взима предвид мобилния контекст.
</p></blockquote>
<p>Колкото повече чета за този мобилен контекст, толкова повече се убеждавам, че това е някаква пълна глупост. Презумпцията, че потребителят на мобилния телефон е задължително в движение и бърза да намери някаква информация на сайта ви догато се шмуга между тълпата излизайки от метрото, е изсмукана от пръстите. Повечето хора използват iPhone-ите си за браузване докато си пият кафето в Старбъкс или вкъщи пред телевизора. Това къде се намира потребителя, с каква скорост се движи, или колко е шумно не определя целта на посещението му на вашия сайт. Ще ви дам примери: Бизнесмен си седи в удобното кресло на частния самолет, летейки с 1000км/ч над Ню Йорк и разглежда сайт за резервации на самолетни билети на своя iPhone, защото планира семейната почивка след 2 месеца. Или пък обикновен служител, заседнал в задръстване заради катастрова на магистралата край Ихтиман отваря същия този сайт на своя лаптоп (щот шефа не му е купил умен телефон), защото след 5 минути има среща в кол-центъра на фирмата, изнесен за по-евтино в Пловдив.</p>
<p>И след тези излияния, нека ви разкажа как смятам, че трябва да се използва техниката на адаптивния дизайн. Първо започваме от най-основните неща, които ще са общи за всички размери на дисплея &#8211; типографията, цветовата схема и т.н. След това чрез медийна заявка можем да опишем специфични стилове за малки екрани със съвременен браузър, ако искаме да добавим нещо специфично за тях &#8211; малки картинки за фон например. После идва ред на по-големите екрани &#8211; пак затворени в медийна заявка поставяме допълните стилове, които оформят разположението на елементите по страницата за големи екрани. В този блок включваме и @font-face декларациите, и фоновите картинки, ако не искаме да товарим мобилните устройства с допълнителен трафик. Що се отнася до изображенията в сайта, варианти много в зависимост от целта на сайта. Ако картинките са особено важна част от съдържанието (фотоблог примерно) и не са твърде големи, можем да ги сервираме както са и да ги намалим със CSS. Ако пък са само за илюстрация на текста и държим да намалим трафика, можем да сложим в сайта картинки с малък размер, които след зареждане на страницата да заменим с по-големи само за големи екрани чрез JavaScript.</p>
<p>Адаптивния дизайн не е техника за пригаждане на десктоп-сайтове към мобилни браузъри. Адаптивния дизайн е техника за цялостен дизайн на сайтове. През XXI век, когато екраните, на които потребителите ползват уеб, варира от 200 до 2000 пиксела адаптивният дизайн Е начинът на направим сайта си достъпен за всички.</p>
<p>Ето и малко връзки към статии по темата, които намирам за особено полезни:</p>
<ul>
<li><a href="http://www.lukew.com/ff/entry.asp?933">Mobile First</a></li>
<li><a href="http://adactio.com/journal/4443/">Context</a></li>
<li><a href="http://forabeautifulweb.com/blog/about/i_dont_care_about_responsive_web_design/">★ I don’t care about Responsive Web Design</a></li>
<li><a href="http://forabeautifulweb.com/blog/about/using_media_queries_in_the_real_world/">Using Media Queries in the Real World</a></li>
<li><a href="http://adactio.com/journal/4494/">Windows mobile media queries</a></li>
<li><a href="http://adactio.com/journal/4496/">Respond</a></li>
<li><a href="http://forabeautifulweb.com/blog/about/320_and_up/">320 and Up</a></li>
<li><a href="http://yiibu.com/articles/rethinking-the-mobile-web/">Rethinking the Mobile Web</a></li>
</ul>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2172&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2172.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Анатомия на едно мобилно уеб приложение, част втора: oAuth и FourSquare API</title>
		<link>http://greatgonzo.net/pages/2163.html</link>
		<comments>http://greatgonzo.net/pages/2163.html#comments</comments>
		<pubDate>Thu, 10 Feb 2011 07:45:08 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[FiveCorners]]></category>
		<category><![CDATA[Foursquare]]></category>
		<category><![CDATA[oAuth]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2163</guid>
		<description><![CDATA[В предишната публикация ви разказах как с помощта на GeoLocation API можете да установите местоположението на потребителя. В тази публикация ще се опитам да ви разкажа как се справих със следващата стъпка към създаването на приложение за FourSquare. Както всяка [...]]]></description>
			<content:encoded><![CDATA[<p>В <a href="http://greatgonzo.net/pages/2151.html">предишната публикация</a> ви разказах как с помощта на GeoLocation API можете да установите местоположението на потребителя. В тази публикация ще се опитам да ви разкажа как се справих със следващата стъпка към създаването на приложение за FourSquare.</p>
<p>Както всяка уважаваща себе си услуга за гийкове, и FourSquare предлага API, за да могат разни асоциални разработчици да прекарват свободното си време в създаване на безполезни приложения. Първо започнах от различни описания на oAuth. Както може би знаете, това е начин потребителите да разрешат достъп на външно приложение до профила им в дадена услуга без да предоставят името и паролата си на приложението. От гледна точка на потребителя процеса е доволно прост &#8211; потребителя бива препратен към сайта на услугата, където след като се аутентикира и разреши достъп на приложението, бива препратен обратно към сайта на приложението. Обаче гледната точка на разработчика, прилагащ на практика механизъма, нещо не ми стана достатъчно ясна.<span id="more-2163"></span></p>
<p>Въпреки, че изчетох доста текст за oAuth, а API-то на FourSquare не е висша математика, накрая просто използвах готова библиотека. Като начало реших, че най-лесно и бързо ще реша проблема със same domain policy като напиша прокси-скрипт. За него няма да пиша подробно, доста е грозен, но за сега работи. Използвах <a href="https://github.com/jmathai/foursquare-async">ето тази библиотека</a> за връзка с API-то на FourSquare. При правенето на скрипта исках да избегна нуждата от база данни &#8211; едно, че исках да е възможно най-прост, и второ, че не желая да се занимавам със съхраняване на данни. По тази причина и защото не можах да схвана значението и смисъла на параметрите, с които борави oAuth (за това спомогнаха неясните за мен примери, в които с едни и същи имена бяха кръстени очевидно различни параметри), реших като начало да разчитам на сесиите в PHP. Неудобството беше, че при всяко рестартиране на браузъра аутентикацията трябва да се извърши наново. Съществената особеност е, че oAuth API-то на FourSquare предлага(ше) възможност потребителя автоматично да бъде пренасочен обратно към приложението, ако вече веднъж е разрешил то да достъпва данните му. Така след първия път, когато трябва да напише потребителското си име и паролата в сайта на FourSquare, потребителя страда само от малко пренасочвания. На <a href="http://www.phpied.com/">Стоян</a> няма никак да му хареса, но пък така не се налага прокси-скриптът ми да пази oAuth токените на потребителя в база данни.</p>
<p>Всъщност преди две седмици изтеглих нова версия на библиотеката, която вече работи с новата версия 2 на FourSquare API, при което естествено се наложи да пренапиша почти изцяло всичко. В примерите обаче след като завърши процеса на oAuth аутенкикация параметърът, достатъчен за по-нататъшната работа беше един и се запазваше като бисквитка. Е, щом в примерите е така, прецених, че и аз мога да постъпя по същия начин и потребителите (аз!) няма да се налага да чакат досадните препращания при първоначалното зареждане на приложението. Освен това добавих малко по-добро обслужване на грешки (е, има още какво да се желае).</p>
<p>И така, набързо скалъпих един доста грозен JavaScript, който след като определи местоположението на потребителя, извлича близките места от FourSquare и ги показва като списък. До името на всяко място поставих бутон, чрез който потребителя да се &#8222;чекира&#8220; в това място. Използването на приложението е песен в сравнение на другите приложения за Symbian. Обаче за да го покажа на хората, не стига то да работи, кода трябва да е малко по-елегантен, че да не се срамувам от него. Трябваше ми нещо секси, и си спомнях, че <a href="http://blog.rstankov.com/">Радо Станков</a> вече ни е показвал <a href="http://www.slideshare.net/rstankov/javascript-eventdriven-architecture">нещо наистина възбуждащо</a>. За това как го приложих обаче ще ви разкажа в следващата част.</p>
<p>Връзки:</p>
<ul>
<li><a href="http://groups.google.com/group/foursquare-api/web/api-documentation?pli=1">Първата версия на Foursquare API, с която започнах</a></li>
<li><a href="http://developer.foursquare.com/docs/">Foursquare APIv2</a></li>
<li><a href="http://hueniverse.com/oauth/">oAuth от първа ръка</a></li>
</ul>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2163&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2163.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Анатомия на едно мобилно уеб приложение, част първа: къде съм аз?</title>
		<link>http://greatgonzo.net/pages/2151.html</link>
		<comments>http://greatgonzo.net/pages/2151.html#comments</comments>
		<pubDate>Fri, 07 Jan 2011 21:58:06 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[FiveCorners]]></category>
		<category><![CDATA[Foursquare]]></category>
		<category><![CDATA[GeoLocation]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2151</guid>
		<description><![CDATA[От доста време търсех задачка, върху която да опитам да приложа различни NEWT. И както изисква добрата практика, намерих поле за изява в решаването на собствените си нужди. Работата е там, че от както ползвам Foursquare пробвах две различни приложения [...]]]></description>
			<content:encoded><![CDATA[<p>От доста време търсех задачка, върху която да опитам да приложа различни <a href="http://www.brucelawson.co.uk/2010/meet-newt-new-exciting-web-technologies/"><abbr title="New Exciting Web Technologies">NEWT</abbr></a>. И както изисква добрата практика, намерих поле за изява в решаването на собствените си нужди. Работата е там, че от както ползвам Foursquare пробвах две различни приложения за Symbian, но и двете имаха един и същ недостатък &#8211; не работят без GPS приемникът на телефона да работи. Проблемът е, че GPS приемникът на моя телефон изпитва големи трудности при намирането на сателитите, ако няма връзка с Интернет, а пък аз все още се дърпам от абонаментите, включващи канал за данни. И така, в моя случай или има GPS (когато съм отвън), или има Интернет (когато мястото, където се намирам, предлага WiFi). И така, решението на проблема е</p>
<h2>GeoLocation API</h2>
<p>Въпреки че не е част от спецификацията на HTML5, GeoLocation API често се споменава заедно с него и е естествена част от NEWT. Позволява ни чрез съвсем малко JavaScript да определим местоположението на потребителя. Отворих една страничка, демонстрираща възможностите на GeoLocation и бях изумен от точността &#8211; точката върху картата беше на 100 &#8211; 200 метра от вкъщи. Напълно достатъчно за нуждите ми. <span id="more-2151"></span></p>
<p>Да видим как става номера:</p>
<pre><code>if (navigator.geolocation) {
	navigator.geolocation.getCurrentPosition(
		function (position) {
                    // имаме местоположението на потребителя: position.coord.lat и position.coords.lon
		},
		function (error) {
                    // грешка при определянето на местоположението
		}
	);
}
else {
    // браузъра не поддържа GeoLocation API
}</code></pre>
<p>Можете да разчитате, че успешно ще установите мястото на потребителя, стига той да ползва достатъчно нова версия на Firefox, Safari, Chrome или Opera. Но за мен е интересно дали ще работи на мобилния ми телефон. Моят парашут се отвори, когато инсталирах Opera Mobile 10.1, а собствениците на iPhone или телефон с Android могат да бъдат локализирани и без нужда от инсталиране на допълнителен софтуер. Единствената особеност е, че някои устройства с Android 2.1 изискват да е включен GPS приемника, въпреки, че не разчитат на него (пробвах с Globul Q1 SE). </p>
<h2>Как работи GeoLocation?</h2>
<p>Добре де, а как браузъра определя местоположението без GPS, ще попитате вие? Браузърите използват няколко метода, чрез които определят местоположението в зависимост от наличните GPS и мрежови устройства.  </p>
<p>Когато има наличен GPS, браузърите на мобилни телефони могат да използват данните от него, за да установят с голяма точност местоположението на потребителя. Този подход работи на телефони с Android OS и на iPhone, но WebKit браузърат на моята Nokia 5800 не поддържа въобще GeoLocation API, въпреки, че телефона има GPS.</p>
<p>Когато няма GPS, или той не може да установи местоположението, браузъра използва други методи. Първата възможност е чрез информация от GSM мрежата &#8211; клетките са с известно местоположение и чрез изчисление на базата на силата на сигнала от различните клетки местоположението може да се установи с достатъчно голяма точност. Това е всъщност една от функциите на <a href="http://en.wikipedia.org/wiki/Assisted_GPS">A-GPS</a> устройствата, вграждани в мобилните телефони. Другата е изтеглянето на алманаха с местоположението на сателитите през Интернет, което ускорява установяването на местоположението.</p>
<p>Когато и този метод не е наличен, има още един начин местоположението да се установи със задоволителна точност. Има различни фирми, които обикалят по улиците с автомобили и събират информация за силата на сигнала на различните WiFi мрежи. След това може лесно по обратния път да се установи къде се намира дадено устройство по списъка с видими мрежи и тяхната сила. Това е и основния метод, който използват Opera и Firefox, като и двата браузъра правят заявка до услуга на Google за това. За Opera това се разбира лесно &#8211; първото нещо, което браузъра ви пита, преди да върне резултат за местоположението, е дали сте съгласни с общите условия на Google за тази услуга. За Firefox го разбрах, докато следях заявките от браузъра чрез разширението TemperData.</p>
<p>И последният възможен метод за установяване на местоположението е чрез GeoIP. Това е най-неточния метод &#8211; в най-добрия случай местоположението ще е с точност до град или квартал (дали?), което са от няколко километра до десетки километри. А в най-лошия случай GeoIP базата данни може да позиционира потребителя в съвсем друга държава или континент.</p>
<h2>По-подробно за методите на API-то</h2>
<p>Но да се върнем към JavaScript и GeoLocation API. В горния пример показах как в общи линии се използва методът <code>getCurrentPosition</code>. Този метод връща текущата позиция на браузъра, като приема три аргумента. Първият е callback функция, която да се изпълни при успешно установяване на местоположението, и която приема като параметър обект, описващ местоположението. Вторият параметър е callback функция, която да се изпълни в случай на грешка и приемаща като параметър обект, който я описва. Третият параметър, който съм пропуснал в примера, е обект, чрез който се подават различни настройки към метода. Втория и третия аргументи могат да бъдат пропуснати.</p>
<pre><code>if (navigator.geolocation) {
    var options = {
        enableHighAccuracy = true, // Ако е истина, изисква възможно най-точни резултати
        timeout = 5000, // Колко време да чакате да получите позицията, в милисекунди
        maximumAge = 10000 // Колко стара позиция сте склонни да приемете
    }
    navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
}
else {
    // браузъра не поддържа GeoLocation API
}

function successCallback(position){
    alert(position.coords.latitude + ', ' + position.coords.longitude);
}

function errorCallback(){
    switch (error.code) {
    case error.TIMEOUT:
        alert ('Timeout');
        break;
    case error.POSITION_UNAVAILABLE:
        alert ('Position unavailable');
        break;
    case error.PERMISSION_DENIED:
        alert ('Permission denied');
        break;
    case error.UNKNOWN_ERROR:
        alert ('Unknown error');
        break;
    default:
        alert(error.message);
    }
}
</code></pre>
<p>Обектът, описващ позицията на устройството има следния вид:</p>
<pre><code>
{
    timestamp: [DOMTimeStamp],
    coords: {
        latitude: [double],
        longitude: [double],
        altitude: [double],
        accuracy: [double],
        altitudeAccuracy: [double],
        heading: [double],
        speed: [double]
    }
}
</code></pre>
<p>Ако браузърът няма възможност да установи височината, посоката или скоростта, стойността на съответното свойство трябва да е <code>null</code>.</p>
<p>Освен, че позволява да установим текущата позиция на браузъра, GeoLocation API има метод, чрез който да следим за промени на местоположението. Методът е <code>watchPosition</code> и се използва по същия начин както и <code>getCurrentPosition</code>. Разликата е, че callback функциите ще се изпълняват всеки път, когато устройството прецени, че има промяна в местоположението, и връща като резултат число подобно на <code>setTimeout</code> и <code>setInterval</code>. Следенето на позицията може да бъде прекъснато чрез метода <code>clearWatch</code>:</p>
<pre><code>if (navigator.geolocation) {
    var watch = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
    setTimeout(function(){
        navigator.geolocation.clearWatch(watch);
    },600000);
}
else {
    // браузъра не поддържа GeoLocation API
}
</code></pre>
<h2>Заключение</h2>
<p>Някои от вас може би се чудят за какво му е на сайта да знае къде се намира потребителя, други вече си представят как ще следят жената или разтресения от пубертета син, а <a href="http://bogomil.info/">Бого</a> ще е загрижен за личната неприкосновеност на потребителите (и с право!). </p>
<p>Да започнем от личната неприкосновеност &#8211; според спецификацията на W3C браузъра не трябва да издава местоположението си без изричното съгласие на потребителя. Тествах поведението на Firefox, Opera и Chrome на десктоп (Linux и Windows) и на браузърите на iPhone, няколко Android устройства, и на Opera Mobile на Symbian, и всички те спазват това изискване. Нещо повече, на iPhone трябваше да разреша някаква опция, забита из настройките на телефона, за да сработи приложението ми.</p>
<p>GeoLocation API ни позволява да навлезем в територия, запазена до скоро само за традиционните приложения. Вече имам идеи за няколко такива, повтарящи функционалността на приложения за Android или iPhone, но работещи на всякакви устройства без нужда от пренаписване. Освен това вече можем да предложим съдържанието по различен начин, знаейки, че потребителят се движи и вниманието му не е изцяло заето със сайта. Можем да предложим по-адекватни резултати от търсенето на &#8222;магазин за сърф&#8220;, знаейки, че той е в Бургас, а не във Варна. Следващата граница е вашето въображение.</p>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2151&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2151.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Позор!</title>
		<link>http://greatgonzo.net/pages/2142.html</link>
		<comments>http://greatgonzo.net/pages/2142.html#comments</comments>
		<pubDate>Fri, 22 Oct 2010 20:26:05 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Музика]]></category>
		<category><![CDATA[Стара планина]]></category>
		<category><![CDATA[Щурците]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2142</guid>
		<description><![CDATA[Не, не вярвам, че някое старо момче ще се съгласи да им каже мерси защото днес е с дълги коси. Ей на, намериха се. И то не кои да е, а най-успелите, онези, които ни даваха надежда, че и в [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Не, не вярвам, че някое старо момче<br />
ще се съгласи да им каже мерси<br />
защото днес е с дълги коси.</p></blockquote>
<p>Ей на, намериха се. И то не кои да е, а най-успелите, онези, които ни даваха надежда, че и в България има място за рок. Групата, която изпя &#8222;Аз не съм комунист и никога няма да бъда!&#8220; сега приема почести от агент Гоце!</p>
<p>Ако не сте се сетили за какво става дума, новината на деня е, че <a href="http://rollingstone.bg/%D0%BF%D1%80%D0%B5%D0%B7%D0%B8%D0%B4%D0%B5%D0%BD%D1%82%D1%8A%D1%82-%D0%BF%D1%8A%D1%80%D0%B2%D0%B0%D0%BD%D0%BE%D0%B2-%D0%B2%D1%80%D1%8A%D1%87%D0%B8-%D0%BE%D1%80%D0%B4%D0%B5%D0%BD%D0%B8%D1%82%D0%B5/">президентът е наградил Щурците с ордени “Св. св. Кирил и Методий”</a>. Въпросът не е заслужават ли Щурците ордени или не. Естествено, че са заслужили много повече за това, че в продължение на 20 години свиреха рок в комунистическа България, че вдъхновяваха младите хора (и мен включително), че чрез музиката си ни даваха глътка свобода, когато ни беше нужна. Обаче от агент Гоце ли чакаха награда?</p>
<p>Не мога да не направя паралел с едно друго събитие, случило се точно на днешния ден през 1965 година. Преди 45 години <a href="http://www.thisdayinrock.com/index.php/general/1965-queen-elizabeth-ii-awards-the-beatles-the-order-of-the-british-empire-john-lennon/">кралица Елизабет II награждава The Beatles с ордените на Британската империя</a>. Разликата с онова събитие е, че Джон Ленън връща своя в знак на протест срещу подкрепата на Британското правителство на войната във Виетнам. </p>
<p>Защо Щурците нямаха доблестта да откажат ордените, връчени им от бивш агент на Държавна сигурност?</p>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2142&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2142.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>CSS3 в действие: купчинка полароиди</title>
		<link>http://greatgonzo.net/pages/2132.html</link>
		<comments>http://greatgonzo.net/pages/2132.html#comments</comments>
		<pubDate>Wed, 20 Oct 2010 05:46:22 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[box-shadow]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS transforms]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[RGBa]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=2132</guid>
		<description><![CDATA[Не, това не е нито първия, нито последния, нито най-хубавия, надявам се не е и най-грозния дизайн, опитващ се да пресъздаде визията на небрежно разхвърляни върху масата снимки от фотоапарат Полароид. Целта на тази статия е да покажа как можете [...]]]></description>
			<content:encoded><![CDATA[<p>Не, това не е нито първия, нито последния, нито най-хубавия, надявам се не е и най-грозния дизайн, опитващ се да пресъздаде визията на небрежно разхвърляни върху масата снимки от фотоапарат Полароид. Целта на тази статия е да покажа как можете да използвате CSS3, за да постигнете впечатляващи визуални ефекти, като заедно с това не нарушавате функционалността за потребителите, използващи по-стари браузъри.</p>
<p>Идеята естествено ми дойде докато гледах подобна галерия, демонстрираща възможностите на CSS3. Поработих доста по моя вариант, за да го направя да изглежда добре дори и на по-стари браузъри или на малкия екран на мобилно устройство. Освен това трябваше да измисля някаква хитрина, за да изглеждат снимките разхвърляни, защото списъкът се генерира динамично и няма как да ги разхвърлям целенасочено. </p>
<p>За да постигна желаната от мен визия използвах няколко свойства, коите вече имат доста добра поддръжка в текущите или бъдещите версии на основните браузъри. Арсеналът включва селектори <code>:nth-child()</code>, <code>box-shadow</code>, трансформации, медийни заявки, RGBa цветове. За съжаление се наложи да напиша доста еднотипни редове с декларации, различаващи се само по префиксите за различните браузъри, но това е неизбежно ако искаме да се насладим на най-новите възможности на CSS.<span id="more-2132"></span></p>
<p>Първата стъпка както винаги е добре структурирания код. Блокът с картинките, които исках да украся изглежда така:</p>
<pre>&lt;ul class="polaroids"&gt;
    &lt;li&gt;
	&lt;a href="" title=""&gt;
		&lt;img src="" alt="" /&gt;
		&lt;p&gt;&lt;/p&gt;
	&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;
	&lt;a href="" title=""&gt;
		&lt;img src="" alt="" /&gt;
		&lt;p&gt;&lt;/p&gt;
	&lt;/a&gt;
    &lt;/li&gt;

...

&lt;/ul&gt;</pre>
<p>Доста проста структура, използвал съм HTML5, за да мога да заградя с един <code>a</code> елемент самата картинка и параграфа с описанието. Основните стилове за оформянето на галерията също не са нищо особено:</p>
<pre>ul.polaroids {
	clear:both;
	width:90%;
	margin:60px auto;
}

ul.polaroids li {
	display: inline;
	vertical-align:top;
	width: 200px;
}

ul.polaroids li a {
	display: inline-block;
	padding: 10px 10px 20px 10px;
	width: 180px;
	margin:15px;
	border: 1px solid #BFBFBF;
	background-color: white;
	vertical-align:top;
	text-decoration: none;
	color: #333;
	font-family:Georgia,"Lucida bright","Times new roman",serif;
	z-index: 0;
}

.polaroids li a:hover,
.polaroids li a:focus,
.polaroids li a:active {
	outline: 5px solid #ddd;
}</pre>
<p>Единственото, което може да ви се стори странно е изборът на стойности на свойствата display на <code>li</code> и <code>a</code> елементите. Те са избрани така, че снимките да се подреждат естествено в редове и колони и да могат да се застъпват, когато започнем да ги &#8222;разхвърляме&#8220; по екрана. Друго, на което държа да обърна внимание е последната декларация. Дефинирал съм стилове за псевдокласовете <code>:hover</code>, <code>:active</code> и <code>:focus</code>, за да сигнализирам на потребителите, ползващи само клавиатура, кой е активния елемент.</p>
<p>Сега вече идва трудното. Искаме да завъртим снимките на различни ъгли, да намалим в различна степен размерите и да им пуснем лека светлосянка. Когато потребителят премине с мишката над някоя снимка (или я фокусира с клавиатурата), искаме тя да се завърти хоризонтално, да е с нормалният си размер за да изглежда добре, и светлосянката да се измести и изсветли, така че да създадем ефект все едно сме я дигнали над масата. </p>
<p>Нека на сцената излязат CSS3 трансформациите сега!</p>
<pre>-webkit-transform: rotate(10deg) scale(.7);
-moz-transform: rotate(10deg) scale(.7);
-o-transform: rotate(10deg) scale(.7);
transform: rotate(10deg) scale(.7);</pre>
<p>Както виждате, една и съща декларация е повторена четири пъти. По веднъж за WebKit, Mozilla и Opera с префикс и една декларация без префикс за браузърите, които ще поддържат това свойство според спецификацията (IE9 например). Тук съм приложил две трансформации наведнъж &#8211; завъртане на 10 градуса по часовниковата стрелка (<code>rotate(10deg)</code>) и намаляване на елемента до 70% от първоначалните размери (<code>scale(.7)</code>). Другите възможности за трансформиране са преместване (<code>translate</code>), наклоняване или изкривяване (<code>skew</code>) или подаване на матрица на трансформацията. Но най-добре прегледайте <a href="http://www.w3.org/TR/css3-2d-transforms/">спецификацията на модула за 2D трансформации</a>.</p>
<p>Това добре, обаче как да създадем впечатление за разхвърляност? Идеята, която ми хрумна е да задам пет различни трансформации като използвам <code>:nth-child()</code> псевдокласове. Ако броят снимки на ред не съвпада с броя варианти на трансформациите, това ще създаде впечатление за неподреденост. Чрез псевдокласа <code>:nth-child</code> можем да избираме елементи, чийто индекс в списъка с дъщерни елементи отговаря на формулата <code>an+b</code>, където <code>n</code> е индекса на елемента, започвайки от 0. В моя случай селекторите са <code>:nth-child(5n)</code>, <code>:nth-child(5n+1)</code> до <code>:nth-child(5n+4)</code>. Освен различни ъгли на завъртане и различен мащаб им зададох и различен <code>z-index</code>, за да подсиля усещането за разхвърляност. </p>
<p>Първоначално имах идея да направя два набора от правила &#8211; един набор от примерно 5 различни ъгъла на завъртане и друг набор от 7 различни мащаба. Този подход естествено не сработи, но ще оставя на вас да помислите защо.</p>
<p>Какво остана? Да опишем свойствата на <code>:hover</code>, <code>:active</code> и <code>:focus</code> псевдокласовете като зададем по-голям <code>z-index</code>, нулеви стойности на транформациите и по-широка светлосянка. </p>
<p>А, светлосенките! Естествено, на помощ идват <code>box-shadow</code> и <code>RGBa</code>. <a href="http://www.w3.org/TR/css3-background/#the-box-shadow">Свойството <code>box-shadow</code></a> описва светлосенките, като се задават последователно отместването по X, отместването по Y, ширината на зоната на разсейване на сянката и цвета и. За да са полупрозрачни сенките използвах RGBa, всички браузъри поддържащи едното, поддържат и другото, така че не е проблем да ги смесим.</p>
<p>И накрая финалните щрихи. Добавих плавни преходи между различните състояния чрес <a href="http://www.w3.org/TR/css3-transitions/">свойството transition</a> със всичките му необходими префикси, накарах снимките да се застъпват, като подадох отрицателни отстояния (<code>margin</code>) и се погрижих всичките тези глезотии да не развалят вида на галерията в по-стари браузъри или на малките екрани на телефони или други преносими устройства. За тази цел използвах медийна заявка. Отново разчитам на факта, че всички браузъри, разбиращи CSS3 трансформации, ротации, транслации, пермутации&#8230; опа, май се увлякох&#8230; та те също така разбират и медийни заявки. Като направя медийната заявка да е насочена към екрани по-широки от 700 пиксела успешно обхващам всичко по-голямо от iPad, що е съвременен браузър. Останалите могат да си припомнят онази реплика от История на света &#8211; сцената в която се обсъждаше бюджета на империята и отношението на сенаторите към по-неплатежоспособните им съграждани.</p>
<p><a href="http://photos.greatgonzo.net/">Завършената галерия</a> служи да споделям снимки с приятели, а можете да разгледате и <a href="http://photos.greatgonzo.net/css/site.20101019.css">пълният CSS</a>, ако желаете.</p>
<p>Като завършек ще кажа, че можете успешно да използвате всякакви CSS3 екстри, за да направите сайта си атрактивен, без да нарушавате потребителското изживяване за потребителите на по-стари браузъри. Медийните заявки са идеален инструмент за прогресивно подобряване.</p>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=2132&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/2132.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordCamp София</title>
		<link>http://greatgonzo.net/pages/846.html</link>
		<comments>http://greatgonzo.net/pages/846.html#comments</comments>
		<pubDate>Mon, 04 Oct 2010 21:30:46 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[WordCamp]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[конференция]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=846</guid>
		<description><![CDATA[Съботния ден си изкарах страхотно. От сутринта до вечерта се наслаждавах на прекрасната компания на готини хора, слушайки разнообразни лекции на теми около WordPress и блогване въобще. Първия WordCamp в София беше много як, не мога да измисля кусур на [...]]]></description>
			<content:encoded><![CDATA[<p>Съботния ден си изкарах страхотно. От сутринта до вечерта се наслаждавах на прекрасната компания на готини хора, слушайки разнообразни лекции на теми около WordPress и блогване въобще. Първия <a href="http://wordcamp.bg/">WordCamp</a> в София беше много як, не мога да измисля кусур на организацията, и въпреки, че не всички лекции ми харесаха, вечерта си легнах с усещането за добре оползотворен почивен ден.</p>
<p>Не можах да уцеля входа на Елиеф Център от първия път, но пък не се наложи да ползвам жокери и след лека заобикалка се намерих пред рецепцията. Организаторите се бяха погрижили за нас, бедните хорица, дето хич не обичаме да ставаме рано, и бяха осигурили кафе (и чай), та си сипах едно голямо се отдадох на социализация. После дойде време и за лекциите, та заедно се понесохме към залата да търсим места. Явно всички чакаха последния момент, защото места имаше разни, но с Бого и Дечо стратегически се настанихме близо до контактите. Когато започна първата лекция, залата вече беше почти пълна.</p>
<p>Повечето лекции ми бяха интересни и полезни, понякога и забавни. Освен румънските лектори, които явно не бяха подготвени за събитието, всички други говориха добре и дори презентациите за SEO не можаха да ме изгонят от залата. Мислех да пиша по-подробно за отделните лекции, но реших да разкажа само за тези, които най-много ми харесаха (разбирай половината).<span id="more-846"></span></p>
<p>Първата техничарска презентация беше на <a href="http://dankov.name/">Константин Данков</a>. Макар и не съвсем стройно, Мързеливеца успя да обясни как се създава дъщерна тема на K2. Беше ми адски полезно, защото все не остава време да прочета за родствени връзки между темите на WordPress.</p>
<p><a href="http://skanev.com/">Стефан Кънев</a> както винаги изкърти. Не знам, имам чувството, че и за квантова механика или термодинамика да седне да говори, пак ще ми е интересно. А той просто <a href="http://skanev.com/2010/10/02/wordcamp-2010-talk/">систематизира нещата</a>, до които всеки блогър (опитващ се да) пише на професионална тема достига.</p>
<p><a href="http://eenk.com">Еленко</a> говори увлекателно и като цяло презентацията му беше забавна. Описа по неговия си неповторим начин промените, настъпили в блогосферата в последно време. Изводът е, че плявата се е преместила във facebook, а машините за линкове вече спамват Twitter.</p>
<p><a href="http://bogomil.info/">Бого</a> направи интересна презентация за това как да искарваме пари, работейки с WordPress. Освен, че разказа интересни неща и говори много увлекателно, спечели поне моето възхищение с факта, че <a href="http://bogomil.info/wp">презентацията</a> беше изградена изцяло с HTML5 и CSS3 (за да се насладите пълноценно ще ви трябава Firefox 4). Бого, имаш бира от мен за това!</p>
<p>Хедлайнер на WordCamp беше <a href="http://dzver.com/blog/">Дзвер</a>, който обясни какво не трябва да се прави, ако искаме блогът ни да ни надживее. Надявам се никога да не ми се случват нещата, <a href="http://dzver.com/blog/?p=2033">описани</a> от него. Което ме подсеща да ида да си направя бекъп.</p>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=846&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/846.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>HTML5 и CSS3 &#8211; сега и веднага!</title>
		<link>http://greatgonzo.net/pages/803.html</link>
		<comments>http://greatgonzo.net/pages/803.html#comments</comments>
		<pubDate>Thu, 02 Sep 2010 20:25:42 +0000</pubDate>
		<dc:creator>Гонзо</dc:creator>
				<category><![CDATA[Уеб]]></category>
		<category><![CDATA[@font-face]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[box-shadow]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[text-shadow]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://greatgonzo.net/?p=803</guid>
		<description><![CDATA[Не знам дали сте обръщали внимание, но под всяка статия, показваща как могат да се използват новите възможности на HTML5 или CSS3 има поне един коментар от типа &#8222;ама то не работи в IE, ще трябва да почакаме&#8220;. Няма време [...]]]></description>
			<content:encoded><![CDATA[<p>Не знам дали сте обръщали внимание, но под всяка статия, показваща как могат да се използват новите възможности на HTML5 или CSS3 има поне един коментар от типа &#8222;ама то не работи в IE, ще трябва да почакаме&#8220;. Няма време за чакане, ако не искате да изпуснете влака, качвайте се сега, защото после догонването е трудно. Бъдещето идва и няма да чака вас!</p>
<p>Въпреки, че и двата стандарта са все още в различни фаза на незавършеност, отделни техни модули не само са придобили стабилен вид, но и вече имат широка поддръжка в различните браузъри. А ако толкова много държите на IE, много от нещата или деградират елегантно, или има има специфичен начин за постигане на ефекта. А и нали не вярвате, че <a href="http://dowebsitesneedtolookexactlythesameineverybrowser.com/">сайтовете трябва да изглеждат еднакво във всеки браузър</a>?</p>
<p>И така, да видим няколко неща от HTML5 и CSS3, които можем да използваме сега и веднага.<span id="more-803"></span></p>
<h2>Нови типове <code>input</code> елементи</h2>
<p>HTML5 дефинира една купчина нови типове елементи за вход от потребителя. Специални елементи за адрес на сайт или електронна поща, за въвеждане на числа чрез бутончета нагоре &#8211; дадолу или чрез плъзгач, за въвеждане на часове и дати. И няма ама абсолютно никакъв проблем да ги ползвате, защото старите браузъри вместо непознатите типове <code>input</code> ще използват поле за текст. Ако много държите, с малко JavaScript можете да оправите нещата. А предимствата са, че потребителите на съвременни браузъри ще имат по-добро потребителско преживяване. Например собственицитне на iPhone (може би и други) ще виждат клавиатура, състояща се само от позволени знаци за въвеждане на URL или пощенски адрес.</p>
<h2>Елементите <code>video</code> и <code>audio</code></h2>
<p>Вече всички настолни браузъри освен един поддържат чудесно новите елементи за публикуване на видео или аудио в уеб-страници. Въпреки, че има различия в поддържаните формати, с много по-малко усилия можете да споделите последното забавно клипче от снощния купон. И да не забравяме, двата най-големи сайта за публикуване на видео &#8211; YouTube и Vimeo вече поддържат HTML5 видео, Vimeo дори са разработили плеър за вграждане на техните видеа в други сайтове.</p>
<h2><code>data-</code> атрибути</h2>
<p>Един чудесен начин да добавите допълнителни данни към DOM елементите във вашето уеб приложение. Стандартът предлага възможността да добавите произволен брой атрибути, започващи с <code>data-</code> и дава възможност за достъп до данните, записани в тях чрез свойството <code>dataset</code> на DOM елемента. Вече няма нужда от безброй скрити и явни елементи и нестандартни атрибути, поставени само за да дадат достъп до някакви данни чрез JavaScript.</p>
<h2>CSS3 selectors</h2>
<p>CSS3 дефинира доста интересни начини за насочване на стилове към елементи от страницата. Особено интересни са новите псевдоелементи, чрез които можете да насочите стиловете не само към първия дъщерен елемент (<code>:first-child</code>), но и към последния (<code>:last-child</code>) и дори към всеки елемент, чийто индекс отговаря на израз от типа a*n+b (<code>:nth-child()</code>).</p>
<h2>Светлосенки чрез <code>text-shadow</code> и <code>box-shadow</code></h2>
<p>Искате светлосенки? Няма проблем, CSS3 е насреща! Ама браузърите на някои потребители няма да ги изобразят? И какво от това, някои потребители нямат възможност да ги видят, но до скоро настоявахте да ги карате да си свалят картинките въпреки това.</p>
<h2>Цветове в RGBa</h2>
<p>Можете да направите фона на даден елемен полупрозрачен, или пък текста в него, или пък контура, както <a href="http://greatgonzo.net/pages/749.html">демонстрирах</a> вече. Вместо PNG изображения, които да забавят зареждането на сайта, можете да постигнете невероятни ефекти само с помощта на RGBa.</p>
<h2>Заоблени ъгли чрез <code>border-radius</code></h2>
<p>Стига вече с тези плъзгащи се врати, със CSS3 можете да постигнете същия ефект и много повече. По един или друг начин свойството се поддържа още от Firefox 1 и ако още не сте го използвали, вече е крайно време.</p>
<h2>CSS3 Media queries</h2>
<p>Пробвали ли сте как изглежда сайта ви на голям монитор? А на мобилен телефон или iPad? Не е както си го представяхте, нали? С помощта на CSS3 media queries можете да приложите различни стилове в зависимост от разделителната способност, ориентацията, или броя цветове, които поддържа екрана. Само с малко допълнителен CSS можете да пригодите сайта си за мобилни устройства и екрани с висока резолюция. Адаптивния дизайн е новото черно!</p>
<h2>Шрифтове с <code>@font-face</code></h2>
<p>О, щях да забравя, <code>@font-face</code>! Това беше горещата тема преди половин или една година, нали не сте забравили? Все едно дали ще предпочетете удобството на някоя от многото услуги, предоставящи шрифтове за уеб или ще публикувате шрифтовете сами. Време е да се освободите от оковите на web-save шрифтовете и да покажете, че типографията в уеб има бъдеще.</p>
<p>След всичко това следва и задължителния списък с помощни материали:</p>
<ul>
<li><a href="http://www.w3.org/TR/2010/WD-html5-20100624/">HTML5</a></li>
<li><a href="http://www.w3.org/standards/techs/css#drafts">Модулите на CSS3</a></li>
<li><a href="http://html5doctor.com/">HTML5 Doctor</a></li>
<li><a href="http://diveintohtml5.org/">Dive Into mHTML5</a></li>
<li><a href="http://www.css3.info/">CSS3.info</a></li>
<li><a href="http://www.alistapart.com/">A List Apart</a></li>
<li><a href="http://google.com">Или просто потърсете</a></li>
</ul>
<img src="http://greatgonzo.net/?ak_action=api_record_view&id=803&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://greatgonzo.net/pages/803.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

