<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>«XOR's Post»</title><link>http://blogs.byte-force.com/xor/default.aspx</link><description>Somewhat frequent posts by Andrew Mayorov (aka XOR) on software architecture, programming, development news and other fun stuff. In russian and english.</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 (Build: 30912.2823)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/xor" /><feedburner:info uri="xor" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>SDF #3. Компоненты в LSD</title><link>http://feedproxy.google.com/~r/xor/~3/ggxoIqy0eEQ/sdf-3.aspx</link><pubDate>Thu, 15 Oct 2009 10:18:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:20977</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=20977</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=20977</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/10/15/sdf-3.aspx#comments</comments><description>&lt;p&gt;&lt;i&gt;Глава третья &lt;/i&gt;&lt;a href="http://blogs.byte-force.com/xor/archive/tags/SDF/default.aspx"&gt;&lt;i&gt;истории про SDF&lt;/i&gt;&lt;/a&gt;&lt;i&gt;, в которой мы продолжаем смотреть на обработчик LiveDocument. Что-то делает его &amp;laquo;живым&amp;raquo;, нам надо в этом разобраться. Появляются компоненты IDocumentSource и INodeExtender с примерами.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Чтобы документы в Live Server Documents стали &amp;laquo;живыми&amp;raquo; надо использовать компоненты, модифицирующие документ. Есть два типа компонентов, реализующих следующие интерфейсы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;IDocumentSource &lt;/b&gt;&amp;ndash; источник документа. Возвращает XML-документ (или элемент, фрагмент документа), который вставляется в документ вместо этого компонента.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;INodeExtender &lt;/b&gt;&amp;ndash; позволяет модифицировать XML-дерево на входе и на выходе из &amp;laquo;расширенного&amp;raquo; узла.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Здесь необходимо рассказать о том, как же именно происходит обработка документа. Все довольно прямолинейно. Обработчик LiveDocument загружает документ с диска и начинает просматривать его элемент за элементом. Если он находит известную ему директиву, то совершает положенные действия. Все директивы LSD принадлежат вот такому пространству имен: &lt;span style="color:red;"&gt;xmlns:lsd&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;http://www.byte-force.com/schemas/LSD&lt;/span&gt;&amp;quot;. Так что если написано &amp;ldquo;lsd:...&amp;rdquo;, то этот элемент относится не к данным, а к &amp;laquo;активному контенту&amp;raquo;. Пример директивы:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:document &lt;/span&gt;&lt;span style="color:red;"&gt;source&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;sdf.ModuleStart, sdf&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;module-name&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;sdf.Articles&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:document&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Директива выполняется так:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Создается компонент типа &amp;ldquo;sdf.ModuleStart, sdf&amp;rdquo;. Этот компонент реализует интерфейс IDocumentSource. &lt;/li&gt;
&lt;li&gt;Исполняется метод ProcessRequest, которому передается один параметр. Имя и значение параметра, думаю, очевидны. &lt;/li&gt;
&lt;li&gt;Метод возвращает элемент (или кусочек XML-дерева), который и вставляется в обрабатываемый документ &lt;b&gt;вместо&lt;/b&gt; всей этой директивы. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;А вот пример, в котором используется node extender:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:extension &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;PriceTagExtender&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;xsl-doc&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;pricetag-brief.xsl&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;select&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;sdf:objects/sdf:article&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:document &lt;/span&gt;&lt;span style="color:red;"&gt;source&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;sdf.Persist.ObjectMan, sdf&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;parent-path&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;request-param&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;$current-site&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;path&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;request-param&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;$path-info&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;mode&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;object&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;lang&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;{/sdf:page/sdf:context/@lang}&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;bookmark-by&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;page-num&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;xsl-doc&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;article-full.xsl&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;filter&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;filter &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;isPublished&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;view&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;published&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;filter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;filter &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;hasLocale&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;param &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;lang&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;lsd:request-param&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;$current-lang&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;filter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:param&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:document&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;lsd:extension&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Здесь происходит следующее:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Когда обработчик подходит к узлу &amp;ldquo;lsd:extension&amp;rdquo;, он создает объект с типом &amp;ldquo;PriceTagExtender&amp;rdquo;. Пытливый читатель заметит, что это неправильное имя типа &amp;ndash; нет неймспейса и имени сборки. Действительно, LSD понимает не только полные имена типов, но и логические имена компонентов (заданные в web.config).&lt;/li&gt;
&lt;li&gt;При входе в элемент &amp;ldquo;lsd:extension&amp;rdquo; вызывается метод INodeExtender.PreProcessNode, в который передаются два аргумента: xsl-doc и select. &lt;/li&gt;
&lt;li&gt;У данного конкретного экстендера метод PreProcessNode ничего не делает, так что обработка просто идет дальше. &lt;/li&gt;
&lt;li&gt;Вызывается компонент &amp;ldquo;sdf.Persist.ObjectMan, sdf&amp;rdquo;. Он отрабатывает, возвращая XML-представление объектов, полученных из базы данных. Полученный XML вставляется в документ вместо директивы &amp;ldquo;lsd:document&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Обработка подошла к выходу из узла &amp;ldquo;lsd:extension&amp;rdquo;, и, соответственно, вызывается метод INodeExtender.PostProcessNode. В этот раз внутри узла, переданного на обработку, находятся объекты, полученные из база данных. Экстендер выбирает элементы по заданному XPath-выражению (sdf:objects/sdf:article) и добавляет к ним цену. &lt;/li&gt;
&lt;li&gt;Выполнение метода PostProcessNode закончено и LiveDocument &lt;b&gt;убирает элемент&lt;/b&gt; &amp;ldquo;lsd:extension&amp;rdquo; из документа. При этом, конечно, все содержимое узла остается. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;А вот и интерфейсы компонентов. Они совершенно очевидны:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IDocumentSource &lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:#2b91af;"&gt;XmlNode &lt;/span&gt;GetDocument( &lt;span style="color:#2b91af;"&gt;HttpContext &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;NameObjectCollection &lt;/span&gt;args );&lt;br /&gt;}&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;INodeExtender &lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;void &lt;/span&gt;PreProcessNode( &lt;br /&gt;        &lt;span style="color:#2b91af;"&gt;HttpContext &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;XmlNode &lt;/span&gt;node, &lt;span style="color:#2b91af;"&gt;NameObjectCollection &lt;/span&gt;args );&lt;br /&gt;    &lt;span style="color:blue;"&gt;void &lt;/span&gt;PostProcessNode( &lt;br /&gt;        &lt;span style="color:#2b91af;"&gt;HttpContext &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;XmlNode &lt;/span&gt;node, &lt;span style="color:#2b91af;"&gt;NameObjectCollection &lt;/span&gt;args );&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;i&gt;В сегодняшней фотосессии &amp;ndash; модуль управления структурой сайта (папками, проще говоря).&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.byte-force.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xor/image_5F00_6F136213.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" alt="image" src="http://blogs.byte-force.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xor/image_5F00_thumb_5F00_4C02F0A3.png" border="0" height="480" width="615" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=20977" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/SDF/default.aspx">SDF</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/10/15/sdf-3.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/7y79qWOxOG0/sdf-3.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/e6ADxIlzd9M/sdf-3.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/gveTVnffXdY/sdf-3.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/cSv3ajVvrcw/sdf-3.aspx</feedburner:origLink></item><item><title>SDF #2. Серверные XSLT-трансформации</title><link>http://feedproxy.google.com/~r/xor/~3/QQHZYATItZQ/sdf-2.aspx</link><pubDate>Wed, 14 Oct 2009 09:23:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:20959</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=20959</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=20959</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/10/14/sdf-2.aspx#comments</comments><description>&lt;p&gt;&lt;i&gt;Глава вторая &lt;/i&gt;&lt;a href="http://blogs.byte-force.com/xor/archive/tags/SDF/default.aspx"&gt;&lt;i&gt;истории про SDF&lt;/i&gt;&lt;/a&gt;&lt;i&gt;, в которой мы кладем на операционный стол хэндлер для файлов с расширением &amp;ldquo;.sdf&amp;rdquo; и начинаем его внимательно рассматривать. Для начала разбираемся, для чего он нужен.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;ASP.NET &amp;ndash; отличная платформа для разработки сайтов, но при этом их стандартный способ рендеринга страниц просто ужасен. Я говорю про Web Forms. На мой взгляд, попытка притащить привычный всем дизайнер форм в веб провалилась. Причем формы-то получаются нормальные, а вот страницы в целом &amp;ndash; вовсе нет. &lt;/p&gt;
&lt;p&gt;Я считаю, что лучший язык для формирования HTML &amp;ndash; это XSLT, и, соответственно, исходные данные для этого должны подаваться в виде XML. В принципе, любой современный браузер может загрузить XML-документ и применить XSLT-трансформацию прямо на клиентской стороне, но такой подход используется редко. Во-первых, не все браузеры современны. Во-вторых, не всегда уместно тащить все данные на клиент. Возможно, мы должны обработать большой массив информации и выдать краткий ответ. Делать это на клиенте, конечно, не разумно. Наконец, клиентская трансформация просто не прижилась пока. &amp;laquo;Так сейчас не носят&amp;raquo;.&lt;/p&gt;
&lt;p&gt;Нужен механизм, который берет XML-документ, лежащий на сервере, тут же трансформирует его при помощи назначенного документу XSLT-файла, и засылает результат клиенту. В SDF для этого служит подсистема LSD &amp;ndash; Live Server Documents. Чтобы использовать ее, надо подключить к сайту специальный HttpHandler. Добавьте следующее в web.config:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;httpHandlers&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add &lt;/span&gt;&lt;span style="color:red;"&gt;verb&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;path&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*.sdf&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;lsd.LiveDocument,lsd&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;httpHandlers&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Обратите внимание, что мы вешаем хэндлер на файлы с расширением &amp;ldquo;.sdf&amp;rdquo;, а значит именно так у нас обычно и называются серверные XML-документы. Тот факт, что Visual Studio 2008 оккупировало это расширение под свои нужды, считаем происками врагов. Мы раньше начали и пока продолжаем. Но вам никто не мешает выбрать любое другое расширение. &lt;/p&gt;
&lt;p&gt;Чтобы проверить серверную трансформацию:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Делаете XML-документ &amp;ldquo;test.sdf&amp;rdquo; и кладете его на сервер. &lt;/li&gt;
&lt;li&gt;Создаете XSLT (&amp;ldquo;test.xslt&amp;rdquo;), который преобразует этот документ в HTML. &lt;/li&gt;
&lt;li&gt;Добавляете в &amp;ldquo;test.sdf&amp;rdquo; директиву: 
    &lt;br /&gt;&amp;lt;?xml-stylesheet language=&amp;rdquo;text/xsl&amp;rdquo; href=&amp;rdquo;test.xsl&amp;rdquo; ?&amp;gt; &lt;/li&gt;
