<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2russianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Design For Masters</title>
	
	<link>http://designformasters.info</link>
	<description>Сайт для веб-разработчиков</description>
	<pubDate>Wed, 03 Nov 2010 08:05:04 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DesignForMasters" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="designformasters" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">DesignForMasters</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FDesignForMasters" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FDesignForMasters" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FDesignForMasters" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/DesignForMasters" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FDesignForMasters" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FDesignForMasters" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FDesignForMasters" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://lenta.yandex.ru/settings.xml?name=feed&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FDesignForMasters" src="http://lenta.yandex.ru/i/addfeed.gif">?????? ? ??????.?????</feedburner:feedFlare><item>
		<title>Краткая история HTML</title>
		<link>http://designformasters.info/posts/brief-history-of-html/</link>
		<comments>http://designformasters.info/posts/brief-history-of-html/#comments</comments>
		<pubDate>Mon, 10 May 2010 07:51:37 +0000</pubDate>
		<dc:creator>Jeremy Keith</dc:creator>
		
		<category><![CDATA[Кодинг]]></category>

		<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=777</guid>
		<description><![CDATA[
HTML объединяющий язык World Wide Web, с&#160;помощью его простых тегов человечество создало фантастически разнообразную сеть, от&#160;крупнейших Amazon, eBay и&#160;Wikipedia до&#160;личных блогов и&#160;сайтов, посвященных котам похожим на&#160;Гитлера.

Как и&#160;сам веб, HyperText Markup Language детище Тима Бернерс-Ли. В&#160;1991 году он&#160;создал документ названный «HTML Tags», в&#160;котором предложил около двух дюжин элементов для создания веб-страниц.
Идея использовать теги, заключенные между угловыми [...]]]></description>
			<content:encoded><![CDATA[<span id="more-777"></span><!--noteaser-->
<p>HTML объединяющий язык World Wide Web, с&nbsp;помощью его простых тегов человечество создало фантастически разнообразную сеть, от&nbsp;крупнейших Amazon, eBay и&nbsp;Wikipedia до&nbsp;личных блогов и&nbsp;сайтов, посвященных котам похожим на&nbsp;Гитлера.</p>
<!--<p>HTML5 это самые масштабные изменения, но&nbsp;далеко не&nbsp;первое обновление HTML, развивавшегося на&nbsp;протяжениии всего своего существования.</p>-->
<p>Как и&nbsp;сам веб, HyperText Markup Language детище Тима Бернерс-Ли. В&nbsp;1991 году он&nbsp;создал документ названный «HTML Tags», в&nbsp;котором предложил около двух дюжин элементов для создания веб-страниц.</p>
<p>Идея использовать теги, заключенные между угловыми скобками, не&nbsp;его, такие теги уже были в&nbsp;формате SGML (Standard Generalized Markup Language). Тим понимал, что создавать новые стандарты нужно на&nbsp;базе существующих, а&nbsp;разработчики HTML5 и&nbsp;сейчас в&nbsp;полной мере следуют этому принципу.</p>

<h2>От IETF до&nbsp;W3C: Путь к&nbsp;HTML 4</h2>
<p>Стандарта HTML 1 никогда не&nbsp;было, первой официальной спецификацией стал HTML 2.0, опубликованный IETF (Internet Engineering Task Force). Многие элементы в&nbsp;этой спецификации были заимствованы из&nbsp;существующих реализаций, например, тег &lt;img&gt; уже поддерживался, лидировавшим тогда браузером Mosaic.</p>
<p>Позже на&nbsp;смену IETF пришел W3C (World Wide Web Consortium) и&nbsp;следующие версии стандарта HTML публиковались на&nbsp;<a href="http://www.w3c.org">www.w3c.org</a>. Во&nbsp;второй половине девяностых HTML претерпел множество изменений и&nbsp;ревизий, последней в&nbsp;череде которых стала спецификация HTML 4.01.</p>
<p>В начале двухтысячных HTML ожидала первая серьезная реформа.</p>

<h2>XHTML 1: HTML как XML</h2>
<p>Следующая после HTML 4.01, версия языка стал XHTML 1.0, X значит eXtensible (расширяемый).</p>
<p>Содержание спецификации XHTML 1.0 не&nbsp;сильно отличалось от&nbsp;HTML 4.01. Не&nbsp;было добавлено ни&nbsp;одного нового элемента или атрибута. Но&nbsp;отличался синтаксис языка. HTML дает авторам значительную свободу в&nbsp;написании элементов и&nbsp;атрибутов, XHTML требует следовать правилам XML, более строгого языка разметки, на&nbsp;котором основаны многие технологии W3C.</p>
<p>У строгих правил есть свои преимущества, они заставляют разработчиков использовать единый стиль кодирования, если прежде теги и&nbsp;атрибуты могли быть в&nbsp;верхнем регистре, нижнем регистре и&nbsp;любой их&nbsp;комбинации, то&nbsp;в&nbsp;XHTML 1.0 все теги и&nbsp;атрибуты должны быть в&nbsp;нижнем регистре.</p>
<p>Выход XHTML 1.0 совпал со&nbsp;значительным улучшением поддержки CSS в&nbsp;браузерах. Веб-разработчики, вдохновленные появлением стандартов, считали строгий синтаксис XHTML лучшим способом создания разметки.</p>
<p>Следующий версией стандарта разметки стал XHTML 1.1.</p>
<p>XHTML 1.0 был простым HTML переформулированным на&nbsp;XML, XHTML 1.1 стал настоящим XML, он&nbsp;больше не&nbsp;мог подаваться клиенту как text/html. Но&nbsp;если разработчик использует для документа медиа тип XML, то&nbsp;самый популярный веб-браузер, Internet Explorer, не&nbsp;сможет отобразить документ.</p>
<p>Стало заметно, что W3C теряет связь с&nbsp;современной реальностью веб.</p>

<h2>XHTML 2: О, мы&nbsp;не&nbsp;будем это терпеть!</h2>
<p>В W3C решили, что историю HTML нужно закончить на&nbsp;четвертой версии и&nbsp;начали работу над XHTML 2, стандартом призванным вести нас в&nbsp;новое будущее основанное на&nbsp;XML.</p>
<p>Несмотря на&nbsp;то, что название стандарта XHTML 2 не&nbsp;сильно отличается от&nbsp;XHTML 1, они совершенно не&nbsp;похожи. В&nbsp;отличии от&nbsp;XHTML 1, в&nbsp;XHTML 2 нет обратной совместимости с&nbsp;существующим веб-контентом и&nbsp;предыдущими версиями HTML, это должен был быть чистый язык, не&nbsp;обремененный нестройной историей предыдущих спецификаций. </p>
<p>Это была катастрофа.</p>

<h2>Раскол: WHATWG TF?</h2>
<p>Внутри W3C назревало восстание. Консорциум формулировал теоретически чистые стандарты, игнорируя потребности веб-разработчиков. Представителей Opera, Apple и&nbsp;Mozilla это не&nbsp;удовлетворяло, они хотели больше вниманию форматам которые позволяют создавать веб-приложения.</p>
<p>Ситуация достигла апогея на&nbsp;рабочей встрече в&nbsp;2004 году. Ян&nbsp;Хиксон, работавший тогда в&nbsp;Opera Software, предложил расширить возможности HTML в&nbsp;области создания веб-приложений. Предложение было отвергнуто.</p>
<p>Недовольные такой политикой Opera, Apple и&nbsp;Mozilla сформировали свою собственную рабочую группу  WHATWG (Web Hypertext Application Technology Working Group).</p>

<h2>От Web Apps 1.0 до&nbsp;HTML5</h2>
<p>Работа WHATWG, отличается от&nbsp;работы W3C. W3C использует подход основанный на&nbsp;консенсусе: вопрос поднимается, обсуждается и&nbsp;проводится голосование. В&nbsp;WHATWG вопрос также поднимается и&nbsp;обсуждается, но&nbsp;окончательное решение остается за&nbsp;редактором. Редактор Ян&nbsp;Хиксон.</p>
<p>На первый взгляд, подход W3C выглядит более демократичным и&nbsp;объективным, на&nbsp;практике политика и&nbsp;внутренние распри способствуют затягиванию принятия решений. В&nbsp;WHATWG все могут принимать участие в&nbsp;работе, но&nbsp;последнее слово остается за&nbsp;редактором, благодаря чему решения принимаются быстро. Конечно, редактор не&nbsp;имеет абсолютной власти и&nbsp;может быть отстранен решением комитета приглашенных экспертов.</p>
<p>С самого начала WHATWG начал работу над двумя расширениями HTML: Web Forms 2.0 и&nbsp;Web Apps 1.0, позже они были объединены в&nbsp;одну спецификацию названную HTML5.</p>

<h2>Воссоединение</h2>
<p>В то&nbsp;время как WHATWG начала разработку HTML5, W3C продолжал работу на&nbsp;XHTML 2. Нельзя сказать, что работа шла не&nbsp;достаточно быстро, она шла очень очень медленно.</p>
<p>В октябре 2006, Тим Бернерс-Ли признал в&nbsp;своем блоге, что попытка перевести веб с&nbsp;HTML на&nbsp;XML не&nbsp;удалась. Через несколько месяцев была создана новая рабочая группа по&nbsp;HTML, вместо того чтобы начать с&nbsp;нуля решили использовать наработки WHATWG как базу будущей версии HTML.</p>
<p>Все эти начала и&nbsp;окончания разработки сильно запутали ситуацию. W3C работает одновременно над двумя различными, несовместимыми типами разметки XHTML 2 и&nbsp;HTML 5 (обратите внимание на&nbsp;пробел перед цифрой пять). В&nbsp;то&nbsp;же&nbsp;время отдельная организация WHATWG, работает над спецификацией HTML5 (без пробела) которая используется как базис одной из&nbsp;спецификаций W3C.</p>

<h2>XHTML мертв: да&nbsp;здравствует XHTML синтаксис</h2>
<p>Ситуация начала проясняться в&nbsp;2009 году, W3C объявило, что работа над XHTML 2 не&nbsp;будет продолжена. На&nbsp;самом деле формат уже давно был мертв, и&nbsp;это заявление только официально подтвердило факт смерти.</p>
<p>Смерть XHTML 2 не&nbsp;прошла незамеченной, XML скептики использовали этот факт как возможность лишний раз высмеять тех кто использовал XHTML 1, несмотря на&nbsp;то, что XHTML 1 и&nbsp;XHTML 2 не&nbsp;имеют между собой ничего общего.</p>
<p>В то&nbsp;же&nbsp;время, разработчики, которым XHTML 1 нравился за&nbsp;более строгий стиль кодирования, опасались, что HTML5 приведет к&nbsp;возвращению небрежного кода.</p>
<p>На самом деле это не&nbsp;обязательно, HTML5 может быть строгим или свободным настолько, насколько этого хочет разработчик.</p>

<h2>Перспективы HTML5</h2>
<p>Сегодняшнее положение HTML5 не&nbsp;столь запутано как раньше, но&nbsp;все еще не&nbsp;простое.</p>
<p>Над стандартом работают две группы, с&nbsp;различной политикой и&nbsp;порядком работы, очевидно, что это не&nbsp;простой союз.</p>
<p>Похоже намечается консенсус и&nbsp;по&nbsp;вопросу «С пробелом или без?» (это HTML5 без пробела, если вам интересно).</p>
<p>Возможно самый неясный вопрос для разработчиков желающих использовать HTML5 «Когда он&nbsp;будет готов?»</p>
<p>В одном из&nbsp;интервью, Ян&nbsp;Хиксон сказал, что HTML5 может получить статус «proposed recommendation» к&nbsp;2022 году. Это вызвало волну недовольства среди веб-разработчиков, не&nbsp;понимающих, что значит «proposed recommendation», но&nbsp;знающих, что им&nbsp;не&nbsp;хватит пальцев на&nbsp;руках, чтобы посчитать сколько лет пройдет до&nbsp;2022 года.</p>
<p>Это возмущение не&nbsp;обосновано. Статус «proposed recommendation» предполагает наличие двух полных реализаций HTML5 и, учитывая объем спецификации, эта дата выглядит даже оптимистичной. В&nbsp;конце концов, и&nbsp;сейчас браузеры не&nbsp;могут похвастаться безупречной поддержкой существующих стандартов. Разработчикам Internet Explorer потребовалось почти десять лет только для того чтобы добавить поддержку элемента abbr.</p>
<p>Действительно важной датой для HTML5 можно считать 2012 год, к&nbsp;этому времени он&nbsp;должен получить статус «candidate recommendation».</p>
<p>Но даже эта дата не&nbsp;особенно важна для веб-разработчиков, самое большое значение имеет то, когда браузеры начнут поддерживать новые возможности. Мы&nbsp;начинали использовать части стандарта CSS 2.1 как только браузеры начинали их&nbsp;поддерживать, если бы&nbsp;мы&nbsp;ждали пока все браузеры будут полностью поддерживать CSS 2.1, мы&nbsp;бы&nbsp;все еще ждали. То&nbsp;же&nbsp;самое с&nbsp;HTML5, не&nbsp;будет такой даты, чтобы можно было сказать, да&nbsp;сегодня язык готов к&nbsp;использованию. Мы&nbsp;можем начинать использовать части спецификации как только появиться их&nbsp;поддержка в&nbsp;браузерах.</p>
<p>HTML5 это не&nbsp;совершенно новый стандарт, созданный с&nbsp;нуля, это эволюционное, а&nbsp;не&nbsp;революционное изменение языка разметки, если сейчас вы&nbsp;используете HTML, то&nbsp;вы&nbsp;уже используете HTML5.</p>
<p><strong>Translated with the permission of <a href="http://www.alistapart.com/">A List Apart Magazine</a><sup class="printOnly">7</sup> and the author[s].</strong></p><h2>Похожие статьи</h2><ul><li><a href="http://designformasters.info/posts/future-of-the-web">HTML5, XHTML2, и будущее Web</a></li></ul>
<p><a href="http://feedads.g.doubleclick.net/~a/81c5h_-tcrUlKuDI07ryHQwVKu8/0/da"><img src="http://feedads.g.doubleclick.net/~a/81c5h_-tcrUlKuDI07ryHQwVKu8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/81c5h_-tcrUlKuDI07ryHQwVKu8/1/da"><img src="http://feedads.g.doubleclick.net/~a/81c5h_-tcrUlKuDI07ryHQwVKu8/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=HIpoUQv1J98:znsLxsJRDGQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=HIpoUQv1J98:znsLxsJRDGQ:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/brief-history-of-html/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Юзабилити сайта Почты России</title>
		<link>http://designformasters.info/posts/russianpost/</link>
		<comments>http://designformasters.info/posts/russianpost/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 10:26:46 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Design For Masters]]></category>

		<category><![CDATA[Статьи]]></category>

		<category><![CDATA[юзабилити]]></category>

		<category><![CDATA[юмор]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=734</guid>
		<description><![CDATA[Неделю назад написал этот пост, потом остыл немного и&#160;решил, что это все таки не&#160;уровень поста, но&#160;если уж&#160;это не&#160;один я&#160;заметил, то&#160;вытаскиваю свой черновик.
История: где-то задержалось заказное письмо, решил посмотреть нельзя ли&#160;проверить статус доставки. Набираю в&#160;гугле "почта россии", и&#160;вижу, что да, можно, сразу две ссылки "Почта России: Отслеживание почтовых отправлений". Возрадовался. Рано.

Жму на&#160;ссылку и... Ошибка 404. Страница [...]]]></description>
			<content:encoded><![CDATA[<p>Неделю назад написал этот пост, потом остыл немного и&nbsp;решил, что это все таки не&nbsp;уровень поста, но&nbsp;если уж&nbsp;это не&nbsp;один я&nbsp;заметил, то&nbsp;вытаскиваю свой черновик.
История: где-то задержалось заказное письмо, решил посмотреть нельзя ли&nbsp;проверить статус доставки. Набираю в&nbsp;гугле "почта россии", и&nbsp;вижу, что да, можно, сразу две ссылки "Почта России: Отслеживание почтовых отправлений". Возрадовался. Рано.</p>
<span id="more-734"></span>
<p>Жму на&nbsp;ссылку и... Ошибка 404. Страница не&nbsp;найдена.</p>
<p>Жму вторую... 404.</p>
<p>Гомерический хохот. Они потеряли даже страницу поиска отправлений — это уже политика компании.</p>
<p>Ну политика, политикой, а&nbsp;письмо искать нужно, иду на&nbsp;главную, а&nbsp;куда еще все остальные ссылки на&nbsp;404-й ведут на&nbsp;404-ю.</p>
<p>Главная страница Почты России радует морем полезной информации:<br>атмосферное давление и&nbsp;температура в&nbsp;Москве и&nbsp;Санкт-Петербурге, курс доллара и&nbsp;евро, индекс ММВБ, индекс РТС и&nbsp;отраслевые индексы РТС, ссылки на&nbsp;Аэрофлот, РЖД, Внешэкономбанк, Мин связи, различные почтовые союзы, как раз то, что нужно людям на&nbsp;почтовом сайте. [<a href="http://designformasters.info/stuff/russianpost/home.png">как это выглядело</a>]</p>
<p>Поиска отправлений пока не&nbsp;видно, но&nbsp;гугл помнит, а&nbsp;значит где-то оно здесь было. Пройдя по&nbsp;всем станицам главного меню, обращаю внимание на&nbsp;баннер "Вход для клиентов". "Вход для клиентов" у&nbsp;меня ассоциируется с&nbsp;закрытой авторизацией частью сайта, но&nbsp;больше пойти некуда, решаюсь.&nbsp;</p>
<p><img src="http://designformasters.info/stuff/russianpost/forclients.png" width="164" height="232" alt="">
<p>Не зря. За&nbsp;баннером страница которую следовало сделать главной, информация об&nbsp;услугах и&nbsp;долгожданный поиск отправлений, который удивил тем, что работает. Оказывается письмо никак не&nbsp;может преодолеть последнюю милю от&nbsp;почтового отделения. Месяц уже не&nbsp;может. Придется пойти помочь.</p>
<h3>Прочие достоинства</h3>
<p>Микрополе поиска.</p>
<p><img src="http://designformasters.info/stuff/russianpost/search.png" width="116" height="78" alt="">
<p>Потерявшиеся сертификаты соответствия системы менеджмента качества требованиям стандарта ИСО 9001:2000, выглядят просто символично. Кстати, кликабельные, ведут на&nbsp;404-ю.</p>
<p><img src="http://designformasters.info/stuff/russianpost/quality.png" width="600" height="94" alt="">
<p>В фотогалерее есть обои рабочего стола. Им&nbsp;тут самое место.</p>
<p><img src="http://designformasters.info/stuff/russianpost/wallpaper.png" width="541" height="321" alt="">
<p>Отличные примеры, демонстрирующие почему не&nbsp;нужно использовать justify.</p>
<p><img src="http://designformasters.info/stuff/russianpost/justify.png" width="313" height="176" alt="">
<p>Кстати, нужно отметить, что над сайтом уже начали работать, как минимум "Вход для клиентов" переименовали в&nbsp;"Услуги и&nbsp;сервисы", что уже намного лучше.
<p><a href="http://feedads.g.doubleclick.net/~a/7QnS9ndk21APYIanBUzD-OwrRfY/0/da"><img src="http://feedads.g.doubleclick.net/~a/7QnS9ndk21APYIanBUzD-OwrRfY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/7QnS9ndk21APYIanBUzD-OwrRfY/1/da"><img src="http://feedads.g.doubleclick.net/~a/7QnS9ndk21APYIanBUzD-OwrRfY/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=HUz_LbQ04BU:yEm6kTe6sFo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=HUz_LbQ04BU:yEm6kTe6sFo:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/russianpost/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MVC в JavaScript</title>
		<link>http://designformasters.info/posts/mvc-javascript/</link>
		<comments>http://designformasters.info/posts/mvc-javascript/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 03:48:25 +0000</pubDate>
		<dc:creator>Jonathan Snook</dc:creator>
		
		<category><![CDATA[Бизнес]]></category>

		<category><![CDATA[Кодинг]]></category>

		<category><![CDATA[Контент]]></category>

		<category><![CDATA[Статьи]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=677</guid>
		<description><![CDATA[JavaScript занимает все более важное место в&#160;веб, а&#160;значит все больше времени в&#160;графиках разработки. Приходится задуматься над тем, как сделать его пригодным для повторного использования и&#160;простым в&#160;поддержке. В&#160;этом нам может помочь MVC.



Термин MVC давно стал привычным в&#160;контексте разработки бэкэнда с&#160;использованием фреймворков, таких как Struts, Ruby on Rails, и&#160;CakePHP — истоки MVC лежат в&#160;области структурирования клиентских приложений. [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript занимает все более важное место в&nbsp;веб, а&nbsp;значит все больше времени в&nbsp;графиках разработки. Приходится задуматься над тем, как сделать его пригодным для повторного использования и&nbsp;простым в&nbsp;поддержке. В&nbsp;этом нам может помочь MVC.</p>

<span id="more-677"></span>

<p>Термин MVC давно стал привычным в&nbsp;контексте разработки бэкэнда с&nbsp;использованием фреймворков, таких как Struts, Ruby on Rails, и&nbsp;CakePHP — истоки MVC лежат в&nbsp;области структурирования клиентских приложений. Давайте посмотрим, что такое MVC, как мы&nbsp;можем использовать его, и&nbsp;какие есть готовые MVC фреймворки.</p>

<h2>Что такое MVC?</h2>

<p>Если вы&nbsp;не&nbsp;знаете, что это такое, то&nbsp;после четырех упоминаний этого акронима вам наверняка не&nbsp;терпится узнать. MVC (сокращение от&nbsp; <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller</a>) — это шаблон проектирования, который разделяет приложение на&nbsp;три части: данные (Model), представление этих данных пользователю (View) и&nbsp;действие выполняемые в&nbsp;ответ на&nbsp;активность пользователя (Controller).</p>

<p>В 1978 году в&nbsp;исследовательском центре Xerox, Trygve Reenskau <a href="http://www.ifi.uio.no/%7Etrygver/documents/9607OOUserInterface/960711-column.pdf">сформулировал основы концепции MVC (PDF)</a>: </p>

<blockquote>
<p>Объект, играющий роль модели, это компьютерное внутреннее представление этой информации. Компьютер отображает различные аспекты этой информации с&nbsp;помощью объекта View, несколько объектов View ассоциированных с&nbsp;одной и&nbsp;той же&nbsp;моделью могут быть видимы одновременно. Объект Controller транслирует команды пользователя в&nbsp;сообщения для объектов View и&nbsp;Model.</p>
</blockquote>

<p>Другими словами, когда пользователь что-то делает, это «что-то» передается контроллеру, который решает, что должно произойти дальше. Контроллер запрашивает данные модели и&nbsp;отсылает их&nbsp;виду, который показывает данные пользователю.</p>

<p>Что же&nbsp;это разделение может дать веб-разработчику.</p>

<h3>Истоки</h3>

<p>Статический документ это основа веб-страницы. Такая страница отображает состояние информации на&nbsp;сервере в&nbsp;момент ее&nbsp;создания.</p>

<p>Раньше, чтобы модифицировать данные на&nbsp;сервере мы&nbsp;создавали форму, в&nbsp;которую пользователь вводил новые данные, потом эта форма отправлялась на&nbsp;сервер, а&nbsp;пользователь получал уведомление, что действие выполнено. Но&nbsp;постоянные перезагрузки всей страницы быстро утомляют пользователя, особенно если он&nbsp;допускает ошибку и&nbsp;нужно заново внести все изменения.</p>


<h3>Прорыв</h3>

<p>Но темные времена веб закончились. JavaScript и&nbsp;Ajax, пришли нам на&nbsp;помощь, теперь мы&nbsp;можем изменять отдельные элементы страницы и&nbsp;сообщать об&nbsp;этом серверу. Особенно важно то, что теперь мы&nbsp;можем реагировать на&nbsp;действия пользователя, не&nbsp;дожидаясь ответа сервера.</p>

<p>На современном уровне сложности JavaScript приложений мы&nbsp;приходим к&nbsp;необходимости разделять компоненты приложения в&nbsp;стиле MVC. Конечно, такое разделение необходимо не&nbsp;всегда — иногда оно делает код излишне объемным. Но&nbsp;когда приложение становиться достаточно сложным, требующим взаимодействия с&nbsp;различными частями сайта, использование паттерна MVC, позволяет создавать более модульный и&nbsp;пригодный к&nbsp;повторному использованию код.</p>

<h2>Структурирование кода</h2>

<p>Обычно, если нужно проверять данные формы, мы&nbsp;устанавливаем обработчик события отправки формы, который проверяет заданные поля и&nbsp;сообщает пользователю о&nbsp;найденный ошибках.</p>


<p>Выглядит это примерно так:</p>

<pre class="prettyprint"><code>function validateForm(){
   var errorMessage = 'The following errors were found:&lt;br&gt;';
   if (document.getElementById('email').value.length == 0) {
      errorMessage += 'You must supply an email address&lt;br&gt;';
   }
   document.getElementById('message').innerHTML = errorMessage;
}</code></pre>

<p>Этот подход работает, но&nbsp;не&nbsp;отличается гибкостью. Если понадобиться добавить поля или проверять другую форму на&nbsp;другой странице, то&nbsp;придется дублировать функциональность для каждого нового поля.</p>

<h3>Вперед к&nbsp;модульности</h3>

<p>Сделаем первый шаг к&nbsp;модульности и&nbsp;разделению, добавив дополнительную семантику в&nbsp;форму. Для обязательного поля содержащего адрес электронной почты код будет примерно такой:</p>

<pre class="prettyprint"><code>&lt;input type="text" class="required email"&gt;</code></pre>

<p>Теперь скрипт может перебрать все поля формы и&nbsp;в&nbsp;зависимости от&nbsp;атрибутов, сохраненных в&nbsp;классе, проверить поле подходящим способом. Еще один плюс таких классов в&nbsp;том, что их&nbsp;можно использовать в&nbsp;CSS.</p>

<p>Мы внедрили метаданные, на&nbsp;основе которых скрипт решает, как работать с&nbsp;соответствующими данными. Но&nbsp;при таком подходе данные и&nbsp;метаданные сильно связаны с&nbsp;разметкой. К&nbsp;тому же&nbsp;сам подход несколько ограничен, трудно описать условия с&nbsp;помощью HTML, например, что делать, если необходимость или допустимые значения одного поля, зависят от&nbsp;заполненности или значения другого поля. Конечно, простейший случай можно закодировать в&nbsp;HTML, но&nbsp;это будет не&nbsp;очень красивое решение, а&nbsp;с&nbsp;усложнением зависимости оно будет просто ужасным:</p>

<pre class="prettyprint"><code>&lt;input type=&quot;checkbox&quot; name=&quot;other&quot;&gt; Other
&lt;textarea class=&quot;dependson-other&quot;&gt;&lt;/textarea&gt;</code></pre>


<p>В предыдущем примере префикс <code>dependson</code> указывает на&nbsp;то, что обязательность <code>textarea</code> зависит от&nbsp;заполненности поля <code>other</code>. Чтобы исключить такие конструкции, давайте попробуем определить всю бизнес логику в&nbsp;JavaScript.</p>

<h3>Используем JavaScript для описания сущностей</h3>

<p>Несмотря на&nbsp;то, что мы&nbsp;можем внедрить некоторую семантику и&nbsp;метаданные в&nbsp;HTML, в&nbsp;конце концов, нам придется, как то&nbsp;представлять эту информацию на&nbsp;уровне JavaScript.</p>

<p>Например:</p>

<pre class="prettyprint"><code>var fields = {
   'other': { 
       required:true 
       },
   'additional': {
       'required': {
           'other':{checked:true},
           'total':{between:[1,5]}
           },
       'only-show-if': {
           'other': {checked:true}
           }
       }
};</code></pre> 

<p>В данном случае поле <code>additional</code> зависит от&nbsp;двух других полей, и&nbsp;отображается только если пользователь активировал чекбокс <code>other</code>.</p>

<p>Несмотря на&nbsp;то, что мы&nbsp;достигли некоторого разделения, лишних зависимостей все еще много. Проверка данных все еще связана с&nbsp;отображением выявленных ошибок, а&nbsp;функция выполняющая проверку данных все еще связана с&nbsp;обработкой события и&nbsp;отвечает за&nbsp;то, чтобы форма не&nbsp;была отправлена, пока данные не&nbsp;введены корректно.</p>

<p>Давайте посмотрим, как мы&nbsp;можем структурировать код с&nbsp;помощью паттерна MVC, а&nbsp;потом вернемся к&nbsp;нашему примеру с&nbsp;проверкой данных формы.</p>


<h2>Модель</h2>

<p>Поскольку паттерн MVC состоит из&nbsp;трех компонент, мы&nbsp;должны попытаться разделить наше приложение как минимум на&nbsp;три главных объекта.</p>

<p>Выделить модель в&nbsp;отдельный объект достаточно просто, как мы&nbsp;видели в&nbsp;предыдущем примере, это происходит естественным образом.</p>

<p>Давайте посмотрим на&nbsp;другой пример, у&nbsp;нас есть календарь событий, данные каждого события сохранены в&nbsp;отдельном объекте. Методы объекта предоставляют абстрактный способ взаимодействия с&nbsp;данными. Часто эти методы называют CRUD tasks (create, read, update, delete).</p>

<pre class="prettyprint"><code>var Events = {
  get: function (id) {
    return this.data[id];
  },
  del: function (id) {
    delete this.data[id];
    AjaxRequest.send('/events/delete/' + id);
  },
  data:{
   '112': { 'name': 'Party time!', 'date': '2009-10-31' },
   '113': { 'name': 'Pressies!', 'date': '2009-12-25' }
  }
  metadata: {
    'name': { 'type':'text', 'maxlength':20 },
    'date': { 'type':'date', 'between':['2008-01-01','2009-01-01'] }
  }
}</code></pre>

<p>Модель содержит метаданные, определяющие допустимые значений полей события.</p>

<p>Кроме того CRUD методы сохраняют состояние объекта на&nbsp;сервере, например, функция delete удаляет запись локально и&nbsp;отсылает запрос на&nbsp;удаление записи на&nbsp;сервер.</p>

<h2>Вид</h2>

<p>В паттерне MVC, вид получает данные и&nbsp;определяет, как их&nbsp;отобразить. Для этого он&nbsp;может использовать существующий HTML, запрашивать HTML блок у&nbsp;сервера, или создавать его с&nbsp;помощью DOM. Вид не&nbsp;беспокоится о&nbsp;том, откуда и&nbsp;как получить данные, он&nbsp;только отображает те&nbsp;данные, которые ему передали.</p>


<pre class="prettyprint"><code>View.EventsDialog = function(CalendarEvent) {
   var html = '&lt;div>&lt;h2>{name}&lt;/h2>' +
              '&lt;div class="date">{date}&lt;/div>&lt;/div>';
   html = html.replace(/\{[^\}]*\}/g, function(key){
        return CalendarEvent[key.slice(1,-1)] || '';
        });
   var el = document.getElementById('eventshell');
   el.innerHTML = html;
}

Events.data = {
   '112': { 'name': 'Party time!', 'date': '2009-10-31' },
   '113': { 'name': 'Pressies!', 'date': '2009-12-25' }
  }

View.EventsDialog(Events.data['112']); // edits item 112</code></pre>

<p>Чтобы контроллер мог управлять видом, не&nbsp;беспокоясь о&nbsp;его внутренней реализации, добавим методы <code>open</code> и&nbsp;<code>close</code>.</p>

<pre class="prettyprint"><code>View.EventsDialog = function(CalendarEvent){ ... }
View.EventsDialog.prototype.open = function(){
   document.getElementById('eventshell').style.display = 'block';
}
View.EventsDialog.prototype.close = function(){ 
   document.getElementById('eventshell').style.display = 'none';
}

var dialog = new View.EventsDialog(eventObject);
dialog.open();
dialog.close(); </code></pre>



<h3>Обобщение Вида</h3>

<p>Легко поддаться на&nbsp;искушение сделать вид зависимым от&nbsp;модели данных и&nbsp;способа их&nbsp;получения. Но, разделяя эти функции, мы&nbsp;делаем вид пригодным для повторного использования. Если мы&nbsp;разделим данные события и&nbsp;диалог в&nbsp;нашем примере, то&nbsp;диалог можно будет использовать для любых данных, а&nbsp;не&nbsp;только для событий.</p>

<pre class="prettyprint"><code>View.Dialog = function(data) {
   var html = '&lt;h2>' + data.name + '&lt;/h2>';
   delete data.name;
   for(var key in data) {
      html += '&lt;div>' + data[key] + '&lt;/div>';
   }
   var el = document.getElementById('eventshell');
   el.innerHTML = html;
}</code></pre>

<p>Теперь у&nbsp;нас есть общий способ просмотра любых элементов, а&nbsp;не&nbsp;только событий, и&nbsp;если в&nbsp;следующем проекте понадобиться диалог, можно будет использовать этот код без изменений.</p>

<p>Многие JavaScript фреймворки разработаны с&nbsp;учетом независимости от&nbsp;данных. YUI controls, jQuery UI, ExtJS, и&nbsp;Dojo Dijit создавались с&nbsp;минимальными предположениями о&nbsp;данных, с&nbsp;которыми им&nbsp;придется работать. В&nbsp;результате эти контрольные элементы можно легко использовать в&nbsp;любых приложениях.</p>

<h3>Работа с&nbsp;методами вида</h3>

<p>Главное правило: вид не&nbsp;должен вызывать свои методы, например, диалог не&nbsp;должен открывать или закрывать себя, это работа контроллера.</p>

<p>Когда пользователь кликает кнопку Сохранить, это событие передается методу контроллера, который должен решить, что дальше делать виду, он&nbsp;может сразу закрыть диалог, или сказать виду отобразить индикатор загрузки пока сохраняются данные, а&nbsp;когда данные сохраняться, событие завершения Ajax вызова запустит другой метод контроллера, который скажет виду что нужно скрыть индикатор и&nbsp;закрыть диалог.</p>

<p>Тем не&nbsp;менее, есть ситуации, когда вид должен сам обрабатывать события и&nbsp;вызывать свои методы. Например, если диалог содержит слайдер, не&nbsp;нужно перекладывать на&nbsp;контроллер, обработку взаимодействия пользователя со&nbsp;слайдером и&nbsp;отображение его значения.</p>

<h2>Контроллер</h2>

<p>Как же&nbsp;данные Модели попадают в&nbsp;Вид? Это задача Контроллера. Он&nbsp;активируется, каким либо событием, это может быть загрузка страницы или действие пользователя, для этого обработчик события связывается с&nbsp;методом Контроллера.</p>

<pre class="prettyprint"><code>Controllers.EventsEdit = function(event) {
   /* здесь event это событие js, а не календарное событие */
   // event.target.id, содержит идентификатор соответствующего календарного события
   var id = event.target.id.replace(/[^d]/g, '');
   var dialog = new View.Dialog( Events.get(id) );
   dialog.open();
}</code></pre>

<p>Этот паттерн особенно удобен, когда данные используются в&nbsp;разных контекстах. Например, мы&nbsp;редактируем событие в&nbsp;календаре, кликаем на&nbsp;кнопку Удалить и&nbsp;теперь нам нужно убрать диалог, удалить событие в&nbsp;календаре и&nbsp;на&nbsp;сервере.</p>

<pre class="prettyprint"><code>Controller.EventsDelete = function(event) {
   var id = event.target.id.replace(/[^d]/g, '');
   View.Calendar.remove(id);
   Events.del(id);
   dialog.close();
}</code></pre>

<p>Экшены контроллера получаются простыми и&nbsp;понятными, а&nbsp;это ключ к&nbsp;созданию удобных в&nbsp;поддержке приложений.</p>

<h2>Внедряем MVC на&nbsp;примере проверки данных формы</h2>

<p>Теперь, когда мы&nbsp;знаем как разделить код на&nbsp;составные части, вернемся к&nbsp;примеру проверки полей формы с&nbsp;которого начинали. Как мы&nbsp;можем сделать его максимально гибким с&nbsp;помощью паттерна MVC?</p>


<h3>Проверка данных модели</h3>

<p>Модель определяет, корректны данные или нет, не&nbsp;беспокоясь о&nbsp;том, как это будет представлено, ей&nbsp;просто нужно определить какие поля не&nbsp;соответствуют требованиям.</p>

<p>У нас уже есть переменная  <code>fields </code>содержащая некоторые метаданные Модели. Теперь мы&nbsp;добавим к&nbsp;этому объекту метод, который может понимать и&nbsp;проверять передаваемые ему данные. Метод <code>validate</code> перебирает поля переданного ему объекта данных и&nbsp;проверяет соответствуют ли&nbsp;он&nbsp;требованиям определенным внутренними метаданными.</p>

<pre class="prettyprint"><code>var MyModel = {
   validate: function(data) {
      var invalidFields = [];
      for (var key in data) {
         if (this.metadata[key].required && !data[key]) {
             invalidFields[invalidFields.length] = {
                field: key, 
                message: key + ' is required.'
             };
         }
      }
      return invalidFields;
   },
   metadata: {
      'other': {required: true}
   }
}</code></pre>

<p>Для проверки мы&nbsp;передаем массив пар ключ/значение, где ключ это имя поля, а&nbsp;значение то, что пользователь ввел в&nbsp;поле.</p>

<pre class="prettyprint"><code>var data = { 'other': false };

var invalid = MyModel.validate(data);</code></pre>

<p>Теперь переменная <code>invalid</code>  содержит список полей, которые не&nbsp;прошли проверку, эти данные можно передать в&nbsp;вид для отображения сообщения об&nbsp;ошибках.</p>
 

<h3>Отображение полей с&nbsp;ошибками</h3>

<p>Теперь нам нужно отобразить ошибки. Отображение это работа для Вида, а&nbsp;данные об&nbsp;ошибках он&nbsp;должен получить от&nbsp;Контроллера.</p>

<pre class="prettyprint"><code>View.Message = function(messageData, type){
    var el = document.getElementById('message');
    el.className = type;
    var message = '&lt;h2&gt;We have something to bring to your attention&lt;/h2&gt;' +
    			  '&lt;ul&gt;';
    for (var i=0; i &lt; messageData.length; i++) {
       message += '&lt;li&gt;' + messageData[i] + '&lt;/li>';
    }
    message += '&lt;/ul&gt;';
    el.innerHTML = message;
}
View.Message.prototype.show() {
	/* provide a slide-in animation */
}</code></pre>

<p>Дополнительный параметр <code>type</code> позволяет указать класс элемента, чтобы применить к&nbsp;нему нужные стили.</p>


<h3>Связываем все вместе с&nbsp;помощью контроллера</h3>

<p>У нас есть модель, которая сохраняет данные и&nbsp;проверяет их&nbsp;на&nbsp;корректность, и&nbsp;вид, который может отображать сообщения об&nbsp;ошибке или успешном выполнении операции, теперь нам нужно связать их&nbsp;,чтобы проверка данных выполнялась, когда пользователь пытается отправить форму.</p>

<pre class="prettyprint"><code>addEvent(document.getElementById('myform'), 'submit', MyController.validateForm);</code></pre>

<p>Метод контроллера, получает данные, проверяет их&nbsp;корректность и&nbsp;отображает ошибки.</p>

<pre class="prettyprint"><code>MyController.validateForm = function(event){
    var data = [];
    data['other'] = document.getElementById('other').checked;
    var invalidFields = MyModel.validate(data);

    if (invalid.length) {
       event.preventDefault();
       // создает вид и отображает сообщение
       var message = new View.Message(invalidFields, 'error');
       message.show();
    }
}</code></pre>

<p>Массив данных содержит значения полей. Модель проверяет их&nbsp;корректность и&nbsp;возвращает список полей содержащих ошибки. Если одно из&nbsp;полей содержит ошибку, сохранение данных отменяется, и&nbsp;сообщение об&nbsp;ошибке передается Виду, после чего он&nbsp;его отображает.</p>

<p>Готово! Теперь у&nbsp;нас есть пригодные к&nbsp;повторному использованию Вид и&nbsp;методы проверки данных Модели.</p>


<h3>Прогрессивное улучшение</h3>

<p>В нашем примере, MVC отлично сочетается с&nbsp;прогрессивным улучшением. JavaScript просто дополняет страницу. Благодаря разделению, меньшему числу компонентов нужно понимать, что происходит на&nbsp;странице, а&nbsp;это упрощает использование прогрессивного улучшения.</p>

<p>Часто в&nbsp;таких приложениях сначала загружается веб страница, а&nbsp;потом отдельным Ajax запросом отображаемые на&nbsp;ней данные. Это может создать у&nbsp;пользователя впечатление медленного интерфейса, поскольку прежде чем он&nbsp;сможет работать со&nbsp;страницей должны выполниться два запроса.</p>

<p>Чтобы избежать задержек, сразу отображайте все данные статически, это должно быть начальное состояние. Данные представленные в&nbsp;начальном состоянии, можно продублировать в&nbsp;виде JavaScript внизу страницы и&nbsp;как только страница загрузиться JavaScript часть вашего приложения будет готова к&nbsp;работе.</p>

<p>Можно предварительно загрузить и&nbsp;некоторые дополнительные данные. Например, в&nbsp;нашем примере изначально отображаются только события текущего месяца, но&nbsp;JavaScript данные могут содержать еще и&nbsp;события предыдущего и&nbsp;следующего месяца, на&nbsp;времени загрузки это скажется незначительно, зато пользователь сможет перейти к&nbsp;следующему и&nbsp;предыдущему месяцу, не&nbsp;запрашивая данные с&nbsp;сервера.</p>


<h2>Фреймворки</h2>

<p>Многие JavaScript MVC фреймворки предоставляют намного более структурированный и&nbsp;мощный чем представленный в&nbsp;статье подход к&nbsp;MVC разработке, но&nbsp;понимание паттерна MVC и&nbsp;того как он&nbsp;может быть применен, важно и&nbsp;в&nbsp;случае разработки своего и&nbsp;в&nbsp;случае использования существующего фреймворка.</p>

<p>Вот несколько примеров таких фреймворков:</p>
<ul><li><a href="http://javascriptmvc.com/">JavaScriptMVC</a></li>
<li><a href="http://www.sproutcore.com/">SproutCore</a></li>
<li><a href="http://code.google.com/p/trimpath/wiki/TrimJunction">TrimJunction</a></li></ul>

<p>Нужно ли&nbsp;использовать фреймворк в&nbsp;конкретном случае или нет, зависит от&nbsp;сложности приложения, если приложение очень простое, то&nbsp;фреймворк будет только лишней нагрузкой.</p>

<h2>В заключение</h2>

<p>Как и&nbsp;всегда в&nbsp;разработке, вам нужно решать стоит ли&nbsp;использовать MVC в&nbsp;конкретном проекте. Для небольших приложений с&nbsp;ограниченным функционалом, это может быть не&nbsp;целесообразно, но&nbsp;чем больше ваше приложение, тем больше преимуществ вы&nbsp;получаете от&nbsp;разделения кода на&nbsp;модель, вид и&nbsp;контроллер.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/ePsGQnbjhadZP_CwHB6GxnGdcAs/0/da"><img src="http://feedads.g.doubleclick.net/~a/ePsGQnbjhadZP_CwHB6GxnGdcAs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/ePsGQnbjhadZP_CwHB6GxnGdcAs/1/da"><img src="http://feedads.g.doubleclick.net/~a/ePsGQnbjhadZP_CwHB6GxnGdcAs/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=MEY2EQ-C4xE:hSoq8_zXsRI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=MEY2EQ-C4xE:hSoq8_zXsRI:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/mvc-javascript/feed/</wfw:commentRss>
		</item>
		<item>
		<title>5 полезных утилит</title>
		<link>http://designformasters.info/posts/5-useful-small-applications/</link>
		<comments>http://designformasters.info/posts/5-useful-small-applications/#comments</comments>
		<pubDate>Sun, 23 Aug 2009 21:25:37 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Design For Masters]]></category>

		<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=601</guid>
		<description><![CDATA[Еще одна пятерка, на&#160;этот раз не&#160;кошмаров, а&#160;очень даже полезных утилит делающих ежедневную работу за&#160;компьютером удобнее.


Alax.Info NTFS Links
Упрощает создание жестких и&#160;символических NTFS ссылок, которые во&#160;многих случаях предпочтительней ярлыков.

К&nbsp;сожалению, использовать символические ссылки в&#160;Win XP не&#160;очень безопасно, так как при удалении ссылки Explorer удалит и&#160;содержимое папки, в&#160;Vista такой проблемы нет.

KeePass
Если вы&#160;не&#160;обладаете феноменальной памятью, позволяющей запомнить сотню логинов [...]]]></description>
			<content:encoded><![CDATA[<p>Еще одна пятерка, на&nbsp;этот раз не&nbsp;кошмаров, а&nbsp;очень даже полезных утилит делающих ежедневную работу за&nbsp;компьютером удобнее.
<span id="more-601"></span>

<h3><a href="http://alax.info/blog/ntfslinks">Alax.Info NTFS Links</a></h3>
<p>Упрощает создание <a href="http://ru.wikipedia.org/wiki/%D0%96%D1%91%D1%81%D1%82%D0%BA%D0%B0%D1%8F_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B0">жестких</a> и&nbsp;<a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B0">символических</a> NTFS ссылок, которые во&nbsp;многих случаях предпочтительней ярлыков.
<p><img src="http://designformasters.info/stuff/5-useful-small-applications/ntfs-links.png" alt="Alax.Info NTFS Links" width="330" height="410">
<p>К сожалению, использовать символические ссылки в&nbsp;Win XP не&nbsp;очень безопасно, так как при удалении ссылки Explorer удалит и&nbsp;содержимое папки, в&nbsp;Vista такой проблемы нет.

<h3><a href="http://keepass.info/">KeePass</a></h3>
<p>Если вы&nbsp;не&nbsp;обладаете феноменальной памятью, позволяющей запомнить сотню логинов и&nbsp;паролей на&nbsp;различных ресурсах, то&nbsp;эта программа для вас, то&nbsp;есть для большинства читателей. KeePass хранит данные учетных записей в&nbsp;одном зашифрованном файле, чтобы получить к&nbsp;ним доступ нужно ввести главный пароль. Встроенный генератор паролей избавляет от&nbsp;однообразия и&nbsp;простоты паролей.
<p><img src="http://designformasters.info/stuff/5-useful-small-applications/KeePass.png" alt="KeePass" width="600" height="352">

<h3><a href="http://nerdcave.webs.com/">Taskbar Shuffle</a></h3>
<p>Позволяет менять порядок приложений на&nbsp;панели задач и&nbsp;значков в&nbsp;трее, но&nbsp;не&nbsp;это главное, главное она позволяет закрывать задачи кликом средней кнопки мышки, точно так же&nbsp;как табы в&nbsp;браузере.

<h3><a href="http://www.teamcti.com/trayit/trayit.htm">Tray It</a></h3>
<p>Может свернуть в&nbsp;трей любое приложение, это полезно для постоянно запущенных приложений в&nbsp;которых такой режим не&nbsp;предусмотрен, например, для виртуальной машины с&nbsp;тестовым сервером.
<p><img src="http://designformasters.info/stuff/5-useful-small-applications/tray-it.png" alt="Tray It" width="245" height="203">


<h3><a href="http://windirstat.info/">WinDirStat</a></h3>
<p>Очень помогает разгрести хлам на&nbsp;диске. На&nbsp;графике хорошо видны объемные файлы и&nbsp;директории, а&nbsp;это значит, что вместо экономии на&nbsp;спичках и&nbsp;удаления множества мелочей, можно освободить место максимально эффективно.
<p><img src="http://designformasters.info/stuff/5-useful-small-applications/WinDirStat.png" alt="WinDirStat" width="600" height="600">
<p>Обнаружен забытый бекап виртуальной машины.

<h3><a href="http://yurez.narod.ru/capslang.html">caps-min.exe</a></h3>
<p>Переключает раскладку при нажатии CapsLock.
<p>Немного погуглив, я&nbsp;нашел способ обойтись только настройками в&nbsp;реестре [<a href="http://www.usnetizen.com/fix_capslock.php">Remap keys</a>, <a href="http://teerapap.blogspot.com/2008/03/switch-input-language-by-caps-lock.html">Switch input language by Caps Lock</a>], но&nbsp;пока не&nbsp;проверял работает ли&nbsp;это и&nbsp;нет ли&nbsp;каких нибудь недостатков, если кто-то попробует, отпишитесь в&nbsp;комментариях о&nbsp;результатах.
<p>Punto Switcher не&nbsp;предлагать, последний раз когда я&nbsp;его пробовал, он&nbsp;не&nbsp;всегда переключал раскладку.<h2>Похожие статьи</h2><ul><li><a href="http://designformasters.info/posts/5-applications">5 программ для веб-разработчика</a></li></ul>
<p><a href="http://feedads.g.doubleclick.net/~a/0uSY34xj9xJj3t0-hV6w9s2USLc/0/da"><img src="http://feedads.g.doubleclick.net/~a/0uSY34xj9xJj3t0-hV6w9s2USLc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/0uSY34xj9xJj3t0-hV6w9s2USLc/1/da"><img src="http://feedads.g.doubleclick.net/~a/0uSY34xj9xJj3t0-hV6w9s2USLc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=z4JTuvfhP2I:4La0m7SJV2I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=z4JTuvfhP2I:4La0m7SJV2I:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/5-useful-small-applications/feed/</wfw:commentRss>
		</item>
		<item>
		<title>5 юзабилити кошмаров на каждый день</title>
		<link>http://designformasters.info/posts/5-usability-mistakes/</link>
		<comments>http://designformasters.info/posts/5-usability-mistakes/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 13:30:00 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Design For Masters]]></category>

		<category><![CDATA[Дизайн]]></category>

		<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=606</guid>
		<description><![CDATA[Некоторые из&#160;приведенных в&#160;статье проблем встречаются практически каждый день, другие реже, но&#160;все равно успевают запомниться. Этот список — продолжение статей 10 отборных юзабилити кошмаров и&#160;15 раздражающих читателя особенностей сайта, но&#160;уже на&#160;собственных впечатлениях.

1. Прозрачный фон до&#160;загрузки картинки
Пример тут не&#160;самый подходящий, но&#160;специально искать не&#160;хотелось.

    
Такая верстка встречается достаточно часто, самый распространенный пример: внешний фон сайта [...]]]></description>
			<content:encoded><![CDATA[<p>Некоторые из&nbsp;приведенных в&nbsp;статье проблем встречаются практически каждый день, другие реже, но&nbsp;все равно успевают запомниться. Этот список — продолжение статей <a href="http://designformasters.info/posts/10-otbornyih-yuzabiliti-koshmarov/">10 отборных юзабилити кошмаров</a> и&nbsp;<a href="http://designformasters.info/posts/15-design-decisions-that-annoy-readers/">15 раздражающих читателя особенностей сайта</a>, но&nbsp;уже на&nbsp;собственных впечатлениях.</p>
<span id="more-606"></span>
<h2>1. Прозрачный фон до&nbsp;загрузки картинки</h2>
<p>Пример тут не&nbsp;самый подходящий, но&nbsp;специально искать не&nbsp;хотелось.</p>
<p>
    <img src="http://designformasters.info/stuff/5-usability-mistakes/ms-transparent-background-2.png"></p>
<p>Такая верстка встречается достаточно часто, самый распространенный пример: внешний фон сайта темный, а&nbsp;фон колонки с&nbsp;текстом светлый и&nbsp;сделан картинкой, в&nbsp;результате пока она загружается, пользователь видит абсолютно не&nbsp;читабельный темный текст на&nbsp;темном фоне.</p>
<p>Решение: проверяйте отображение сайта при отключенных изображениях, текст должен оставаться читабельным.</p>
<h2>2. Подмена кнопки в&nbsp;плеере youtube</h2>
<p>После запуска ролика, я&nbsp;часто выключаю звук, действие доведено до&nbsp;автоматизма: клик на&nbsp;Play и&nbsp;сразу клик на&nbsp;звук, к&nbsp;сожалению, после того как появилась возможность переключиться на&nbsp;HQ, этот порядок уже не&nbsp;работает, потому что на&nbsp;месте кнопки выключающей звук успевает появиться кнопка HQ, на&nbsp;которую и&nbsp;приходится второй клик.</p>
<p>
    <img src="http://designformasters.info/stuff/5-usability-mistakes/youtube-hd-button.png"></p>
<p>Решение: избегайте неожиданных перемещений элементов интерфейса и&nbsp;появления новых элементов на&nbsp;месте старых.</p>
<h2>3. Не&nbsp;исчезающие пояснения в&nbsp;полях</h2>
<p>Когда место для формы ограничено, метки к&nbsp;полям выводят внутри самих полей, при этом важно не&nbsp;забыть очистить поле при получении им&nbsp;фокуса, иначе эту работу придется делать пользователю. Реализовать это не&nbsp;сложно, но&nbsp;часто оказывается, что в&nbsp;скрипте ошибка, а&nbsp;разработчик даже не&nbsp;пытался проверить его работу.</p>
<p>
    <img src="http://designformasters.info/stuff/5-usability-mistakes/text-1.png"><br>
    <a href="http://onegadget.ru/">http://onegadget.ru/</a></p>
<p>
    <img src="http://designformasters.info/stuff/5-usability-mistakes/text-2.png"><br>
    <a href="http://zt9.ru/">http://zt9.ru/</a></p>
<p>
    <img src="http://designformasters.info/stuff/5-usability-mistakes/text-3.png"><br>
    <a href="http://coolidea.ru/">http://coolidea.ru/</a></p>
<p>Решение: чтобы полностью исключить такую проблему, никогда не&nbsp;вводите текст приглашения непосредственно в&nbsp;поле, используйте технику описанную в&nbsp;статье о&nbsp;<a href="http://designformasters.info/posts/compact-accessible-forms/">компактных формах</a>.</p>
<h2>4. Загрузка программ с&nbsp;сайта Adobe</h2>
<p>Решение несуществующих проблем создает реальные проблемы, хороший пример, менеджер загрузки на&nbsp;сайте Adobe, создает сразу несколько проблем: непривычность такого способа загрузки, дополнительные вопросы о&nbsp;том куда сохранять загружаемый файл (менеджер загрузок и&nbsp;браузер наверняка знают куда пользователь предпочитает сохранять файлы), недоработанность (так и&nbsp;не&nbsp;справился с&nbsp;загрузкой 1Гб с&nbsp;двух попыток).</p>
<p>
    <img src="http://designformasters.info/stuff/5-usability-mistakes/adobe-downloads.png"></p>
<p>В большинстве браузеров есть встроенный менеджер загрузок, у&nbsp;многих пользователей установлен отдельный менеджер загрузок, который хорошо знает свое дело, даже если такового нет проще его поставить чем бороться с&nbsp;сомнительной поделкой, как минимум пользователь должен иметь возможность выполнить действие стандартными средствами.</p>
<p>Решение: не&nbsp;решайте проблемы которых нет, конечно, это касается не&nbsp;только загрузки файлов, но&nbsp;и&nbsp;таких популярных в&nbsp;прошлом элементов как кнопка «Добавить в&nbsp;избранное», «Сделать стартовой», переопределения горячих клавиш, например, Ctrl+Home для перехода на&nbsp;главную (проблема в&nbsp;том, что многие привыкли использовать это сочетание чтобы перематывать документ к&nbsp;началу).</p>
<h2>5. Ввод даты рождения в&nbsp;LiveJournal</h2>
<p>Поле ввода даты рождения, в&nbsp;лучшем случае не&nbsp;очень привычно для русского человека, а&nbsp;в&nbsp;худшем случае заставляет призадуматься, вариантов тут не&nbsp;так уж&nbsp;много и&nbsp;правильное решение быстро найдут даже те&nbsp;кто совсем не&nbsp;знаком с&nbsp;таким форматом даты, тем не&nbsp;менее, непривычных пользователю форматов данных следует избегать.</p>
<p>
    <img src="http://designformasters.info/stuff/5-usability-mistakes/livejournal-signup.png"></p>
<p>Решение: при локализации приложений нужно помнить не&nbsp;только о&nbsp;переводе&nbsp;текста, но&nbsp;и&nbsp;о&nbsp;локальных форматах.</p><h2>Похожие статьи</h2><ul><li><a href="http://designformasters.info/posts/usability-rules-psychology-terms">Юзабилити: Правила, психология, термины</a></li></ul>
<p><a href="http://feedads.g.doubleclick.net/~a/wDuT1_JCWNc14kjiiIqvLZqiYYc/0/da"><img src="http://feedads.g.doubleclick.net/~a/wDuT1_JCWNc14kjiiIqvLZqiYYc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/wDuT1_JCWNc14kjiiIqvLZqiYYc/1/da"><img src="http://feedads.g.doubleclick.net/~a/wDuT1_JCWNc14kjiiIqvLZqiYYc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=FNwuTa-c-1M:Lv_pJnZ7gFA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=FNwuTa-c-1M:Lv_pJnZ7gFA:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/5-usability-mistakes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Разгоняем jQuery. Часть 1</title>
		<link>http://designformasters.info/posts/speed-up-jquery/</link>
		<comments>http://designformasters.info/posts/speed-up-jquery/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 10:47:32 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Кодинг]]></category>

		<category><![CDATA[Статьи]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=587</guid>
		<description><![CDATA[
    Статей
    по&#160;ускорению jQuery достаточно много, но&#160;обычно они не&#160;отличаются наглядностью и&#160;подробностью, поэтому я&#160;решил провести несколько тестов и&#160;выделить, те&#160;советы по&#160;ускорению jQuery, которые действительно работают.

Кеширование
Кеширование результатов выборки заложено в&#160;типовую конструкцию применения jQuery.
Цепочка вызовов:
$('#id-of-element').attr('data-value', 'data-for-element')
                  [...]]]></description>
			<content:encoded><![CDATA[<p>
    <img width="285" height="84" alt="jQuery" style="float: right; margin: 0 0 1em 1em;" src="http://designformasters.info/stuff/speed-up-jquery/logo-jquery.png" />Статей
    по&nbsp;ускорению jQuery достаточно много, но&nbsp;обычно они не&nbsp;отличаются наглядностью и&nbsp;подробностью, поэтому я&nbsp;решил провести несколько тестов и&nbsp;выделить, те&nbsp;советы по&nbsp;ускорению jQuery, которые действительно работают.</p>
<span id="more-587"></span>
<h2>Кеширование</h2>
<p>Кеширование результатов выборки заложено в&nbsp;типовую конструкцию применения jQuery.</p>
<p>Цепочка вызовов:</p>
<pre class="prettyprint"><code>$('#id-of-element').attr('data-value', 'data-for-element')
                   .css('color', 'red')
                   .html('&lt;p&gt;html code&lt;/p&gt;');</code></pre>
<p>эквивалентна, следующему коду:</p>
<pre class="prettyprint"><code>var element = $('#id-of-element');
element.attr('data-value', 'data-for-element');
element.css('color', 'red');
element.html('&lt;p&gt;html code&lt;/p&gt;');</code></pre>
<p>Уже здесь на&nbsp;одну выборку приходится несколько вызовов методов, и&nbsp;нам остается только
    расширить эту практику дальше одной цепочки, например, для выноса выборки за&nbsp;пределы
    цикла:</p>
<pre class="prettyprint"><code>var el = $('#el-999-9');

for (var i = 0; i < runCount; i++) {
    el.addClass('el-class')
      .css('background-color', 'blue')
      .html(i);
}</code></pre>
<p>или обработчика события:</p>
<pre class="prettyprint"><code>var el = $('#el-999-9');

$('#button').click(function(){
    el.empty()
      .html('html code');
});</code></pre>
<p>Кеширование эффективно даже на&nbsp;примере самого быстрого селектора #id:</p>
<p>
    <img width="566" height="353" alt="" src="http://designformasters.info/stuff/speed-up-jquery/cache-id-selector.png" /></p>
<p>Код тестов:</p>
<pre class="prettyprint"><code>var runCount = 100;

function testIdLoopNoCache()
{
    for (var i = 0; i < runCount; i++)
    {
        $('#el-999-9').html(i);
    }
}

function testIdLoopCache()
{
    var el = $('#el-999-9');

    for (var i = 0; i < runCount; i++)
    {
        el.html(i);
    }
}</code></pre>
<p>Хороший результат, но&nbsp;давайте проверим селектор посложнее, например, .class1&nbsp;.class2:</p>
<p>
    <img width="566" height="353" alt="" src="http://designformasters.info/stuff/speed-up-jquery/cache-class-class-selector.png" /></p>
<p>Разница в&nbsp;производительности браузеров настолько велика, что трудно показать их&nbsp;результаты
    на&nbsp;одном графике, поэтому выделим еще один график для самых быстрых (по крайней
    мере в&nbsp;этом тесте):</p>
<p>
    <img width="566" height="282" alt="" src="http://designformasters.info/stuff/speed-up-jquery/cache-class-class-selector-modern.png" /></p>
<p>Очевидно, что чем медлительней селектор тем эффективнее кеширование, особенно актуально кеширование выборок в&nbsp;браузерах, не&nbsp;поддерживающих querySelectorAll.</p>
<h2>Минимизируйте работу с&nbsp;DOM</h2>
<p>Работа с&nbsp;DOM по&nbsp;возможности должна сводиться к&nbsp;минимуму, например, при добавлении
    нескольких элементов нужно сначала объединить их&nbsp;код, а&nbsp;потом вставить одним вызовом
    html.</p>
<p>Начнем с&nbsp;тестов:</p>
<p>
    <img width="566" height="701" alt="" src="http://designformasters.info/stuff/speed-up-jquery/append.png" /></p>
<p>Код тестов:</p>
<pre class="prettyprint"><code>function testAppendLi()
{
    $('#cnt').append('&lt;ol id="list"&gt;&lt;/ol&gt;');

    for (var i = 0; i &lt; runCount; i++)
    {
        $('#list').append('&lt;li&gt;' + i + '&lt;/li&gt;');
    }
}

function testAppendLiCacheSelection()
{
    $('#cnt').append('&lt;ol id="list"&gt;&lt;/ol&gt;');
    var list = $('#list');

    for (var i = 0; i &lt; runCount; i++)
    {
        list.append('&lt;li&gt;' + i + '&lt;/li&gt;');
    }
}

function testAppendAllLi()
{
    $('#cnt').append('&lt;ol id="list"&gt;&lt;/ol&gt;');

    var list = '';
    for (var i = 0; i &lt; runCount; i++)
    {
        list += '&lt;li&gt;' + i + '&lt;/li&gt;';
    }
    $('#list').append(list);
}

function testAppendAllUlLi()
{
    var list = '';
    for (var i = 0; i &lt; runCount; i++)
    {
        list += '&lt;li&gt;' + i + '&lt;/li&gt;';
    }
    $('#cnt').append('&lt;ol id="list"&gt;' + list + '&lt;/ol&gt;');
}</code></pre>
<p>Тест testAppendLiCacheSelection попал на&nbsp;этот график с&nbsp;той лишь целью, чтобы показать
    эффект от&nbsp;кеширования (пусть даже очень быстрого селектора #id).</p>
<h3>Собирайте в&nbsp;один элемент</h3>
<p>Чтобы ускорить вставку большого количества элементов, их&nbsp;нужно обернуть в&nbsp;один элемент.</p>
<p>Обратите внимание, что тест testAppendAllUlLi работает быстрее, чем тест на&nbsp;чистом DOM и&nbsp;практически так же&nbsp;быстро как innerHTML, то&nbsp;же&nbsp;самое касается методов
    html, after и&nbsp;других методов с&nbsp;таким функционалом.</p>
<p>Значительное ускорение при обертывании кода в&nbsp;один элемент связано со&nbsp;способом которым
    jQuery внедряет html код в&nbsp;документ. После предварительной обработки кода, создается
    элемент div и&nbsp;код присваивается его свойству innerHTML, потом поэлементно клонируется
    в&nbsp;документ, обертывание в&nbsp;кода в&nbsp;один элемент позволяет минимизировать клонирования.</p>
<h2>Функция $.each</h2>
<p>Не используйте $.each там где важна скорость работы с&nbsp;массивом. $.each&nbsp; — это
    вызов функции в&nbsp;контексте объекта и&nbsp;последующая проверка необходимости досрочного
    выхода из&nbsp;перебора (зависит от&nbsp;возвращаемого функцией значения), очевидно, что простой
    for без лишних вызвов функций и&nbsp;проверок значительно быстрее $.each. Результаты
    тестов это подтверждают:</p>
<p>
    <img width="566" height="574" alt="" src="http://designformasters.info/stuff/speed-up-jquery/each-array.png"></p>
<p>Разница в&nbsp;производительности $.each и&nbsp;for in применительно к&nbsp;объектам не&nbsp;столь значительна,
    вероятно это связано с&nbsp;тем, что for in не&nbsp;столь быстр как for и&nbsp;дополнительные расходы
    на&nbsp;вызов функции и&nbsp;if на&nbsp;его фоне не&nbsp;столь заметны.</p>
<p>
    <img width="566" height="394" alt="" src="http://designformasters.info/stuff/speed-up-jquery/each-object.png"></p>
<h3>Не используйте for in для массивов</h3>
<p>Ну и&nbsp;еще раз подтверждение известного факта о&nbsp;медлительности цикла for in в&nbsp;применении
    к&nbsp;массивам:</p>
<p>
    <img width="566" height="353" alt="" src="http://designformasters.info/stuff/speed-up-jquery/for-vs-for-in.png" /></p>
<p>&nbsp;</p>
<h2>Конкатенация строк</h2>
<p>Конкатенация не&nbsp;относится к&nbsp;jQuery, но&nbsp;это одна из&nbsp;часто используемых операций, причем
    с&nbsp;подводным камнем, она фантастически медленно выполняется в&nbsp;IE6 и&nbsp;IE7.</p>
<p>
    <img width="566" height="353" alt="" src="http://designformasters.info/stuff/speed-up-jquery/concatenation.png"></p>
<p>Если быстрая конкатенация нужна здесь и&nbsp;сейчас, можно использовать Array.push(string)
    и&nbsp;Array.join(''), но&nbsp;использовать их&nbsp;повсеместно не&nbsp;рекомендуется, так как конкатенация
    хорошо поддается оптимизации и&nbsp;быстрее join почти во&nbsp;всех современных браузерах
    (а если не&nbsp;быстрее, значит разработчики использовали не&nbsp;все возможности для ее&nbsp;оптимизации
    и&nbsp;она может ускориться в&nbsp;будущем).</p>
<p>Тот же&nbsp;самый график без IE6 и&nbsp;IE7:</p>
<p>
    <img width="566" height="306" alt="" src="http://designformasters.info/stuff/speed-up-jquery/modern-concatenation.png" /></p>
<p>Код тестов:</p>
<pre class="prettyprint"><code>function testConcatenationOperator()
{
    var str = '';
    
    for (var i = 0; i < count; i++)
    {
        str += words[i];
    }
    
    // для оптимизации браузер может не собирать строку
    // пока она не потребуется в целом виде
    var forceConcat = str.toString();
}

function testJoin()
{
    var str = '';
    var tmpArray = [];
    
    for (var i = 0; i < count; i++)
    {
        tmpArray.push(words[i]);
    }
    
    var str = tmpArray.join('');
}</code></pre>
<p>Проблема конкатенации в&nbsp;IE6/7 в&nbsp;том, что она выполняется тривиально, для каждых двух
    операндов создается буфер в&nbsp;который они последовательно копируются, рассмотрим пример:</p>
<pre class="prettyprint"><code>var s = 'str1' + 'str12' + 'str123'</code></pre>
<p>В IE6/7 при выполнении первой конкатенации выделяется память под временную строку
    и&nbsp;в&nbsp;нее копируются строки 'str1' и&nbsp;'str12', при выполнении второй конкатенации выделяется
    память под еще одну строку и&nbsp;в&nbsp;нее копируется строки 'str1str12' и&nbsp;'str123', и&nbsp;т.д.
    При каждой конкатенации происходит выделение памяти и&nbsp;копирование строк.</p>
<p>В эффективной реализации при выполнении первой конкатенация создается вспомогательный
    объект, содержащий ссылки на&nbsp;строки 'str1' и&nbsp;'str12', при выполнении второй конкатенации
    добавляется ссылка на&nbsp;'str123' и&nbsp;только когда потребуется значение строки, выделяется
    память в&nbsp;которую копируются строки 'str1', 'str12', 'str123'.</p>
<p>Подробнее об&nbsp;этом можно почитать в&nbsp;статьях:<br>
    <a href="http://blogs.msdn.com/jscript/archive/2007/10/17/performance-issues-with-string-concatenation-in-jscript.aspx">
        Performance issues with "String Concatenation" in JScript</a><br>
    <a href="http://blogs.msdn.com/jscript/archive/2008/03/19/insight-into-string-concatenation-in-jscript.aspx">
        Insight into String Concatenation in JScript</a></p>
<h2>Ускорение доступа к&nbsp;переменным</h2>
<p>Еще один прием которому можно научиться у&nbsp;jQuery это ускорение глобальных переменных
    созданием соответствующей локальной.</p>
<p>Метод прост, создаются локальная переменная, равная соответствующей глобальной, а&nbsp;доступ к&nbsp;локальным переменным во&nbsp;многих браузерах быстрее доступа к&nbsp;глобальным переменным,
    иногда более чем в&nbsp;10 раз, в&nbsp;худшем случае разницы нет.</p>
<p>
    <img width="566" height="353" alt="" src="http://designformasters.info/stuff/speed-up-jquery/local-vs-global.png"></p>
<p>Код теста:</p>
<pre class="prettyprint"><code>var runCount = 1000000;

var globalVariable = 1;

function testGlobalVariable()
{            
    for (var i = 0; i < runCount; i++)
    {
        globalVariable++;
    }
}

function testLocalVariable()
{
    var localVariable = 1;

    for (var i = 0; i < runCount; i++)
    {
        localVariable++;
    }
}</code></pre>
<p>Пример использования оптимизации undefined в&nbsp;приближенных к&nbsp;реальным условиях:</p>
<pre class="prettyprint"><code>function testArrayLocalUndefined()
{
    var array = globalArray; //массив в котором каждый 5-й элемент определен
    var summ = 0;
    
    var undefined; //ускоритель
    
    for (var i = 0, l = array.length; i < l; i++) {
        if (array[i] !== undefined) {
            summ += array[i];
        }
    }
}</code></pre>
<p>
    <img width="566" height="353" alt="" src="http://designformasters.info/stuff/speed-up-jquery/local-undefined.png"></p>
<p>jQuery использует эту технику для ускорения window и&nbsp;undefined.</p>
<h2>Статьи</h2>
<ul>
    <li><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx">
        Improve your jQuery - 25 excellent tips</a></li>
    <li><a href="http://www.artzstudio.com/2009/04/jquery-performance-rules/">jQuery Performance
        Rules</a></li>
    <li><a href="http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance/">
        10 Ways to Instantly Increase Your jQuery Performance</a></li>
    <li><a href="http://mabp.kiev.ua/2009/02/07/accelerates-selectors-in-jquery/">Ускоряем
        селекторы в&nbsp;jQuery</a></li>
    <li><a href="http://habrahabr.ru/blogs/jquery/52201/">Закрепляем jQuery — 25 отличных
        советов</a></li>
    <li><a href="http://www.slideshare.net/jeresig/jquery-internals-cool-stuff-presentation">
        jQuery Internals</a></li>
</ul>
<p><a href="http://feedads.g.doubleclick.net/~a/IMoJy9Wbfff1yIyWJZG1HDi5n8g/0/da"><img src="http://feedads.g.doubleclick.net/~a/IMoJy9Wbfff1yIyWJZG1HDi5n8g/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/IMoJy9Wbfff1yIyWJZG1HDi5n8g/1/da"><img src="http://feedads.g.doubleclick.net/~a/IMoJy9Wbfff1yIyWJZG1HDi5n8g/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=SDzWJIWSqPw:BdM54ty7Slc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=SDzWJIWSqPw:BdM54ty7Slc:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/speed-up-jquery/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Обзор блога Алика Кирилловича</title>
		<link>http://designformasters.info/posts/alik-blog/</link>
		<comments>http://designformasters.info/posts/alik-blog/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 06:19:03 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Обзоры]]></category>

		<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=515</guid>
		<description><![CDATA[Хочу представить вашему вниманию блог Алика Кирилловича. Блог посвящен разработке веб-приложений и&#160;выделяется качественными материалами, к&#160;сожалению, обновляется довольно редко.



Работает блог на&#160;собственном движке AlikPress, у&#160;которого есть две особенности: во-первых он&#160;написан на&#160;JavaScript (серверный JavaScript), а&#160;во-вторых генерирует хорошо отформатированный и&#160;полностью соответствующий стандарту XHTML Strict код, который приятно читать.

Достаточно активно используются достижения Semantic Web: есть RDF-описание в&#160;FOAF формате, все статьи [...]]]></description>
			<content:encoded><![CDATA[<p>Хочу представить вашему вниманию <a href="http://www.alik.su/">блог Алика Кирилловича</a>. Блог посвящен разработке веб-приложений и&nbsp;выделяется качественными материалами, к&nbsp;сожалению, обновляется довольно редко.

<span id="more-515"></span>

<p>Работает блог на&nbsp;собственном движке AlikPress, у&nbsp;которого есть две особенности: во-первых он&nbsp;написан на&nbsp;JavaScript (серверный JavaScript), а&nbsp;во-вторых генерирует хорошо отформатированный и&nbsp;полностью соответствующий стандарту XHTML Strict код, который приятно читать.

<p>Достаточно активно используются достижения Semantic Web: есть <a href="http://en.wikipedia.org/wiki/Resource_Description_Framework">RDF</a>-описание в&nbsp;<a href="http://en.wikipedia.org/wiki/FOAF">FOAF</a> формате, все статьи снабжены метаданными <a href="http://en.wikipedia.org/wiki/Dublin_Core">Дублинского ядра</a>, не&nbsp;забыты и&nbsp;микроформаты.

<p>Автор внимательно относится к&nbsp;оформлению материалов, не&nbsp;жалеет времени на&nbsp;создание иллюстраций и&nbsp;качественное оформление статей, мне кажется, в&nbsp;некоторых статьях даже слишком. В&nbsp;оформление сайта несколько напрягают неравномерные разрывы в&nbsp;тексте из-за justify, но&nbsp;Алик обещал решить эту проблему.

<p>Вот несколько примеров статей из&nbsp;блога Алика:

<ul>
<li><a href="http://www.alik.su/articles/the-decline-of-the-web/">Закат веба?</a><br>
Отличная статья о&nbsp;настоящем и&nbsp;будущем веб, проблемах развития и&nbsp;причинах их&nbsp;возникновения, а&nbsp;также о&nbsp;новой надежде, на&nbsp;прорыв в&nbsp;технологиях создания веб-приложений. Статья написана год назад и&nbsp;сегодня можно уверенно сказать, что предсказанное сбывается. Появляются первые крупные проекты, использующие HTML5, достаточно сказать, то&nbsp;Google использует его в&nbsp;новой мобильной версии gMail и&nbsp;многообещающем проекте Google Wave.

<li><a href="http://www.alik.su/articles/10-ugly-programming-techniques/">Десять приёмов программирования, разрушающих красоту кода</a><br>
Хорошая статья на&nbsp;актуальную тему красоты кода, будет полезна новичкам и&nbsp;послужит напоминанием профессионалам. Рассмотрены такие темы как объявление переменных, возврат результата функции через параметр, хранение размера массива в&nbsp;отдельной переменной, использование рекурсии, именованные параметры функций и&nbsp;некоторые другие.<br><br>
Статья породила много споров, но&nbsp;я&nbsp;хочу напомнить, что у&nbsp;любого правила есть свои границы применимости, и&nbsp;из&nbsp;их&nbsp;наличия отнюдь не&nbsp;следует ошибочность правила.

<li><a href="http://www.alik.su/articles/perfect-ajax/">Совершенный Ajax</a><br>
Новый подход к&nbsp;построению веб-приложений, при котором веб-сервер взаимодействует с&nbsp;внешним миром только посредством веб-служб, а&nbsp;клиентский интерфейс реализуется на&nbsp;основе клиентских HTML, CSS, JavaScript.

<li><a href="http://www.alik.su/articles/xml-and-yaml/">Сравнение языков в&nbsp;стиле XML и&nbsp;языков в&nbsp;стиле YAML</a><br>
Кроме непосредственно сравнения XML и&nbsp;YAML, статья наводит на&nbsp;мысль о&nbsp;том, что нужно шире использовать Wiki разметку которая удобнее, чем HTML и&nbsp;BBCode, для конечного пользователя.<br>
Например
<pre class="pretty"><code>* Пункт 1
* Пункт 2
* Пункт 3</code></pre>
vs
<pre class="prettyprint"><code>&lt;ul&gt;
  &lt;li&gt;Пункт 1&lt;/li&gt;
  &lt;li&gt;Пункт 2&lt;/li&gt;
  &lt;li&gt;Пункт 3&lt;/li&gt;
&lt;/ul&gt;</code></pre>
или
<pre class="pretty"><code>[http://designformasters.info/ Design For Masters]</code></pre>
vs
<pre class="prettyprint"><code>&lt;a href="http://designformasters.info/"&gt;Design For Masters&lt;/a&gt;</code></pre>

</ul>

<p>Есть и&nbsp;интересные планы на&nbsp;будущие публикации:

<ul>
<li>Мир JavaScript за&nbsp;пределами браузера, будет одной из&nbsp;ключевых тем блога.<br><br>
Алик считает, что JavaScript — удивительно мощный, гибкий и&nbsp;красивый язык, превосходящий в&nbsp;ряде случаев по&nbsp;гибкости и&nbsp;функциональным возможностям таких монстров, как Java или C#. Однако, многие особенности JavaScript, придающие ему мощь и&nbsp;гибкость такие как: ООП на&nbsp;основе прототипов, объекты-как-хеши, функциональное программирование или замыкания, оказались недопоняты разработчиками, привыкшими к&nbsp;классическим языкам, вроде C++, Java, Delphi или VB.<br><br>
Кроме привычного многим использования этого языка в&nbsp;веб, будут рассмотрены менее распространенные применения, такие как создание десктопных приложений (HTA, Air, XUL, Windows Sidebar gadgets и&nbsp;т.п.), сервер-сайд JS (ASP, Apache + mod_js и&nbsp;т.п.), скриптование (Adobe Creative Suite, PDF, OpenOffice, HD DVD), а&nbsp;также основные JS-движки и&nbsp;компиляторы (Mozilla Rhino, Google V8, MS ActiveScripting и&nbsp;др).

<li>Вторая часть статьи «Совершенный Ajax» посвященная деталям реализации.<li>HTML — самый недооценённый язык построения интерфейсов в&nbsp;мире.<li>Прототипно-ориентированная ORM — система объектно-реляционных отображений для прототипно-ориентированных (неклассовых) языков программирования (например, JavaScript).

<li>Три уровня семантики: семантическая вёрстка &#8594; микроформаты &#8594; Semantic Web.

<li>Механизмы функционирования сообществ: люди (Википедия) vs софт (Хабр).
</ul>

<p style="text-align: center;margin-bottom:3em;">Подписывайтесь на&nbsp;RSS:<br>
<img style="margin-right:4px;vertical-align:middle;" src="http://designformasters.info/wp-content/themes/dfm/images/feed-icon-16x16.gif" alt="RSS"><a href="http://feeds.feedburner.com/alik-kirillovich">Блог Алика Кирилловича</a>
<p><a href="http://feedads.g.doubleclick.net/~a/gFbYgSxgSYOREo6tmKT18TrmCjc/0/da"><img src="http://feedads.g.doubleclick.net/~a/gFbYgSxgSYOREo6tmKT18TrmCjc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/gFbYgSxgSYOREo6tmKT18TrmCjc/1/da"><img src="http://feedads.g.doubleclick.net/~a/gFbYgSxgSYOREo6tmKT18TrmCjc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=_4uI4ZMeGnQ:42guFK8aMD8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=_4uI4ZMeGnQ:42guFK8aMD8:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/alik-blog/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Подготовка ссылок к печати 2</title>
		<link>http://designformasters.info/posts/improving-link-display-for-print-2/</link>
		<comments>http://designformasters.info/posts/improving-link-display-for-print-2/#comments</comments>
		<pubDate>Tue, 26 May 2009 07:04:29 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Design For Masters]]></category>

		<category><![CDATA[Кодинг]]></category>

		<category><![CDATA[Статьи]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=478</guid>
		<description><![CDATA[
К&#160;сожалению, далеко не&#160;на&#160;все сайты готовы к&#160;печати, во&#160;многих случаях вместе с&#160;нужной информацией печатается 5 листов меню и&#160;баннеров, а&#160;если особо повезет можно получить почти настоящий пазл. Конечно, печать не&#160;самая востребованная функция, но&#160;подготовка страницы к&#160;печати и&#160;не&#160;требует больших затрат времени и&#160;труда.

Приятным дополнением к&#160;печатной версии страницы могут стать сноски для ссылок, предложенные Аароном Густафносоном.
Примерно так выглядит распечатанная страница DFM.


Скрипт подготовки [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:right;margin:0 0 1em 1em;" src="http://designformasters.info/stuff/improving-link-display-for-print-2/c110-small.jpg" width="125" height="101">
К&nbsp;сожалению, далеко не&nbsp;на&nbsp;все сайты готовы к&nbsp;печати, во&nbsp;многих случаях вместе с&nbsp;нужной информацией печатается 5 листов меню и&nbsp;баннеров, а&nbsp;если особо повезет можно получить почти настоящий пазл. Конечно, печать не&nbsp;самая востребованная функция, но&nbsp;<a href="http://designformasters.info/posts/print-styles/">подготовка страницы к&nbsp;печати</a> и&nbsp;не&nbsp;требует больших затрат времени и&nbsp;труда.</p>
<span id="more-478"></span>
<p>Приятным дополнением к&nbsp;печатной версии страницы могут стать <a href="http://designformasters.info/posts/improving-link-display-for-print/">сноски для ссылок</a>, предложенные Аароном Густафносоном.</p>
<p>Примерно так выглядит распечатанная страница DFM.</p>
<p style="text-align:center;"><img src="http://designformasters.info/stuff/improving-link-display-for-print-2/dfm-print1.png" width="516" height="734"></p>
<p style="text-align:center;"><img src="http://designformasters.info/stuff/improving-link-display-for-print-2/dfm-print2.png" width="516" height="734"></p>
<p>Скрипт подготовки ссылок к&nbsp;печати, который предложил Аарон, прекрасно работает, но&nbsp;<a href="http://designformasters.info/stuff/improving-link-display-for-print-2/printLinksOld.js">три экрана кода</a> только для того, чтобы сделать концевые сноски ссылок это слишком. Я&nbsp;уверен, что многие сразу же&nbsp;откажутся от&nbsp;самой идеи сносок, и&nbsp;в&nbsp;чем-то будут правы — печатаются страницы редко, а&nbsp;тут еще и&nbsp;скрипт огромный.</p>
<p>Чтобы отбросить хотя бы&nbsp;эту часть сомнений, я&nbsp;переписал скрипт под jQuery с&nbsp;небольшим сокращением совсем уж&nbsp;редко используемого функционала, получилось на&nbsp;экран <a href="http://designformasters.info/stuff/improving-link-display-for-print-2/printLinks.js">с комментариями</a>, и&nbsp;450 символов <a href="http://designformasters.info/stuff/improving-link-display-for-print-2/printLinksMini.js">в сжатом виде</a>.</p>
<pre class="prettyprint"><code>/**
 * Создает концевые сноски для ссылок.
 * @param container  селектор элемента содержащего ссылки
 * @param target     селектор элемента в который нужно добавить список ссылок
 * @param title      заголовок списка ссылок
 * @param printClass класс элементов добавляемых функцией
 */
function footnoteLinks(container, target, title, printClass) {
    if(!printClass)
        printClass = 'printOnly';

    var linksArray = [];  // ссылки по порядку
    var linksHash = {};   // индексы по href, для поиска дубликатов
    
    // перебор всех ссылок с атрибутом href
    // в пределах контейнера
    $(container + ' a[href]').each(function(elementIndex) {
        var index = elementIndex;
        
        if(!linksHash[this.href]) {
            // ссылка встречается впервые
            linksHash[this.href] = index;
            linksArray.push(this);
        } else {
            // такая ссылка уже была и ей присвоен индекс
            index = linksHash[this.href];
        }
        
        // добавляем номер сноски после ссылки
        $(this).after('&lt;sup class="' + printClass + '"&gt;' + (index + 1) + '&lt;/sup&gt;');
    });

    // создание списка с концевыми сносками, если ссылки былы
    var linksFound = linksArray.length;
    if(linksFound &gt; 0) {
        var links = '';

        for(var i = 0; i &lt; linksFound; i++)
            links += '&lt;li&gt;' + linksArray[i].href + '&lt;/li&gt;';

        links = '&lt;h2 class="' + printClass + '"&gt;' + title + '&lt;/h2&gt;' +
                '&lt;ol class="' + printClass + '"&gt;' + links + '&lt;ol&gt;';

        $(target).append(links);
        
        // задаем класс для элемента html
        // может быть полезно при написании CSS для печати
        $(document.documentElement).addClass('print-footnote-links');
    }
}

// пример использования
$(document).ready(function() {
    footnoteLinks('.single .post-content', '.post-content', 'Ссылки');
});</code></pre>

<p><a href="http://designformasters.info/stuff/improving-link-display-for-print-2/example.html">Пример страницы</a> (сноски не&nbsp;скрыты)</p>

<p>Теперь скроем сноски. Если стили для всех устройств в&nbsp;одном файле то&nbsp;можно использовать следующее правило:</p>
<pre class="prettyprint"><code>// лишние устройства можно удалить
@media aural, braille, embossed, handheld, projection, tty, screen, tv {
    .printOnly { display: none; }
}</code></pre>
<p>Если для каждого устройства подключается свой файл стилей, то&nbsp;все еще проще, добавьте <code>.printOnly { display: none; }</code> во&nbsp;все файлы кроме файла стилей для печати.</p>
<p>Чтобы посмотреть еще одни пример используйте «Предварительный просмотр...»</p><h2>Похожие статьи</h2><ul><li><a href="http://designformasters.info/posts/improving-link-display-for-print">Подготовка ссылок к печати</a></li><li><a href="http://designformasters.info/posts/print-styles">15 минут на подготовку к печати</a></li></ul>
<p><a href="http://feedads.g.doubleclick.net/~a/hlHA8U-Kv5pCuBXKJgyRYPI97YY/0/da"><img src="http://feedads.g.doubleclick.net/~a/hlHA8U-Kv5pCuBXKJgyRYPI97YY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/hlHA8U-Kv5pCuBXKJgyRYPI97YY/1/da"><img src="http://feedads.g.doubleclick.net/~a/hlHA8U-Kv5pCuBXKJgyRYPI97YY/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=vckue57e2-I:eKyonWWRgTo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=vckue57e2-I:eKyonWWRgTo:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/improving-link-display-for-print-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Пользовательские поля в WordPress</title>
		<link>http://designformasters.info/posts/wordpress-custom-fields/</link>
		<comments>http://designformasters.info/posts/wordpress-custom-fields/#comments</comments>
		<pubDate>Sun, 17 May 2009 20:04:45 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Design For Masters]]></category>

		<category><![CDATA[Кодинг]]></category>

		<category><![CDATA[Статьи]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=458</guid>
		<description><![CDATA[В&nbsp;продолжение статьи Custom Fields Hacks For WordPress хочу поделиться своим опытом использования пользовательских полей поста.

Автор и&#160;оригинал поста
Не&nbsp;секрет, что на&#160;сайте в&#160;основном опубликованы переводы статей, чтобы удобно 
    указать автора и&#160;дать ссылку на&#160;оригинал я&#160;использую дополнительные поля author 
    и&#160;original.

Работа с&#160;этими полями выделена в&#160;плагин dfmAuthorOriginal.php
Автора подменяем с&#160;помощью фильтра:
add_filter('the_author', 'dfm_author_filter');

function dfm_author_filter($author) [...]]]></description>
			<content:encoded><![CDATA[<p>В продолжение статьи <a href="http://www.smashingmagazine.com/2009/05/13/10-custom-fields-hacks-for-wordpress/">Custom Fields Hacks For WordPress</a> хочу поделиться своим опытом использования пользовательских полей поста.</p>
<span id="more-458"></span>
<h2>Автор и&nbsp;оригинал поста</h2>
<p>Не секрет, что на&nbsp;сайте в&nbsp;основном опубликованы переводы статей, чтобы удобно 
    указать автора и&nbsp;дать ссылку на&nbsp;оригинал я&nbsp;использую дополнительные поля <code>author</code> 
    и&nbsp;<code>original</code>.</p>
<p><img src="http://designformasters.info/stuff/wordpress-custom-fields/custom-fields.png" width="476" height="403" alt="Пользовательские поля"></p>
<p>Работа с&nbsp;этими полями выделена в&nbsp;плагин dfmAuthorOriginal.php</p>
<p>Автора подменяем с&nbsp;помощью фильтра:</p>
<pre class="prettyprint"><code>add_filter('the_author', 'dfm_author_filter');

function dfm_author_filter($author) {
    global $post;

    $custom_author = get_post_meta($post-&gt;ID, 'author', true);
    if($custom_author) {
        if(is_feed()) {
            $custom_author = strip_tags($custom_author);
        }
        return $custom_author;
    } else {
        return $author;
    }
}</code></pre>
<p>Для оригинала вводим функцию <code>dfm_original</code>:</p>
<pre class="prettyprint"><code>function dfm_original($before = '&lt;p&gt;', $after = '&lt;/p&gt;') {
    global $post;

    $original = get_post_meta($post->ID, 'original', true);
    if($original) {
        echo $before . $original . $after;
    }
}</code></pre>
<p>и вставляем ее&nbsp;в&nbsp;нужном месте шаблона:</p>
<pre class="prettyprint"><code>&lt;?php if(function_exists('dfm_original'))
    dfm_original('&lt;p&gt;Оригинал: ', '&lt;/p&gt;'); ?&gt;</code></pre>


<h2>Краткие заголовки постов</h2>
<p>Для списка «Последние статьи» в&nbsp;сайдбаре используются краткие заголовки из&nbsp;поля 
    <code>short_title</code>. 
    В&nbsp;общем случае код должен выглядеть так:</p>

<pre class="prettyprint"><code>function dfm_recent_posts($before='&lt;li&gt;', $after='&lt;/li&gt;')
{
    $posts = get_posts(array('numberposts' =&gt; 10));
    echo dfm_posts_list($posts, $before, $after);
}

function dfm_posts_list($posts, $before='&lt;li&gt;', $after='&lt;/li&gt;')
{
    $result = array();
    
    foreach($posts as $post) {
        $permalink = get_permalink($post);
        $title = get_post_meta($post-&gt;ID, 'short_title', true);
        $title = empty($title) ? $post-&gt;post_title : $title;
        
        $result[] = sprintf('%s&lt;a href="%s" rel="bookmark"&gt;%s&lt;/a&gt;%s',
                            $before, $permalink, $title, $after);
    }

    return implode("\n", $result);
}</code></pre>
<p>К сожалению, <code>get_posts</code> это 4 запроса к&nbsp;БД&nbsp;и&nbsp;если таким способом выводить блоки 
    «Последние статьи», «Лучшие статьи» и&nbsp;«Похожие статьи» то&nbsp;количество запросов на&nbsp;сборку 
    страницы будет более чем удвоено (22 вместо 10), благодаря чему хостер отключит 
    сайт как раз в&nbsp;тот момент, когда на&nbsp;него появиться ссылка на&nbsp;популярном ресурсе, поэтому я&nbsp;использую менее 
    универсальный, но&nbsp;быстрый метод:</p>
<pre class="prettyprint"><code>function dfm_recent_posts($before='&lt;li&gt;', $after='&lt;/li&gt;')
{
    global $wpdb;
    
    $posts = $wpdb->get_results(
        "SELECT COALESCE({$wpdb-&gt;postmeta}.meta_value, post_title) AS post_title, post_name " .
        "FROM {$wpdb-&gt;posts} " .
        "LEFT JOIN {$wpdb-&gt;postmeta} ON post_id = ID AND {$wpdb-&gt;postmeta}.meta_key = 'short_title' " .
        "WHERE post_status='publish' ORDER BY post_date DESC LIMIT 10"
    );
    
    echo dfm_posts_list($posts, $before, $after);
}

function dfm_posts_list($posts, $before='&lt;li&gt;', $after='&lt;/li&gt;')
{
    $siteurl = get_bloginfo('siteurl');
    $result = array();
    
    foreach($posts as $post) {
        $permalink = $siteurl . '/posts/' . $post-&gt;post_name;
        $result[] = sprintf('%s&lt;a href="%s" rel="bookmark"&gt;%s&lt;/a&gt;%s',
                            $before, $permalink, $post-&gt;post_title, $after);
    }
    
    return implode("\n", $result);
}</code></pre>    
<p>Функцию <code>dfm_recent_posts</code> вставляем в&nbsp;шаблоне <code>sidebar.php</code>:</p>
<pre class="prettyprint"><code>&lt;?php if(function_exists('dfm_recent_posts')) : ?&gt;
&lt;h3&gt;Последние статьи&lt;/h3&gt;
&lt;ul class="favorite"&gt;
    &lt;?php dfm_recent_posts(); ?&gt;
&lt;/ul&gt;
&lt;?php endif; ?&gt;</code></pre>

<h2>Похожие статьи</h2>
<p>Для похожих статей используется поле <code>related</code> со&nbsp;списком идентификаторов похожих 
    постов:</p>
<pre class="prettyprint"><code>add_filter('the_content', 'dfm_related_articles_filter');

function dfm_related_articles_filter($content) {
    global $post, $wpdb;

    $result = '';
    
    if(is_single() || is_feed()) {
        $related_IDs = get_post_meta($post->ID, 'related', true);    
        if(!empty($related_IDs)) {
            $related_posts = $wpdb->get_results(
                "SELECT post_title,post_name FROM {$wpdb->posts} " .
                "WHERE post_status='publish' AND ID IN ($related_IDs) " .
                "ORDER BY post_date DESC;"
            );

            if(!empty($related_posts)) {
                $result = '&lt;h2&gt;Похожие статьи&lt;/h2&gt;&lt;ul&gt;';
                
                foreach($related_posts as $p) {
                    $href = get_bloginfo('siteurl') . '/posts/'. $p->post_name;
                    $result .= sprintf('&lt;li&gt;&lt;a href="%s"&gt;%s&lt;/a&gt;&lt;/li&gt;',
                                       $href, $p->post_title);
                }
                $result .= '&lt;/ul&gt;';
            }
        }
    }

    return $content . $result;
}</code></pre>

<p>Идентификаторы смотрю на&nbsp;<a href="http://designformasters.info/site-map/">карте 
    сайта</a> с&nbsp;помощью FireBug, конечно, хорошо бы&nbsp;автоматизировать этот процесс, 
    но&nbsp;все руки не&nbsp;доходят, да&nbsp;и&nbsp;не&nbsp;так уж&nbsp;часто приходится этим заниматься. </p>

<p style="overflow:hidden;zoom:1;">
<a style="border:none;" href="http://make4you.net"><img alt="make4you" style="float:left;margin-right:1em;" src="http://designformasters.info/stuff/wordpress-custom-fields/make4you.png" width="211" height="69"></a>
<a href='http://make4you.net'>Форум Web 2.0 и&nbsp;блоггинг</a><br>
Дружелюбный форум о&nbsp;создании сайтов и&nbsp;ведении блогов. Присоединяйтесь.
</p>
<p><a href="http://feedads.g.doubleclick.net/~a/xXZGVsrRJxRGXPFub4B9qQxq2o8/0/da"><img src="http://feedads.g.doubleclick.net/~a/xXZGVsrRJxRGXPFub4B9qQxq2o8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/xXZGVsrRJxRGXPFub4B9qQxq2o8/1/da"><img src="http://feedads.g.doubleclick.net/~a/xXZGVsrRJxRGXPFub4B9qQxq2o8/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=f00cajxbWPs:ZAxWGz4QITA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=f00cajxbWPs:ZAxWGz4QITA:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/wordpress-custom-fields/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Путеводитель для новых читателей</title>
		<link>http://designformasters.info/posts/review-for-new-readers/</link>
		<comments>http://designformasters.info/posts/review-for-new-readers/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 23:29:17 +0000</pubDate>
		<dc:creator>Евгений</dc:creator>
		
		<category><![CDATA[Design For Masters]]></category>

		<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://designformasters.info/?p=414</guid>
		<description><![CDATA[Некоторые полезные статьи были опубликованы, когда количество читателей не&#160;достигало и&#160;десятой части сегодняшнего, поэтому я&#160;позволил себе немного вернуться к&#160;старым статьям.

Код

    Тестирование
        на&#160;кроссбраузерность, сервисы и&#160;утилиты
        Кроссбраузерность одна из&#160;самых сложных проблем в&#160;веб-разработке, хоть следование
        [...]]]></description>
			<content:encoded><![CDATA[<p>Некоторые полезные статьи были опубликованы, когда количество читателей не&nbsp;достигало и&nbsp;десятой части сегодняшнего, поэтому я&nbsp;позволил себе немного вернуться к&nbsp;старым статьям.</p>
<span id="more-414"></span>
<h2>Код</h2>
<ul>
    <li><a href="http://designformasters.info/posts/browser-compatibility-testing/">Тестирование
        на&nbsp;кроссбраузерность, сервисы и&nbsp;утилиты</a><br>
        Кроссбраузерность одна из&nbsp;самых сложных проблем в&nbsp;веб-разработке, хоть следование
        веб-стандартам и&nbsp;дает достаточно высокий уровень совместимости, но&nbsp;не&nbsp;все браузеры
        совершенны, старые браузеры часто удивляют разработчиков своим творческим подходом
        к&nbsp;обработке (X)HTML/CSS кода. </li>
    <li><a href="http://designformasters.info/posts/flash-embed-with-swfobject-2/">Внедрение
        Flash с&nbsp;помощью SWFObject 2</a><br>
        SWFObject 2 позволяет внедрять Flash не&nbsp;только динамически, с&nbsp;помощью JavaScript,
        но&nbsp;и&nbsp;статически, с&nbsp;помощью стандартной разметки, а&nbsp;JavaScript только исправляет
        неразрешимые с&nbsp;помощью разметки проблемы.</li>
    <li><a href="http://designformasters.info/posts/markup-craft/">Искусство разметки</a><br>
        Разметка это основа представления сайта, в&nbsp;той или иной степени она взаимосвязана
        с&nbsp;дизайном, контентом, аксессибилити, CSS и&nbsp;JavaScript, качество разметки влияет
        на&nbsp;качество связанного с&nbsp;ней кода, следуя советам этой статьи, вы&nbsp;сможете подняться
        на&nbsp;новый уровень мастерстве разметки. </li>
    <li><a href="http://designformasters.info/posts/70-expert-ideas-for-better-css-coding/">
        70 идей экспертов для улучшения CSS кода</a><br>
        Множество полезных советов по&nbsp;CSS.</li>
    <li><a href="http://designformasters.info/posts/microformats-what-they-are-and-how-to-use-them/">
        Микроформаты: Что это и&nbsp;как ими пользоваться?</a><br>
        Обзор который даст вам представление о&nbsp;том, что такое микроформаты, какие они могут
        дать вам преимущества и&nbsp;как их&nbsp;использовать, чтобы сделать контент более заметным
        и&nbsp;понятным для поисковых машин. </li>
    <li><a href="http://designformasters.info/posts/background-property/">Свойство background</a><br>
        Подробное описание свойства background и&nbsp;связанных с&nbsp;ним багов и&nbsp;различий в&nbsp;браузерах.
    </li>
    <li><a href="http://designformasters.info/posts/body-switcher/">Переключатель стилей</a><br>
        Часто новички задают вопрос, как подключить разный css, для разного разрешения экрана,
        времени суток, времени года, фазы луны. На&nbsp;самом деле в&nbsp;99% случаев, хватит одного
        css файла и&nbsp;использования техники описанной в&nbsp;этой статье.&nbsp; </li>
    <li><a href="http://designformasters.info/posts/adaptive-layout/">Адаптивная разметка</a><br>
        Отличный пример использования переключателя стилей и&nbsp;интересная идея адаптации разметки
        к&nbsp;возможностям устройства. </li>
    <li><a href="http://designformasters.info/posts/css-float-theory-and-practice/">CSS
        Float в&nbsp;теории и&nbsp;на&nbsp;практике</a><br>
        Float одно из&nbsp;самых проблемоемких свойств CSS, в&nbsp;значительной степени благодаря
        браузерам. </li>
    <li><a href="http://designformasters.info/posts/fauxcolumns/">Псевдоколонки</a><br>
        Один из&nbsp;простейших способов сделать колонки равной высоты.</li>
    <li><a href="http://designformasters.info/posts/accessible-data-visualization/">Визуализация
        данных на&nbsp;HTML и&nbsp;CSS</a><br>
        Техника визуализации данных с&nbsp;помощью HTML и&nbsp;CSS позволяет тесно интегрировать визуализацию
        и&nbsp;навигацию на&nbsp;сайте. </li>
    <li><a href="http://designformasters.info/posts/windows-sidebar-gadget/">Создание гаджетов
        для Windows Sidebar</a><br>
        Гаджет — это небольшая веб-страница, поэтому его создание не&nbsp;требует от&nbsp;веб-разработчика
        значительных усилий или освоения новых технологий. </li>
</ul>
<h2>Дизайн</h2>
<ul>
    <li><a href="http://designformasters.info/posts/usability-rules-psychology-terms/">Юзабилити: Правила,
        психология, термины</a><br>
        Профессиональный веб-разработчик должен быть адвокатом посетителя сайта, защищать
        его интересы и&nbsp;гарантировать, что независимо от&nbsp;сложности сайта, пользователь всегда
        сможет найти то, что ему нужно. Чтобы успешно выполнять эти задачи, вы&nbsp;должны уметь
        эффективно защищать свои идеи и&nbsp;решения в&nbsp;дискуссиях с&nbsp;клиентами и&nbsp;коллегами, ваша
        работа в&nbsp;том, чтобы корректировать плохие идеи и&nbsp;неверные концепции, а&nbsp;не&nbsp;слепо
        следовать им. </li>
    <li><a href="http://designformasters.info/posts/creative-use-of-png-transparency/">Креативное
        использование полупрозрачных PNG в&nbsp;веб-дизайне</a><br>
        С&nbsp;уходом со&nbsp;сцены IE6 полупрозрачные PNG будут все шире применяться в&nbsp;веб-дизайне,
        к&nbsp;сожалению времена когда можно будет использовать полупрозрачность и&nbsp;не&nbsp;беспокоиться
        о&nbsp;костыле для старичка IE6 наступят еще не&nbsp;скоро.</li>
    <li><a href="http://designformasters.info/posts/readability/">Читабельность</a><br>
        Если текст сайта будет удобочитаемым выиграют все, пользователям не&nbsp;придется щуриться,
        и&nbsp;они еще не&nbsp;раз к&nbsp;вам вернуться, вы&nbsp;будете рады растущей аудитории, а&nbsp;люди с&nbsp;пониженным
        зрением будут вам особенно благодарны. </li>
    <li><a href="http://designformasters.info/posts/clear-hyperlinks/">Оформление гиперссылок</a><br>
        Чтобы посетители могли легко ориентироваться на&nbsp;сайте, ссылки должны хорошо выделяться,
        быть абсолютно ясными и&nbsp;информативными, несмотря на&nbsp;очевидность этих советов все
        еще можно встретить сайты с&nbsp;неудачным оформлением ссылок.</li>
    <li><a href="http://designformasters.info/posts/web20-design/">Дизайн в&nbsp;стиле Web 2.0</a><br>
        Некоторые элементы, распространенные в&nbsp;современном web дизайне, с&nbsp;объяснением, почему
        они работают, и&nbsp;как когда и&nbsp;где вы&nbsp;можете использовать эти элементы в&nbsp;ваших работах.</li>
    <li><a href="http://designformasters.info/posts/23-lessons-from-eye-tracking-studies/">
        23 важных вывода из&nbsp;результатов eye-tracking исследований</a><br>
        Eye-tracking исследования горячая тема в&nbsp;мире веб-дизайна, но&nbsp;у&nbsp;них есть одна проблема,
        не&nbsp;всегда очевидно как применить результаты при разработке реального сайта. В&nbsp;этой
        статье автор пытается дать несколько, основанных на&nbsp;результатах таких исследований,
        советов позволяющих увеличить эффективность вашего сайта.</li>
    <li><a href="http://designformasters.info/posts/usability-ria/">Юзабилити интернет приложений</a><br>
        По&nbsp;мере усложнения интернет приложений все труднее сохранить простору взаимодействия
        с&nbsp;пользователей.</li>
    <li><a href="http://designformasters.info/posts/whitespace/">Роль пространства в&nbsp;дизайне</a><br>
        Когда вы&nbsp;научитесь, использовать пространство, вы&nbsp;упростите жизнь вашим читателям,
        сможете точнее позиционировать продукты, и, возможно, начнете видеть свои работы
        в&nbsp;новом свете.</li>
</ul>
<h2>SEO</h2>
<ul>
    <li><a href="http://designformasters.info/posts/google-page-rank/">Все о&nbsp;Google PageRank</a><br>
        Все его используют, но&nbsp;мало кто знает, как он&nbsp;работает. Google PageRank, это один
        из&nbsp;важнейших для веб-разработчиков параметров.</li>
</ul>
<p>На <a href="http://designformasters.info/site-map/">карте сайта</a> можно посмотреть
    все опубликованные статьи.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/_KHvD1w2i-0D8WwdUyRv8H1jxTc/0/da"><img src="http://feedads.g.doubleclick.net/~a/_KHvD1w2i-0D8WwdUyRv8H1jxTc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/_KHvD1w2i-0D8WwdUyRv8H1jxTc/1/da"><img src="http://feedads.g.doubleclick.net/~a/_KHvD1w2i-0D8WwdUyRv8H1jxTc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DesignForMasters?a=3UX5toy4Bsw:q1w5n3CjgZk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DesignForMasters?i=3UX5toy4Bsw:q1w5n3CjgZk:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://designformasters.info/posts/review-for-new-readers/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