&lt;li&gt;Открываете файл в браузере и убеждаетесь, что это HTML. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Это уже удобно для создания статического сайта &amp;ndash; все ваши данные лежат по файлам XML, а все их представления &amp;ndash; по файлам XSLT. Получается MVC без одного компонента &amp;ndash; без контроллера. Но и он тоже у нас есть.&lt;/p&gt;
&lt;p&gt;Для того, чтобы контролировать процесс формирования документа, в LSD есть директивы, позволяющие выполнять код, модифицирующий этот XML-документ перед трансформацией. Собственно, поэтому эта подсистема и называется &amp;laquo;Живые Серверные Документы&amp;raquo;. Но про это мы будем говорить уже не сегодня. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.byte-force.com/xor/archive/2009/10/15/sdf-3.aspx"&gt;Продолжение &amp;raquo;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;i&gt;Сегодняшняя картинка &amp;ndash; индексная страница sdf.CPanel (или просто цэпанели):&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.byte-force.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xor/image_5F00_1584B607.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" alt="image" src="http://blogs.byte-force.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xor/image_5F00_thumb_5F00_5A50DA3B.png" border="0" height="768" width="410" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Да, я знаю, похоже на iPhone. :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=20959" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/SDF/default.aspx">SDF</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/10/14/sdf-2.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/vnPrBhZLhNs/sdf-2.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/w_LahXErmG0/sdf-2.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/usYmEAxqBig/sdf-2.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/1mTwN-FKpQg/sdf-2.aspx</feedburner:origLink></item><item><title>SDF #1. О чем это вообще?</title><link>http://feedproxy.google.com/~r/xor/~3/vHLMyZshsew/sdf-1.aspx</link><pubDate>Tue, 13 Oct 2009 08:30:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:20796</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=20796</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=20796</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/10/13/sdf-1.aspx#comments</comments><description>&lt;p&gt;Время идет, SDF развивается, появляются пользователи уже и за стенами BYTE-force, а хорошей документации все нет и нет. Я решил пока начать писать короткие заметочки про SDF, которые бы так или иначе помогали понять его суть. Пишу в наш публичный блог, чтобы уж сразу все желающие видели. Нам скрывать нечего.&lt;/p&gt;
&lt;h2&gt;Итак, что такое SDF?&lt;/h2&gt;
&lt;p&gt;SDF &amp;ndash; это фреймворк (или движок) для разработки сайтов и веб-приложений. Выстроен поверх ASP.NET. Включает в себя несколько подсистем:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HttpHandler LiveDocument, который собирает XML-документ из компонентов и прогоняет через XSLT-трансформацию. &lt;/li&gt;
&lt;li&gt;Система ограничения доступа ForceField.NET. &lt;/li&gt;
&lt;li&gt;sdf.XPath &amp;ndash; известный многим ObjectXPathNavigator. &lt;/li&gt;
&lt;li&gt;Ядро SDF. Обеспечивает работу с объектами в базе данных. &lt;/li&gt;
&lt;li&gt;sdf.CPanel &amp;ndash; CMS для управления объектами SDF. &lt;/li&gt;
&lt;li&gt;Плюс дополнительные модули. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Рассказывать про все сразу не получится, ибо слои приложения разнообразны и достаточно независимы. Поэтому буду перескакивать с пятого на десятое. Надеюсь, что, в процессе прочтения заметок, у вас будет складываться общая картина.&lt;/p&gt;
&lt;p&gt;Да, кстати, я не ответил на вопрос: что означает &amp;laquo;SDF&amp;raquo;? Открою великую тайну &amp;ndash; это аббревиатура &amp;laquo;Site Development Framework&amp;raquo;. Банально, но так уж сложилось исторически. &lt;/p&gt;
&lt;h2&gt;Зачем это?&lt;/h2&gt;
&lt;p&gt;Зачем это нужно, если уже есть куча готовых решений? Тому есть несколько причин:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Мы начали делать SDF в 2001 году. Тогда уже была вторая бэта-версия .NET Framework, а вот кучи готовых решений под него еще не было. &lt;/li&gt;
&lt;li&gt;Нам не нравятся Web Forms, которые следовало использовать по официальной идеологии MS. Вместо этого хотелось использовать XSLT. Похожее решение есть только на Яве &amp;ndash; это Cocoon, и он не настолько популярен, чтобы его портировали под .NET (до сих пор). &lt;/li&gt;
&lt;li&gt;SDF &amp;ndash; это не только веб-движок, но еще и идеология иерархического хранения объектов. Для этого сделана специальная структура базы данных, с которой мы и работаем. Пока удается с удобством загнать в нее большинство решаемых задач. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Можно продолжать список, но пока хватит. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.byte-force.com/xor/archive/2009/10/14/sdf-2.aspx"&gt;Продолжение &amp;raquo;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;i&gt;Скриншот логиновой страницы&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;/i&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="image" alt="image" src="http://blogs.byte-force.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xor/image_5F00_2E4E73EA.png" border="0" height="480" width="473" /&gt; &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=20796" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/SDF/default.aspx">SDF</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/10/13/sdf-1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/5eecP8Y_FDc/sdf-1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/XhWkF5_QAS8/sdf-1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/73GPlYOnEs0/sdf-1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/gT9PsAPVSnc/sdf-1.aspx</feedburner:origLink></item><item><title>Неладно что-то в HttpApplication</title><link>http://feedproxy.google.com/~r/xor/~3/lAketI6YghQ/19998.aspx</link><pubDate>Fri, 09 Oct 2009 15:07:36 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:19998</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=19998</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=19998</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/10/09/19998.aspx#comments</comments><description>&lt;p&gt;Угробил кучу времени на такую вот проблему. Цепляю обработчик на событие HttpApplication.PostAuthenticateRequest, а он не срабатывает. Причем раньше все работало, а после, казалось бы, небольшого рефакторинга перестало. После долгих разбирательств оказалось, что когда приложение полностью проинициализировано, его события уже нельзя менять. Я не могу ни подписаться на событие, ни отписаться от события. Все заморожено. &lt;/p&gt;  &lt;p&gt;Другими словами, цепляться на события приложения можно только в методе HttpApplication.Init() или в Application_Start() в global.asax.cs. Зачем придуманы такие ограничения, для меня совершенно непонятно. &lt;/p&gt;  &lt;p&gt;Корень же проблемы в том, что в ASP.NET есть только одна возможность сделать что-то по старту приложения – метод Application_Start. Ясно, что из своего модуля ты в этот метод не подпихнешься. Если делаешь инициализацию в методе Init() модуля, то в это время еще не готово само приложение. Некоторые методы могут быть недоступны. Например, MapPath. Пригодилось бы событие HttpApplication.AfterInit, но такого нет. Вот я и пытался сделать инициализацию по первому событию BeginRequest. Не получилось.&lt;/p&gt;  &lt;p&gt;Возможно, нам поможет &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx" target="_blank"&gt;preload&lt;/a&gt;, но он будет еще только в следующей версии АСП. А пока помним, что подписываться на события можно не всегда. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=19998" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/ASP.NET/default.aspx">ASP.NET</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/10/09/19998.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/m18xdGcUIXA/19998.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/GzBRY5zNOVE/19998.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/Pmtr7UrXHRg/19998.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/aJy53g15oUg/19998.aspx</feedburner:origLink></item><item><title>CEE-SECR 2009</title><link>http://feedproxy.google.com/~r/xor/~3/_gOqtg89MYI/19560.aspx</link><pubDate>Mon, 05 Oct 2009 08:13:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:19560</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=19560</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=19560</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/10/05/19560.aspx#comments</comments><description>&lt;p&gt;Нашел свой доклад про XSLT в &lt;a href="http://cee-secr.org/lang/ru-ru/for-participants/talks-by-author/" target="_blank"&gt;списке докладов&lt;/a&gt; конференции &amp;laquo;Разработка ПО 2009&amp;raquo; (CEE-SECR). Придется съездить, посмотреть, как там что. :)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://cee-secr.org/poster-talks/mayorov/"&gt;Опубликовали страничку про мой доклад&lt;/a&gt;. С моей же физиономией. Какая-то странная фотография, а? :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=19560" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/CEE-SECR/default.aspx">CEE-SECR</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/10/05/19560.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/IxithDKCQzM/19560.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/KIgE2R1ztqA/19560.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/UgTt-MSZY7U/19560.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/WlhudbhLUj8/19560.aspx</feedburner:origLink></item><item><title>Google Chrome Frame</title><link>http://feedproxy.google.com/~r/xor/~3/KQIjktql1sU/google-chrome-frame.aspx</link><pubDate>Wed, 23 Sep 2009 10:00:29 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:15170</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=15170</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=15170</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/23/google-chrome-frame.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://code.google.com/chrome/chromeframe/" target="_blank"&gt;Google Chrome Frame&lt;/a&gt; - интереснейшая вещь. Это примочка к IE (6, 7, 8), которая показывает страницу во внедренном в IE Хроме. В деталях не разбирался. Скорее всего, в страницу внедряется ActiveX с Chrome внутри. Ну может хоть так удастся IE забороть.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=15170" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.byte-force.com/xor/archive/tags/News/default.aspx">News</category><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/web+development/default.aspx">web development</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/23/google-chrome-frame.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/H7PI4eCUd7U/google-chrome-frame.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/SlXScH1UL3s/google-chrome-frame.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/uR73x40shrA/google-chrome-frame.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/AD6xXbHM_Ek/google-chrome-frame.aspx</feedburner:origLink></item><item><title>Вдогонку к докладу Макса про рефлекшен</title><link>http://feedproxy.google.com/~r/xor/~3/gfTqAmPdkAs/ObjectXPathNavigator-reflection-optimization.aspx</link><pubDate>Tue, 22 Sep 2009 09:43:48 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:14719</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=14719</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=14719</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/22/ObjectXPathNavigator-reflection-optimization.aspx#comments</comments><description>&lt;p&gt;Так как &lt;a href="http://yana.ineta.ru/Events/LectureInfo.aspx?Id=3536caab-55b5-4dfb-a038-f2589101d246" target="_blank"&gt;доклад Макса Высоких&lt;/a&gt; мне очень понравился, я сходу решил улучшить ObjectXPathNavigator, избавив его от чтения значений свойств через Reflection. Сказано – сделано. Сумел успешно применить оба метода: и через генерацию лямбда-выражений, и через DynamicMethod. &lt;/p&gt;  &lt;p&gt;Но вот незадача: потестировав скорость, я не увидел большой разницы. Максимум процентов 7. От запуска к запуску наблюдаются отклонения – примерно %0.5. Так что и тот максимум мог еще под погрешность попасть. &lt;/p&gt;  &lt;p&gt;Признаюсь, правда, что тестировал я спустя рукава – просто сделал юнит-тест с 100000 итераций и посмотрел время, которое запускалка тестов показывает. Возможно, она и врет, но вряд ли как Троцкий. Да и трассировка показывает, что все эти вызовы занимают только 0.27 процентов всего времени работы. А генерация делегатов – 0.47 сотых. И это всего за 4 вызова! Кстати, генерация акцессора для поля на порядок дольше, чем для свойства. Так что не ленитесь делать свойства. &lt;/p&gt;  &lt;p&gt;Но раз работа сделана, то выбрасывать ее как-то глупо. Решил остановиться на динамических методах, так как у Макса выходило, что это лучшее решение. И тут оказалось, что этот подход не работает в ASP.NET. Генерирует эксепшен: “System.Security.VerificationException: Operation could destabilize the runtime.”. Пришлось вернуться к лямбда-выражениям.&lt;/p&gt;  &lt;p&gt;Мораль проста: даже если рефлекшен медленнее прямого вызова в 80 раз, в сложных процессах это вообще не играет роли. Так что не напрягайтесь. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=14719" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/ObjectXPathNavigator/default.aspx">ObjectXPathNavigator</category><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/22/ObjectXPathNavigator-reflection-optimization.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/HltPPrqqgCI/ObjectXPathNavigator-reflection-optimization.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/Yl_bzlawVok/ObjectXPathNavigator-reflection-optimization.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/eYAkNtX_74U/ObjectXPathNavigator-reflection-optimization.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/tRf2DwPr9_o/ObjectXPathNavigator-reflection-optimization.aspx</feedburner:origLink></item><item><title>Про пятничный семинар</title><link>http://feedproxy.google.com/~r/xor/~3/ymjCNFwddUc/yana-0909-review.aspx</link><pubDate>Mon, 21 Sep 2009 09:18:48 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:14347</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=14347</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=14347</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/21/yana-0909-review.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.byte-force.com/xor/archive/2009/09/11/yana_2D00_september_2D00_2009.aspx" target="_blank"&gt;Тусовка в пятницу&lt;/a&gt; очень понравилась. Особенно доклад Макса Высоких. У него всегда отлично получается, а тут было просто великолепно. Все, кто поленился прийти, кусайте локти. Ну и рассматривайте материалы самостоятельно. Я свой доклад опубликовал &lt;a href="http://blogs.byte-force.com/media/p/14328.aspx" target="_blank"&gt;к нам&lt;/a&gt; и &lt;a href="http://yana.ineta.ru/Events/LectureInfo.aspx?Id=679b46e7-b643-4853-9d5c-e0d237c1cfde" target="_blank"&gt;на сайт YaNA&lt;/a&gt; (ищите, там где-то есть ссылочка).&lt;/p&gt;  &lt;p&gt;Еще мы с самыми активными камрадами здорово посидели после семинара за кружечкой пива. Это вот надо бы в традицию ввести. :)&lt;/p&gt;  &lt;p&gt;И вообще, такая вот идея возникла. Проводить регулярно беседы и транслировать их в интернет. Как бы такое ток-шоу локального масштаба. Чтобы можно было слушать беседы, а можно было написать или позвонить по скайпу. Звонящий тоже появляется в эфире, как если бы он тоже пришел. Ясно, что такое должно проходить регулярно, иначе постоянная аудитория не сформируется. И вот как раз регулярность какой-то одной маленькой группе обеспечить сложно. Представьте, каждую пятницу, например, устраивать эфир. Задолбает. &lt;/p&gt;  &lt;p&gt;Другое дело, если бы была такая кафуха, где собираются программисты. Не обязательно одни и те же, но всегда есть достаточное количество, чтобы было кого послушать. С разных столиков можно разные дискуссии транслировать, кстати. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=14347" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/YaNA/default.aspx">YaNA</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/21/yana-0909-review.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/2Fn0T5vQTlc/yana-0909-review.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/F3Sk4sMzxVA/yana-0909-review.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/3t2b23Neaw4/yana-0909-review.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/ISrKwGY-FbU/yana-0909-review.aspx</feedburner:origLink></item><item><title>В дженериках C# мог бы быть полезен “this type”</title><link>http://feedproxy.google.com/~r/xor/~3/4zONkSSGFOw/thistype-for-generics.aspx</link><pubDate>Wed, 16 Sep 2009 06:56:48 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:12587</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=12587</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=12587</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/15/thistype-for-generics.aspx#comments</comments><description>&lt;p&gt;&lt;em&gt;Разбирая наш код, нашел место, которое явно требовало бы некоторой подчистки. Но чтобы почистить, в языке нужна бы еще фича, которую и хочу обсудить. Я поднимал этот вопрос также и на &lt;/em&gt;&lt;a href="http://stackoverflow.com/questions/1400831/is-it-possible-to-make-this-type-for-generics-in-c" target="_blank"&gt;&lt;em&gt;StackOverflow&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. Был поддержан авторитетным камрадом.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Возьмем два класса, один наследуют от другого. Базовый класс – дженерик, в котором есть метод, который в производном закрытом типе должен возвращать экземпляр этого самаого закрытого типа.&lt;/p&gt;  &lt;p&gt;Например, так (обратите внимание на ??? в тексте):&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;public class Adapter&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt; public virtual &lt;strong&gt;???&lt;/strong&gt; DoSomething()&lt;br /&gt; {&lt;br /&gt;&amp;#160; ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class AdaptedString : Adapter&amp;lt;String&amp;gt;&lt;br /&gt;{&lt;br /&gt; public override AdaptedString DoSomething()&lt;br /&gt; {&lt;br /&gt;&amp;#160; ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Так сделать нельзя, так как в нет способа сослаться на тип, получающийся при “закрытии” дженерика. Нет такого ключевого слова, которым можно заменить “???”, чтобы указать, что этот метод будет возвращать экземпляр производного закрытого класса.&lt;/p&gt;

&lt;p&gt;Вместо этого остается только обходное решение. Надо явным образом передавать тип в базовый класс. Получается явно избыточно:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class Adapter&amp;lt;TThis,T&amp;gt;&lt;br /&gt;{&lt;br /&gt; public virtual TThis DoSomething()&lt;br /&gt; {&lt;br /&gt;&amp;#160; ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class AdaptedString : Adapter&amp;lt;&lt;strong&gt;AdaptedString&lt;/strong&gt;,String&amp;gt;&lt;br /&gt;{&lt;br /&gt; public override AdaptedString DoSomething()&lt;br /&gt; {&lt;br /&gt;&amp;#160; ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;А если в базовом классе нужно обращаться к методам экземпляра типа TThis, то приходится добавлять констрейнт. И получается совсем страшно:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class Adapter&amp;lt;TThis,T&amp;gt;&lt;br /&gt;&amp;#160;&lt;strong&gt;where TThis : Adapter&amp;lt;TThis, T&amp;gt;&lt;br /&gt;&lt;/strong&gt;{&lt;br /&gt; protected int _field; &lt;br /&gt;&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; public bool Compare( TThis obj )&lt;br /&gt; {&lt;br /&gt;&amp;#160; return _field == obj._field;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class AdaptedString : Adapter&amp;lt;AdaptedString,String&amp;gt;&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;В принципе, это работает. Но выглядит очень непонятно. Каждый раз, когда смотришь на этот код, путаешься, и нужно какой-то время, чтобы разобраться кто есть кто. &lt;/p&gt;

&lt;p&gt;Кажется было бы гораздо удобнее, если бы можно было как-то указать, что “TThis” должен быть &lt;strong&gt;этим&lt;/strong&gt; типом. Может быть использовать какое-нибудь ключевое слово. Типа “thistype”, хотя это тоже выглядит страшно. Может быть констрейнт ввести: where TThis: this type. &lt;/p&gt;

&lt;p&gt;А то ведь получается, что этот окружной путь позволяет запросто накосячить:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class TypeA : Adapter&amp;lt;TypeA, string&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;class TypeB : Adapter&amp;lt;TypeA, string&amp;gt; // Bug!&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=12587" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/csharp/default.aspx">csharp</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/15/thistype-for-generics.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/uY_bKt86i2o/thistype-for-generics.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/hw2-9oouWGo/thistype-for-generics.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/7i3glNZw0Fg/thistype-for-generics.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/4NPvZG7eX3c/thistype-for-generics.aspx</feedburner:origLink></item><item><title>PostSharp. Реализация INotifyPropertyChanged</title><link>http://feedproxy.google.com/~r/xor/~3/Kdnpfqzkrso/INotifyPropertyChanged-in-PostSharp.aspx</link><pubDate>Tue, 15 Sep 2009 07:59:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:11998</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;a href="http://www.postsharp.org/" target="_blank"&gt;PostSharp&lt;/a&gt; &amp;ndash; инструмент для аспектно-ориентированного программирования (AOP). Сделан здорово; руки постоянно чешутся заюзать его для чего-нибудь. Но найти хорошее применение для аспектов не так и просто. Возможно, просто мозг еще в правильном направлении не повернут, не знаю. &lt;/p&gt;
&lt;p&gt;В блоге проекта появился пример &lt;a href="http://www.postsharp.org/blog/introducing-postsharp-20-1-notifypropertychanged" target="_blank"&gt;действительно отличного применения&lt;/a&gt; &amp;ndash; реализация интерфейса INotifyPropertyChanged. Его ручная реализация настолько скучна, что просто пугает. А тут достаточно написать аспект и использовать его вот так:&lt;/p&gt;
&lt;pre&gt;[NotifyPropertyChanged]&lt;br /&gt;public class TestBaseClass&lt;br /&gt;{&lt;br /&gt;    public string PropertyA { get; set; }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Причем сам аспект реально прост и логичен. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=11998" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/PostSharp/default.aspx">PostSharp</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/15/INotifyPropertyChanged-in-PostSharp.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/J3lcAeakIVs/INotifyPropertyChanged-in-PostSharp.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/Uc9TrKcQ560/INotifyPropertyChanged-in-PostSharp.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/TJlypot8INw/INotifyPropertyChanged-in-PostSharp.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/HNAJ2kvjHbo/INotifyPropertyChanged-in-PostSharp.aspx</feedburner:origLink></item><item><title>XsltView для MVC Framework</title><link>http://feedproxy.google.com/~r/xor/~3/-xuKX1zgyH8/xsltview-for-mvc.aspx</link><pubDate>Mon, 14 Sep 2009 20:26:27 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:11886</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=11886</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=11886</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/14/xsltview-for-mvc.aspx#comments</comments><description>&lt;p&gt;Не прошло и года с тех пор, как я &lt;a href="http://blogs.byte-force.com/xor/archive/2009/02/26/2764.aspx" target="_blank"&gt;ругал&lt;/a&gt; реализацию XsltViewEngine в MvcContrib, как я взял, и переделал эту штуку с использованием ObjectXPathNavigator. Выбросил, пожалуй, три четверти кода, осталось всего четыре ма-аленьких класса. И все работает. :) Надо только еще добавить специальную политику для класса ViewDataDictionary. Чтобы xpath-выражения для работы со входными данными попроще были. &lt;/p&gt;  &lt;p&gt;Должен сказать, что с объектом Html в этих шаблонах работать нельзя. Ну понятно, это же не веб-формы со внедренным кодом на C# – это XSLT. Думается, что это можно решить правильно сделанным объектом расширения с кастомными функциями. Надо только хорошо это обдумать. Все-то методы из хелперов тащить туда точно не надо.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=11886" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/ObjectXPathNavigator/default.aspx">ObjectXPathNavigator</category><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/MVC/default.aspx">MVC</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/14/xsltview-for-mvc.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/OoLPlRTR_2M/xsltview-for-mvc.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/129jHk40fdo/xsltview-for-mvc.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/juWugSn5BOE/xsltview-for-mvc.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/8Oafs9huOC0/xsltview-for-mvc.aspx</feedburner:origLink></item><item><title>YaNA – в следующую пятницу</title><link>http://feedproxy.google.com/~r/xor/~3/eYN_szKAuR4/yana_2D00_september_2D00_2009.aspx</link><pubDate>Fri, 11 Sep 2009 08:33:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:11456</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=11456</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=11456</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/11/yana_2D00_september_2D00_2009.aspx#comments</comments><description>&lt;p&gt;В следующую пятницу, 18 сентября 2009, состоится очередной семинар Yaroslavl .NET UG (YaNA). С точным местом пока не определились. Либо нам дадут обычную аудиторию в первом корпусе ЯрГУ, либо мы проведем все у нас в BYTE-force. В тесноте, но не в обиде. Следите за эфиром.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Семинар пройдет в обычном месте. Чуть раньше чем всегда, не в 7 вечера, а в 18:30. Все-таки пятница.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=11456" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/News/default.aspx">News</category><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/YaNA/default.aspx">YaNA</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/11/yana_2D00_september_2D00_2009.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/VHDpA_ER3bs/yana_2D00_september_2D00_2009.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/oPUxgiV5Hd0/yana_2D00_september_2D00_2009.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/LwoX1roL4T8/yana_2D00_september_2D00_2009.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/vSR-6471SXo/yana_2D00_september_2D00_2009.aspx</feedburner:origLink></item><item><title>Светящийся стакан</title><link>http://feedproxy.google.com/~r/xor/~3/TOZZt9G_Hek/glowing-glass.aspx</link><pubDate>Mon, 07 Sep 2009 16:35:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:10887</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=10887</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=10887</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/07/glowing-glass.aspx#comments</comments><description>&lt;p&gt;Студия Артемия Лебедева продает светящийся стакан &amp;ldquo;&lt;a href="http://store.artlebedev.ru/kitchen/luminarus/"&gt;Люминарус&lt;/a&gt;&amp;rdquo;. Берешь его в руку &amp;mdash; зажигается подсветка.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img alt="image" src="http://store.artlebedev.ru/_i/catalog/4hd2otcg.jpg" /&gt;    &lt;br /&gt;Вещь интересная, но все же не то, что нужно. Какая-то, знаете, индивидуалистская. Надо чтобы это работало так:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Разливаем по рюмкам. &lt;/li&gt;
&lt;li&gt;&amp;laquo;Тостующий&amp;raquo; берет рюмку и говорит тост. Рюмка загорается. Причем яркость может зависеть от длины тоста. &lt;/li&gt;
&lt;li&gt;Начинает чокаться и передает свечение другим. &lt;/li&gt;
&lt;li&gt;Выпили &amp;mdash; все плавно погасло. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Получаем девайс для дружной компании. Это же завсегда лучше, чем пить в одиночку. :) &lt;/p&gt;
&lt;p&gt;Если помните, такую штуку мы обсуждали несколько лет назад. Может кто и сделает?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(Кросспост с &lt;a href="http://habrahabr.ru/blogs/design/68959/" target="_blank"&gt;хабра&lt;/a&gt;. Интересно, что там он очень неоднозначную оценку получил. Куча людей против и только чуть-чуть больше - за. Непонятная реакция. Я бы понял, если бы было все равно.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=10887" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/Russian/default.aspx">Russian</category><category domain="http://blogs.byte-force.com/xor/archive/tags/_1F0440043E04_+_3604380437043D044C04_/default.aspx">Про жизнь</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/07/glowing-glass.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/caus-US4xHM/glowing-glass.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/IOaNgxdn5X8/glowing-glass.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/GuYlYrbEf08/glowing-glass.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/zacIn9gzvwI/glowing-glass.aspx</feedburner:origLink></item><item><title>Can we use CSS-sprite for custom fonts?</title><link>http://feedproxy.google.com/~r/xor/~3/7nqXwYMxXnk/css-sprite-for-custom-font.aspx</link><pubDate>Tue, 01 Sep 2009 17:32:00 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:8505</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=8505</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=8505</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/09/01/css-sprite-for-custom-font.aspx#comments</comments><description>&lt;p&gt;I wonder if it is possible to use CSS-sprites to output header text with custom fonts?&lt;/p&gt;
&lt;p&gt;Looks like it&amp;rsquo;s not hard to implement:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Prepare CSS-sprite with font &amp;ndash; output all letters in single image and make CSS file, which contains separate class for each letter. Class defines letter dimensions and background position, as usual.&lt;/li&gt;
&lt;li&gt;Mark HTML element to tranform with certain class.&lt;/li&gt;
&lt;li&gt;In onLoad event select all elements to transform and substitute each letter with span with respective class. &lt;/li&gt;
&lt;li&gt;Original letter goes into the span. It should be almost transparent so it is not visible, but can be selected. It will be also good if size of the original letter will be close to the size of letter in custom font. This will make selection more natural.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, we can make code on the server, that makes such sprite out of font (TrueType for example). This code could be run even at compile time, so it won&amp;rsquo;t impact run time experience at all.&lt;/p&gt;
&lt;p&gt;This method definitely have problems with kerning so for some fonts output won&amp;rsquo;t be perfect. But we can try to define kerning pairs in JavaScript file and adjust letter positions with margins. If there are not that many pairs in the particular font, it can work out.&lt;/p&gt;
&lt;p&gt;It is more a theoretical thing. Will it work? Will it lood good? Will it be faster than canvas- or flash-based solutions? Finally, maybe such approach is not new already?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;As I expected, such solution already exists - &lt;a href="http://fontjazz.com/"&gt;fontjazz.com&lt;/a&gt;. It doesn&amp;#39;t allow for text copying, but it should be quite easy to add this. Thanks &lt;a href="http://nuxdie.habrahabr.ru/" class="user_link"&gt;nuxdie&lt;/a&gt;&lt;span class="user_link"&gt; for the link. &lt;/span&gt;&lt;a href="http://nuxdie.habrahabr.ru/" class="user_link"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(Crossposted with translation from &lt;a href="http://habrahabr.ru/blogs/css/68411/" target="_blank"&gt;Habrahabr&lt;/a&gt;.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=8505" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/English/default.aspx">English</category><category domain="http://blogs.byte-force.com/xor/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://blogs.byte-force.com/xor/archive/tags/web+development/default.aspx">web development</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/09/01/css-sprite-for-custom-font.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/NudCm0VRFhU/css-sprite-for-custom-font.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/Lw2-y0Ys-_k/css-sprite-for-custom-font.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/cIQVYvNGZYg/css-sprite-for-custom-font.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/DkqWPFm7M0A/css-sprite-for-custom-font.aspx</feedburner:origLink></item><item><title>Ext.ux.TinyMCE v0.7 b1</title><link>http://feedproxy.google.com/~r/xor/~3/jT1LkGy7P2o/ext.ux.tinymce-v0.7b1.aspx</link><pubDate>Mon, 03 Aug 2009 10:32:17 GMT</pubDate><guid isPermaLink="false">2d7b5c81-17d2-487b-a0e9-0530898b531a:4551</guid><dc:creator>Andrew Mayorov</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.byte-force.com/xor/rsscomments.aspx?PostID=4551</wfw:commentRss><wfw:comment>http://blogs.byte-force.com/xor/commentapi.aspx?PostID=4551</wfw:comment><comments>http://blogs.byte-force.com/xor/archive/2009/08/03/ext.ux.tinymce-v0.7b1.aspx#comments</comments><description>&lt;p&gt;I’ve updated Ext.ux.TinyMCE to version 0.7 beta 1. It now surely works with Ext 3.0 and latest TinyMCE. Fixed some issues with resizing, focusing and so on. Applied changes, proposed by community. For now code is only available from &lt;a href="http://extjs.com/forum/showthread.php?p=366996#post366996" target="_blank"&gt;this forum post&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Please report any problems and bugs to the forum.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.byte-force.com/aggbug.aspx?PostID=4551" width="1" height="1"&gt;</description><category domain="http://blogs.byte-force.com/xor/archive/tags/News/default.aspx">News</category><category domain="http://blogs.byte-force.com/xor/archive/tags/English/default.aspx">English</category><category domain="http://blogs.byte-force.com/xor/archive/tags/ExtJS/default.aspx">ExtJS</category><category domain="http://blogs.byte-force.com/xor/archive/tags/TinyMCE/default.aspx">TinyMCE</category><feedburner:origLink>http://blogs.byte-force.com/xor/archive/2009/08/03/ext.ux.tinymce-v0.7b1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/_yCogBE5pcc/ext.ux.tinymce-v0.7b1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/56xW01zGhLw/ext.ux.tinymce-v0.7b1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/eiaNXKlPQ0Q/ext.ux.tinymce-v0.7b1.aspx</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/xor/~3/LUvPc25Rp4Q/ext.ux.tinymce-v0.7b1.aspx</feedburner:origLink></item></channel></rss>
