воскресенье, 30 ноября 2008 г.

XSLT атрибуты дочерних элементов

Как в XSLT использовать атрибуты дочерних элементов. Не так давно я описывал как в XSLT создавать новые элементы и атрибуты. Теперь приведу пример посложнее.

Для основного шаблона я генерирую ссылку-кнопку с помощью rails-методов:
xml.tag!("advanced"){
xml << link_to(image_tag("/images/template/buttons/search-advanced.gif", {:alt => "advanced", :class => "imagebutton"}),
:controller => '/search', :seller => @store.id)
}

В другом шаблоне, вместо ссылки и изображения, мне нужна просто ссылка. Вот примерный XSLT-код.
<xsl:element name="a">
<xsl:attribute name="href" >
<xsl:value-of select="advanced/a/@href" />
</xsl:attribute>
<xsl:text>Advanced Search</xsl:text>
</xsl:element>

Я просто создал новый элемент-ссылку(<a>) и присвоил ей атрибут href дочернего элемента <advanced>: "advanced/a/@href".
Читать дальше »

пятница, 28 ноября 2008 г.

БобрДобр для SEO-специалистов

Бобр ДобрСервис социальных закладок БобрДобр разрабатывает новый функционал для SEOшников. Как ни старался, в упор не смог найти, где в «блоге бобра» указывается дата поста (несерьёзно, господа «бобры»). Ну да свежее ничего нет, поэтому -- в «новости»
Уважаемые SEO-специалисты, пользующиеся нашим сервисом. Мы задумали оптимизировать работу с Бобрдобр для вас. Для того, чтобы сделать это наиболее качественно, нам нужна обратная связь с вами. Напишите нам, пожалуйста, о том, каких функций вам не хватает и какие были бы вам максимально полезны в вашей работе.
Бобрдобр прирастет новым удобным функционалом для SEOшников
Читать дальше »

Подсветка меню с помощью CSS

Большинство веб-сайтов подсвечивает пункт меню навигации в зависимости от раздела, где в данный момент находится пользователь. Это помогает посетителю лучше сориентироваться на сайте (помним о юзабилити!). Как правило, для этого нужно подстраивать код HTML каждой страницы, чтобы выделить соответствующий элемент меню.


Оказывается, выделение пункта меню можно реализовать с помощью CSS.

Перво-наперво вы должны присвоить class каждому элементу навигации.
<ul>
<li><a href="#" class="home">Home</a></li>
<li><a href="#" class="about">About us</a></li>
<li><a href="#" class="contact">Contact us</a></li>
</ul>

Затем вы должны назначить id каждому тегу <body>. Идентификатор id будет отражать где в данный момент находится пользователь и изменяться при переходе из одного раздела сайта в другой.

Для главной страницы он будет выглядеть <body id="home">, на странице «О нас» так: <body id="about">, а в разделе «Контакты» вот так: <body id="contact">.

После этого вы создаете правило CSS:
#home .home, #about .about, #about .about, #contact .contact
{
/* команды для подсвеченного элемента меню */
}

Это создаёт правило, которое срабатывает только тогда, когда class="home" находится внутри id="home", class="about" внутри id="about" и class="contact" внутри id="contact".

Пример из статьи: «My Top Ten CSS Tricks»

Upd: Специально для Анонима даю код:
/* стили для меню в этом посте */
.listMenu1 {
margin:0; padding:0px;list-style-type:none;background-color:#C61A1A;border-bottom:2px solid #000;
}
.listMenu1 li {
display:inline;
}
.listMenu1 li a, .listMenu1 li a:hover, .listMenu1 li a:visited {
color:#FFF;padding:0px 10px;margin:0px;border-bottom:0px;padding-bottom:3px;
}
/* теперь внимательно!
если у тебя, например, body id="products" как в моем примере,
или body id="contact", то соответствующий пункт меню будет подсвечен черным фоном
*/
#home .home, #about .about, #about .about, #contact .contact, #products .products {
background-color:#000;
}

Читать дальше »

Юзабилити в Web

Внимание: ненормативная лексикаВкратце о юзабилити в веб.
Юзабилити (англ. usability — дословно «удобство пользования», «применимость») — понятие в микроэргономике, обозначающее общую степень удобства предмета при использовании; термин схож с термином «эргономичность», однако имеет иную область распространения и отличается нюансами определения. Применительно к компьютерной технике термином юзабилити называют концепцию разработки пользовательских интерфейсов программного обеспечения, ориентированную на максимальное психологическое и эстетическое удобство для пользователя.
wikipedia.org
Самое простое и ёмкое определение, которое мне попадалось -- «Удобство сайта и его положительное восприятие аудиторией»

От юзабилити, зависит насколько комфортно пользователю будет работать с вашим сайтом.

О составляющих хорошего юзабилити даже писать не стану. Поверьте, -- на статьях по этой теме «взрослые» дяденьки с волосатыми руками и не менее толстые тётеньки с волосатыми ногами уже давно сколотили состояние. Лично я для себя выделил фразу «максимальное психологическое и эстетическое удобство для пользователя» Так сказать -- «на заметку»

И примерчик для тренировки «шишковидной железы»:
Господа «веб-мастеры» (написано как задумывалось!), угадайте с трёх раз какие эмоции вызовет у пользователя следующая ситуация. Он впервые попадает на ваш сайт, где его тут же встречает рекламный pop-up. Катающийся по экрану, а при попытке закрыть вываливающий в новое окно браузера «сайтец» с голыми тётками и полуметровыми хуями.

Что-то мне подсказывает, что для юзабилити это явный минус. Какова вероятность того, что этот гость снова вернётся на ваш сайт? Не так вот, снова лоханувшись через поиск, а конкретно? Да ему резко, до поноса должно что-то понадобиться именно на вашем сайте. А при том изобилии информации, существующем в современном интернете это весьма и весьма сомнительно.

Вобщем, господа, помните о «хуях» при разработке интерфейсов :).
Читать дальше »

110+ бесплатных RSS-иконок

Еще один ресурс со ссылками на более 110 бесплатных иконок для RSS.
110+ иконок для RSS
Кстати, свою RSS-иконку взял именно оттуда. Да, многие иконки в формате PNG, так что статья про PNG в Internet Explorer будет кстати.
Pro Blog Design
Читать дальше »

четверг, 27 ноября 2008 г.

Файл Sitemap для Blogger

Оказывается, Blogger генерирует robots.txt для каждого блога автоматически. Зайдите в Инструменты Google для веб-мастеров, затем в раздел вашего сайта (если он у вас зарегистрирован) и на страницу Анализ Robots.txt.

Или можете просмотреть его в браузере. Ваш файл robots.txt находится по адресу: http://yourblogname.blogspot.com/robots.txt.

Файл robots.txt для Ruby Brewed выглядит так:
User-agent: Mediapartners-Google
Disallow:

User-agent: *
Disallow: /search
Noindex: /feedReaderJson

Sitemap: http://dotrb.blogspot.com/feeds/posts/default?orderby=updated

Нижняя строчка и есть адрес вашего файла Sitemap.
Создание и отправка файла Sitemap позволяет обеспечить наличие в системе Google данных обо всех страницах на вашем сайте, включая URL-адреса, которые невозможно обнаружить в ходе стандартного процесса сканирования Google. После передачи файла Sitemap вы сможете выявлять проблемы, относящиеся к этому файлу или его URL-адресам.

На основании данных анализа файла robots.txt поисковый движок Google сам находит ваш Sitemap. Однако никто не мешает вам задать его вручную, в тех же инструментах Google для веб-мастеров. Более того, этот файл Sitemap вы можете указать и при регистрации сайта на Яндексе.
Читать дальше »

среда, 26 ноября 2008 г.

Тестер RegExp - регулярных выражений

Нашел полезный инструмент для тестирования регулярных выражений (RegExp) JavaScript. Нужно ввести шаблон (регулярное выражение) и проверяемый объект. Тестер выполняет операции:
String.match(pattern)
Проверяет совпадение заданной строки (String) регулярному выражению (pattern). С флагом g возвращает массив совпадений, без флага g возвращает первое совпадение. Если совпадений не найдено, возвращает null.
String.replace(pattern, string)
Заменяет совпадения заданной строкой и возвращает полученную строку.

Тестер регулярных выражений (RegExp) на JavaScript


RegExp:

Subject string:

Replacement text:

Result:



Ссылка: Online Regular Expression Tester
Читать дальше »

вторник, 25 ноября 2008 г.

CSS оформление внешних ссылок

Внешняя ссылка, Внутренняя ссылкаКак с помощью CSS выделить внешние ссылки, чтобы они отличались от внутренних.

Иногда в тексте страницы требуется выделить внешние ссылки другим стилем, чтобы они отличались от внутренних ссылок сайта. Для чего этим ссылкам может понадобиться дополнительное оформление? Потому, что пользователь должен знать, что пройдя по этой ссылке, он перейдёт на другой сайт. А вдруг страницы, на которую ведёт ваша внешняя ссылка, уже не существует? Или сервер недоступен? Или там, прости господи, такая непотребщина выложена, что просто «ужоснах»?! ..и пользователю придётся срочно в панике закрывать окно браузера, потому что он в данный момент в офисе, сзади приближается шеф, а тут в мониторе ТАКОЕ!..

Таким образом, подобное выделение делает интерфейс сайта более предсказуемым. А это, ИМХО, для юзабилити только плюс.

Для начала определимся, какие ссылки будем считать внутренними. В моём случае они могут быть такие: "http://dotrb.blogspot.com/", "http://www.dotrb.blogspot.com/" и "/". Крайнее обозначение -- это ссылка в «корень» сайта.

Для этого применим регулярные выражения и селекторы атрибутов CSS:
a[href^="http:"] {...}

Этот код означает, что все ссылки с атрибутом href начинающимся с http: будут иметь стили присвоенные в данном правиле.

Чтобы отличить внешние ссылки от внутренних, пропишем правило, включающее домен:
a[href^="http://dotrb.blogspot.com/"], a[href^="http://www.dotrb.blogspot.com/"], a[href^="/"] {
color:#C61A1A;
}

Беда в том, что IE 6 не понимает таких селекторов. Поэтому специально для «эксплорера» будем использовать expression.

Примерно так будет выглядеть правило, работающее для всех нормальных браузеров и Internet Explorer:
/* Цвет ссылки "по-умолчанию" -- для внешних ссылок */
a {color:#3256B6;}

/* Цвет внутренних ссылок */
a[href^="http://dotrb.blogspot.com/"], a[href^="http://www.dotrb.blogspot.com/"], a[href^="/"] {
color:#C61A1A;
}
/* Цвет внутренних ссылок для IE */
a, a:link{
color:expression(
(this.getAttribute("href") &&
( (this.getAttribute("href").lastIndexOf("http://dotrb.blogspot.com/")==0)||
(this.getAttribute("href").lastIndexOf("http://www.dotrb.blogspot.com/")==0)||
(this.getAttribute("href").lastIndexOf("/")==0)
)
) ? "#C61A1A" : "#3256B6"
);
}

Теперь внутренние ссылки у меня будут под цвет дизайна (#C61A1A), а внешние -- более приближенными к «стандартному» синему (#3256B6).
Читать дальше »

XSLT создание элементов и атрибутов

Еще одна «боевая» задача -- как в XSLT создавать элементы и задавать им атрибуты. Например, есть комплексная форма (<FORM>) или remote-форма (AJAX). И не хочется в XSLT-шаблонах лишний раз нагружать юзера конструкциями вроде:
<form onsubmit="new Ajax.Updater('paypal',
'/mystore/ajax_update_paypal',
{asynchronous:true, evalScripts:true,
onComplete:function(request){ajax_refresh_options()},
parameters:Form.serialize(this)});
return false;" method="post" action="/mystore/ajax_update_paypal">

<!-- Еще туева хуча полей -->

</form>

Это как номер раз. Второе -- когда самому нужно сверстать несколько таких шаблонов для одного и того же XML, так это и нерационально, и самому рехнуться можно. И третье: В Rails лучше использовать рельсовые методы, а не то, что получается у них на выходе.

Приведу пару простеньких примеров.

Пример номер «раз»

Фрагмент .rxml


# Form:Buy Now
xml.tag!("form-buy_now") do
xml.action("/cart/add/#{@item.id}")
xml.name("add_to_cart")

xml.tag!("button-buynow"){
xml << ( link_to_remote image_tag("/images/buttons/button_buynow.png", :class => "button", :alt => "buy now"), :url => {:controller => "cart", :action => "ajax_check_item", :id => @item.id, :buynow => 1 } )
}
end

Фрагмент XSLT


<xsl:element name="form" >
<!-- form: attributes -->
<xsl:attribute name="action" >
<xsl:value-of select="action" />
</xsl:attribute>
<xsl:attribute name="name" >
<xsl:value-of select="name" />
</xsl:attribute>

<!-- form: fields -->
<xsl:copy-of select="button-buynow/*" />
</xsl:element>

Пример номер «два»

Фрагмент .rxml


xml.tag!("store-search"){
#Form
xml.tag!( "form", :action => url_for({:controller=>"/search", :action=>"index"}), :name=>"searchform", :method => "get" ){
xml.tag!("search_by"){ xml << hidden_field_tag(:search_by_seller,1) }
xml.tag!("seller"){ xml << hidden_field_tag(:seller, @store.name) }

xml.tag!("submit"){
xml << image_submit_tag("/images/template/button_search.gif", {:alt => "search", :class => "imgbutton"})
}
}
#End: Form
}

Фрагмент XSLT


<xsl:template match="store-search/form">
<xsl:element name="form">
<!-- form: attributes -->
<xsl:attribute name="action" >
<xsl:value-of select="@action" />
</xsl:attribute>
<xsl:attribute name="name" >
<xsl:value-of select="@name" />
</xsl:attribute>
<xsl:attribute name="method" >
<xsl:value-of select="@method" />
</xsl:attribute>
<!-- form: elements -->
<xsl:copy-of select="search_by/*" />
<xsl:copy-of select="seller/*" />
<table class="compact">
<tr><td align="center" height="30">
<input name="text" id="text" class="field" value="" type="text" />
</td></tr>
<tr><td align="center">
<xsl:copy-of select="submit/*" />
</td></tr>
</table>
</xsl:element>
</xsl:template>

Вот такие конструкции :).
Читать дальше »

воскресенье, 23 ноября 2008 г.

Решение проблемы PNG в IE на чистом CSS

Суть проблемы в том, что IE по крайней мере до версии 6 не понимает полупрозрачность изображений формата PNG. Вобщем, кто сталкивался, тот знает.

Вот мой фикс для проблемы PNG в Internet Explorer на чистом CSS

CSS:


/* -- PNG Fix for IE 6 -- */
#rssfeed {
cursor: pointer;
background: none;
/* фильтр применим к IE5+/Win */
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='fixed', src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiel0SeNsSu52YwmiAJR-AEnJqpqUDxW-lDI_85mtdf-Cll5zo9pyO32TbT5cC5LYi3eaDiQZ183gVw-5kpDyNlmj3m_3HzQbpr05Wshe1vPSovqYY1Ocwipw6jQiZxJrXUkBgin-3zN6yz/');
}
#rssfeed[id] {
/* [id] применим для нормальных браузеров (не IE) */
background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiel0SeNsSu52YwmiAJR-AEnJqpqUDxW-lDI_85mtdf-Cll5zo9pyO32TbT5cC5LYi3eaDiQZ183gVw-5kpDyNlmj3m_3HzQbpr05Wshe1vPSovqYY1Ocwipw6jQiZxJrXUkBgin-3zN6yz/) no-repeat;
}
* html #rssfeed a {
/* сделать ссылки интерактивными в IE */
position: relative;
z-index: 999;
}

HTML:


<div id="rssfeed"></div>

Этот прием у меня сработал.

Почему-то многие рекомендуют способ от Komodomedia - CSS PNG Image Fix for IE. Наверное потому, что никто не применял :). У меня их способ не сработал.
Ну и вот еще ссылка на подборочку фиксов для PNG в IE: CSS Hackz Series: PNG Fix for Internet Explorer.
Читать дальше »

Баннер для вашего блога

Нужен баннер для вашего блога? Нет ничего проще! Предлагаю анимированный баннер, который показывает по очереди пять самых последних записей из вашего фида. Это циклический баннер для вашей рекламы!

Ruby Brewed [.rb]

↑ Grab this Headline Animator


Как сделать такой?

1. Регистрируйтесь на Feedburner;

2. После успешной регистрации вы попадёте на страницу Мои фиды. Введите URL вашего фида в поле "Зажигай" фид прямо сейчас;

Зажигай фид прямо сейчас

3. Не знаете, как найти фид (feed, RSS) вашего блога?
У каждого блога есть RSS-лента. Всё, что вам нужно, это отыскать такой значок на главной странице вашего дневника rss. Щелкните этот значок и вас перебросит на RSS-ленту. Скопируйте URL из адресной строки браузера;

4. После того как «прожжете» фид, заходите в настройки вашего фида. И оттуда -- на вкладку «Публикуй» - «Аниматор заголовков»;

5. Выберите шаблон для вашего баннера (или загрузите собственный), подберите шрифты и цвета. Когда всё будет готово, жмите кнопку «Активировать»;

6. Получите код вашего баннера. В списке предлагается несколько платформ:
MySpace page, TypePad blog, TypePad JP blog, Blogger blog, WordPress.com blog и Email signature (подпись к email)
Если вы не обнаружили движка вашего блога в списке, выбирайте последний пункт: Other (just gimme the code) -- Другой (просто дай мне код);

Получить код баннера

7. Полученный код разместите у себя в блоге.

© 2008 Ruby Brewed.
Читать дальше »

Иконка favicon для блога

Как добавить иконку (favicon) для вашего блога? Чтобы в адресной строке и в закладках пользователей URL вашего сайта отображался примерно так:
Иконка в адресной строке
1. Создать иконку
Вы можете создать иконку самостоятельно с помощью специальных програм (я использовал Axialis IconWorkshop) или плагина для Photoshop. Используйте
размер 16x16 пикселей или двойной: (16x16 и 32x32). Или вы можете выбрать готовую иконку, например, на следующих ресурсах.

2. Загрузить иконку
Теперь вам нужно загрузить иконку "в мир". Для этого вы можете использовать: сервисы файл-хостинга (требуется регистрация) или Сайты Google

3. Добавить иконку в шаблон
В редакторе шаблонов вставьте следующий код (только измените пути к вашей иконке) где-либо между тегами <head> и </head>:
<link href='http://imagehost.com/yourfavicon.ico' rel='shortcut icon'/>
<link href='http://imagehost.com/yourfavicon.ico' rel='icon'/>

Сохраните шаблон

Приложения

П1. Ресурсы иконок




П2. Файл-хостинги для иконок



Читать дальше »

Куда же вставить этот CSS?

Я здесь довольно часто пишу про оформление вашей страницы Blogger, тюнинг blogspot-страницы с помощью стилей. И если с HTML всё более-менее понятно /* не понятно? -- пишите! :) */, то с CSS может быть далеко не так тривиально. Итак, куда же вставлять этот чёртов CSS?

Blogger CSS: Инструкция по применению


Способ первый (универсальный):
  1. Идем в настройки шаблона (Настроить - Макет - Изменить HTML)
  2. В поле шаблона находим закрывающий тег </head>
  3. Прямо перед этим тегом создаём собственный раздел стилей: <style>здесь пишите ваши стили</style>
    Дополнено: Еще лучше
    <style type="text/css">здесь пишите ваши стили</style>

Например:
<style type="text/css">
/* комментарий: стиль для параграфа */
p {color: #1A4676;}

blockquote {
line-height:1.3em;
}
.more span {
font-size:100%;
font-weight:bold;
color: #1A4676;
}
</style>
</head>


Способ второй (настройка скина):
  1. Шаг 1 из первого способа
  2. В поле шаблона находим строку ]]></b:skin>
  3. Прямо перед этой строкой добавляем собственные стили

Например:
p {color: #1A4676;}
blockquote {
line-height:1.3em;
}
]]></b:skin>

Инструкция дана.
Читать дальше »

пятница, 21 ноября 2008 г.

Обдираем обои на веб-страницы

Нашел еще один ресурс, откуда можно надёргать бэкграундов (фонов). Ресурс этот не совсем обычный для веб-дизайна. Дело в том, что это магазин обоев. Тех самых, которые клеятся на стену, а не на ваш рабочий стол :). С сопутствующим замешиванием клея «Метилана», «Момента» или еще чего-нибудь в этом духе.

Настенные обои

И как же может нам пригодиться этот ресурс с бумажными обоями? А всё просто! Что характерно для обоев? -- Правильно! -- повторяемость рисунка. И при наличии нехитрых навыков можно нарезать бесшовных текстур из более 200 образцов, вывешенных на сайте.

А вот и ссылка: vintage wallpapers and wallcovering. Читать дальше »

Ошибка Internet Explorer: Операция прервана

Время от времени, особенно когда web-разработка вам начинает казаться на редкость простым и приятным делом, вы натыкаетесь на это:

Ошибка Microsoft Internet Explorer: Не удалось открыть узел... Операция прервана.
Error: Internet Explorer cannot open the Internet site. Operation aborted
IE Не удалось открыть узел. Операция прервана
В интернете вы скорее всего найдёте только одну причину, вызывающую эту ошибку. Видимо мне исключительно "повезло" -- я знаю целых 3 (три!).

1. Первая -- самая известная. Вы без труда найдёте её описание и решение в любом поисковике (я даже ссылки дам). Это ошибка DOM и JavaScript.

Это вызовет ошибку в IE


<html>
<head>
<script type="text/javascript">
function appendElementToBody() {
var span = document.createElement('span');
document.body.appendChild(span);
}
</script>
</head>
<body>
<table>
<tr>
<td>
<script type="text/javascript">
appendElementToBody();
</script>
</td>
</tr>
</table>
</body>
</html>

a) Дело в том, что вы не можете добавлять в элемент BODY из скрипта (javascript), который не является прямым потомком BODY;
b)Более того: вы не можете изменять родительский элемент из скрипта, являющегося его потомком.

Решение проблемы (фрагмент):


<body>
<table>
<tr>
<td>
...
</td>
</tr>
</table>
<script type="text/javascript">
appendElementToBody();
</script>
</body>

Это был первый случай. Два других не столь распространенныё, но описать их проще.
2. Wrong HTML code при использовании SSL
Причиной служит корявый HTML-код. Чаще всего наблюдается при защищенном соединении (по протоколу https://).
Решение: Перепроверьте, нет ли у вас «пересекающихся» элементов, все ли теги закрыты и т.п.

Третий случай совсем не тривиальный и довольно редкий
3. «Tabs in ERb views»
ХЗ, это уже просто «родной» глюк Ruby on Rails. Только вот один момент: иногда табы в видах .rhtml прокатывают. Их и не замечаешь пока не начнешь тестить страницу в IE. Опять-таки, чаще всего по https:. «Мистика», а бывает :).
Решение: не используйте символы табуляции в .rhtml

А вот и ссылки (только по первому случаю):
BUG: Error message when you visit a Web page or interact with a Web application in Internet Explorer: "Operation aborted"
Error: Internet Explorer cannot open the Internet site Operation aborted
Dealing with IE "Operation Aborted". Or, how to Crash IE


Еще по теме
Определить IE6 с помощью JavaScript 2
IE8 узнайте факты!
IE и параметр white-space:pre

Читать дальше »

четверг, 20 ноября 2008 г.

CSS горизонтальные списки

Горизонтальные списки полезны, например, при создании меню, списка ссылок и т.п. Лично я для создания меню традиционно использую таблицы (table), но это может быть не совсем правильно. Т.к. список -- это всё-таки структурированные данные, и для поисковой машины должен выглядеть в более выгодном свете. Это просто мои догадки, и возможно не совсем верные ;).

Итак, создадим структуру списка.

HTML: Неупорядоченный список (ul)


<ul class="listMenu">
<li><a href="http://dotrb.blogspot.com/search/label/HTML">HTML</a></li>
<li><a href="http://dotrb.blogspot.com/search/label/XML">XML</a></li>
<li><a href="http://dotrb.blogspot.com/search/label/CSS">CSS</a></li>
<li><a href="http://dotrb.blogspot.com/search/label/XSLT">XSLT</a></li>
</ul>

Создаём стили CSS для списка. Если задаёте стили в теле сообщения, заключайте их между тегами <style> и </style>.

CSS: Стили для списка


.listMenu {
margin:0; padding:0;
list-style-type:none;
}
.listMenu li {
display:inline;
}

В-принципе этого достаточно. Чтобы получить горизонтальный список-меню, как у меня в начале поста, потребуется немного усложнить стили.

CSS: Горизонтальное меню - список


.listMenu {
margin:0; padding:0;
list-style-type:none;
float:right;
}
.listMenu li {
font-family: Georgia, Times, serif;
display:inline;
padding:0px 4px;
}
.listMenu li a {
color:#000;
text-decoration:none;
}
.listMenu li a:hover {
color:#000;
text-decoration:none;
border-bottom:3px solid #C61A1A;
}

На этом краткий экскурс по спискам закончен :)
Читать дальше »

CSS полупрозрачность изображения

.rb
Из недавнего опыта применения CSS. Полупрозрачность изображения при наведении указателя мыши. Может пригодиться, например, если нужно «дёшево и сердито» сделать подсветку графического меню или кнопки.

Код HTML:


<div class="hover_image">
<a href="http://dotrb.blogspot.com">
<img src="путь к изображению" style="width:88px; height:31px;" />
</a>
</div>

В примере будем использовать псевдо класс hover.

Стили CSS:


.hover_image a:hover img {
opacity:.75;
filter: alpha(opacity=75); /* IE */
-moz-opacity: 0.75; /* Firefox */
}

Читать дальше »

CSS-фикс для Internet Explorer

В одном из предыдущих постов, я приводил решение проблемы min-height для IE. Кстати, тот же самый прием прекрасно работает как для min-height, так и для max-height, min-width, max-width.

В том случае фикс был основан на использовании команды !important. Дело в том, что Internet Explorer до версии 6 включительно её не понимает.

CSS:

div.diff-width {
width: 256px !important;
width: 250px;
}

HTML:

<div class="diff-width">
Internet Explorer отобразит это иначе ;).
</div>

Internet Explorer отобразит блок длиной 250 пикселей вместо положенных 256. Т.к. для браузеров, нормально поддерживающих спецификацию, инструкция с !important будет более важной, а для IE нет.
Читать дальше »

среда, 19 ноября 2008 г.

CSS замена input[type="text"] в Internet Explorer

Internet Explorer 6 не понимает селектор input[type="text"]. Однако можно воспользоваться expression (существует еще со времён IE 5).
input[type="text"] {width: 120px;}
/* Правило для Internet Explorer */
input { width:expression(this.type=='text' ? '120px' : ''); }


Читать дальше »

понедельник, 17 ноября 2008 г.

XSLT вывод элементов в группах

Довольно давно сталкивался с задачкой как в XSLT сделать вывод элементов коллекции в группах по X элементов. Решил поделиться решением :).

Например, есть магазин (@store) и в нём товары (@items). Нужно с помощью XSLT выводить их в 2, 3 или 4 колонки.
@store = Store.find(params[:id])
@items = @store.items

Вот так я генерирую XML

Фрагмент файла index.rxml


# Store items
xml.tag!("item-list") do
@items.each do |item|
xml.tag!("item", :id => item.id) do
xml.tag! "name" do
xml << (link_to truncate(item.name, 20), :controller => "store", :action => "item", :id => item.id)
end
xml.tag! "description", truncate(item.description, 36)
xml.tag! "price", item.price
end
end
end


В файле XSLT задаю параметр, в котором будет задаваться размер группы <xsl:param name="group-size" select="'3'" />, чтобы легче в-последствии было его изменять.

А примерно вот так выглядит файл XSLT трансформации.

Фрагмент файла index.xsl


<xsl:param name="group-size" select="'3'" />

...

<xsl:apply-templates select="//item-list" />

<xsl:template match="item-list">
<table class="item-gallery">
<xsl:apply-templates select="item[position() mod $group-size = 1]" mode="row" />
</table>
</xsl:template>

<!-- Строка -->
<xsl:template match="item" mode="row">
<tr>
<xsl:apply-templates select=". | following-sibling::item[position() &lt; $group-size]" />
</tr>
</xsl:template>

<!-- Ячейка -->
<xsl:template match="item">
<td>
<table border="0" cellpadding="0" cellspacing="0">
<tr><td align="left" colspan="2"><strong><xsl:copy-of select="item-name/*" /></strong></td></tr>
<tr><td align="left" colspan="2"><xsl:value-of select="item-description" /></td></tr>
<tr><td align="left"><strong>price:</strong></td><td align="right"><xsl:value-of select="item-price" /></td></tr>
</table>
</td>
</xsl:template>

Вуа-ля! Элементы выводятся в строки по 3.
Читать дальше »

Как скрыть правило CSS от IE

Часто возникает задача скрыть правило CSS от обработки браузером. В случае с Internet Explorer 6 и более ранними версиями прекрасно срабатывал трюк с дочерними селекторами.

Скрыть правило CSS от IE 6


html>body .foo {Скрытый CSS;}

Теперь Internet Explorer 7 понимает дочерние селекторы и поэтому CSS-трюк немного усложняется :)

Скрыть правило CSS от IE 7


html>/**/body .foo {Скрытый CSS;}

Читать дальше »

воскресенье, 16 ноября 2008 г.

Черепичные фоны для веб

Небольшой ресурс с набором из черепичных (бесшовных) фонов для web: Squidfingers / Patterns. Можно бесплатно скачать и использовать как фоны собственных веб-страниц.
набор черепичных веб-фонов
Читать дальше »

CSS: дочерние, соседские селекторы и псевдо классы в IE7

Эти команды CSS наконец-то понимает Internet Explorer 7

Потомки


Допустим, у нас есть следующий HTML:
<div><p><span>Текст сообщения</span></p></div>

В этом примере <p> является "сыном" (прямым потомком) <div>, а <span> -- "внуком" <div>. Мы можем сделать текст элемента <span> красным, используя следующее правило CSS:
div span {color: red;}

Это означает, что содержимое любого элемента <span>, расположенного внутри элемента <div> будет красным. Этот <span> может быть прямым потомком ("сыном"), или непрямым потомком ("внуком", "правнуком" и т.д.) элемента <div>.

Если мы используем следующее правило CSS:
div>span {color: red;}

Текст внутри <span> не будет красным. Так как это правило озачает: <span>, являющийся прямым потомком <div>. А в нашем примере <span> является "внуком" <div>.

Соседи


Теперь IE7 понимает еще и "соседские" селекторы.
blockquote+p {margin-top: 0;}

Это CSS правило означает, что параграф, следующий сразу за цитатой, не имеет верхнего отступа.

Еще один хороший пример использования соседского селектора можно применить к горизонтальным спискам.
li+li {border-left: 1px solid black;}

Это правило означает, что каждый <li>(элемент списка), следующий за другим <li> (т.е. все, кроме первого) будет иметь левый бордюр.

Псевдо-класс First-child


Если вам нужно выделить первый элемент (первого потомка) родительского элемента, используйте псевдокласс first-child. Например, чтобы первый параграф внутри некой области с id="content" имел нулевой верхний отступ, используйте правило CSS:
#content p:first-child {margin-top: 0;}


Источник: New CSS commands for Internet Explorer 7
Читать дальше »

CSS: подчеркивание ссылки другим цветом

Довольно старый трюк, основанный на вложенных элементах HTML, задающий подчеркивание ссылки цветом, отличным от цвета самой ссылки.

Создадим CSS классы для ссылки, подсвеченной ссылки и вложенного элемента:

CSS: стили


/* CSS-класс для ссылки */
a.underlined {
color: #C61C1C;
text-decoration: none;
}
/* CSS-класс для подсвеченной ссылки */
a.underlined:hover {
color: #C61C1C;
text-decoration: underline;
}
/* CSS-класс для вложенного элемента */
.nested {
color: #3357B6;
}

HTML: код HTML для ссылки с вложенным элементом


<a class="underlined" href="http://dotrb.blogspot.com/">
<span class="nested">Это ссылка</span>
</a>


И вот, что в итоге должно получиться:
Это ссылка
Читать дальше »

суббота, 15 ноября 2008 г.

Скриншот веб-страницы полностью - 2: Firefox addon

Fireshot: дополнение для FirefoxВ догонку к ранее упомянутому еще одно расширение Firefox для снимков полных веб-страниц. Лично мне понравилось тем, что снимки можно «автоматом» отправлять на удаленный сервер (регистрация не требуется). В web-разработке весьма полезно.

FireShot - это дополнение к обозревателю Mozilla Firefox, которое позволяет создавать скриншоты открываемых вами страниц.
В отличие от других средств подобного рода, это дополнение предоставляет в распоряжение пользователя целый ряд инструментов для редактирования скриншота и добавления графических и текстовых аннотаций. Подобная функциональность будет полезна для веб-разработчиков, тестеров и редакторов.
Скриншоты могут быть загружены на сервер изображений, сохранены на диске (в форматах PNG, GIF, JPEG, BMP), распечатаны, скопированы в буфер обмена, отправлены по электронной почте или экспортированы во внешний редактор для последующей обработки.


Качать отсюда: FireShot

P.S. Есть это дополнение и для Internet Explorer (качать с сайта разработчика)
Читать дальше »

Удаление рамок изображений в Blogger

Как удалить рамки изображений в Blogger?
У меня, например, для изображений внутри блоков сообщений определены следующие стили.

CSS: Изображение с рамкой и отступом


.post img {
padding:4px;
border:1px solid $bordercolor;
}

Что трансформируется в следующее:
.post img {
padding:4px;
border:1px solid #E3635C;
}

То есть: внутри блока сообщения все изображения отображаются с отступом 4 пикселя «внутрь» и рамкой цвета, заданного в разделе «Шрифты и Цвета» как Цвет рамки.

И большую часть времени меня это устраивает ;). Но иногда изображение выглядит заметно лучше без рамки и прочих «выкрутасов».

Логотип Ruby в оформлении рамкойЛоготип Ruby без рамкиТак выглядит логотип Ruby с бордюром и без него, соответственно.

Чтобы избавиться от бордюра вокруг изображений, существует множество способов. Лично я, поскольку «безбордюрные» картинки мне нужны лишь время от времени, просто добавил еще один CSS-класс для изображений, у которых рамка мне не нужна. И назвал этот класс noborder.

CSS: Изображение без рамки и отступа


.post img.noborder {
border-width: 0px;
}


И добавил этот код CSS в шаблон Blogger. Теперь прикрепленному изображению, где мне хочется избавиться от бордюра я просто присваиваю class="noborder". Например:
<img class="noborder" style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 100px; height: 100px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv88kwFA4oy1QDYq-LE1b3i1Wxz1rTOSeB7ZOli4d5vmMbk7kh_sNvDMSWCeIr46jdecPR7durVq06r-pqN-z5SwhWGUEMIBshhILnpsVPpbdY5A3TQTHq5eXc3PtRhSE-8WXaA-OIwzwH/s400/Ruby_logo.gif" border="0" alt="Логотип Ruby без рамки" id="BLOGGER_PHOTO_ID_5268639454841268082" />

Читать дальше »

Снимок всей веб-страницы: дополнение Firefox

снимок веб-страницы целикомУстановил дополнение для Firefox, позволяющее буквально парой кликов делать снимок (скриншот) всей страницы в браузере. Как всегда понадобилось по работе :). Весьма полезная тулза, доложу я вам :). Изображения выглядят примерно как на прикреплённой иллюстрации (изображение уменьшено).

Screengrab сохраняет полные web-страницы как изображения.

Это дополнение сохраняет то, что вы видите в окне (видимую область), страницу целиком, выделенное или отдельный фрейм... В-основном оно предназначено для сохранения веб-страниц как изображений.

Простое, удобное в использовании дополнение, может сохранять снимки страниц в указанную директорию или копировать в буфер обмена.

Скачать дополнение для Firefox можно сдесь: Screengrab!
Читать дальше »

среда, 12 ноября 2008 г.

Фон для страницы Blogger

Как добавить фон на страницу Blogger?
Во-первых: создайте фоновое изображение. Можете, например использовать инструмент для создания фонов для web.
Далее: Загрузите фоновое изображение в свой альбом Picasa. Не волнуйтесь! Если у вас есть аккаунт в Blogger, то хотя бы один альбом Picasa у вас точно есть :).
И финальный штрих: Откройте редактор шаблонов Blogger (Макет - Изменить HTML) и добавьте CSS-правило для элемента body. Примерно так:
body {
background: fixed #FFF url('https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPm4Tr8OcRPpFMqKSjEJYgimB8h5h_EAOJg0r0yahFduARoLwVmQhzKJHxFdNTVSvb9sXUbMSaEoNZaeJ2E4pMW1zEYYTYxrc-M6hTcE-nPydcnIhv7oCi9yi9fnqPuhO6lEhpdsQNtKdh/');
}

Сохраните шаблон
Читать дальше »

Генератор фонов онлайн

Решил сделать фон для страницы. Нашел хороший инструмент для этой цели -- онлайн-генератор фонов. Создание оригинального фона для web-страницы занимает не более нескольких минут. Весьма и весьма полезная тулза :).
генератор фонов для веб-страниц

Читать дальше »

CSS: удаление обводки активной ссылки в Firefox

У Firefox есть такая забавная черта -- в дополнение ко всему подсвечивать активную ссылку пунктиром. Не то, чтобы это сильно напрягало, но смотрится неаккуратно.
Активная ссылка в Firefox подсвечивается пунктиром
Удалить подсветку активных ссылок поможет небольшое CSS-правило:
a:active {
outline: none;
}

И еще стоит можно создать такое же правило для псевдокласса :focus. В итоге у меня CSS для удаления пунктирной обводки в Firefox выглядел так:
a:active, a:focus {
outline: none;
}

Upd: Тем не менее не рекомендую вам задавать это правило для псевдокласса :focus. Как верно заметил анонимный комментатор, судя по всему – знаток «основ юзабилити интерфейсов» и владелец поломанной мыши: это сделано для того, чтобы можно было ходить по странице без мышки - с помощью клавиши Tab. Например, если у пользователя поломалась мышка, или (не дай бог конечно) правая рука.

Если вам все-таки хочется избавиться от рамки, позаботьтесь о пользователях, обозначив выделенные ссылки каким-нибудь другим способом. Например – цветом фона:

a:focus {
outline: none;
background-color: #FEFF9F;
}

Лично я это правило просто исключил. Но окончательный выбор по-прежнему за вами.


Читать дальше »

Использование CDATA в Ruby on Rails

В одном из предыдущих постов я рассказывал о том, что такое CDATA и для чего она нужна. Теперь приведу пару примеров использования CDATA в XML, сваренном на Ruby on Rails.

Если у вас есть некоторый текст, который не должен быть проанализирован XML-парсером, просто определяем его как CDATA соответствующей командой cdata! или cdata_section. Более того, в CDATA можно включать и partials.

Пример с cdata!


xml.cdata!("Этот текст не будет проанализирован XML-парсером")
#=> <![CDATA[Этот текст не будет проанализирован XML-парсером]]>

Пример с cdata_section


cdata_section("<Это бля не тег!>")
# => <![CDATA[<Это бля не тег!>]]>

Ну и как определять рельсовые partials как CDATA.

Пример с partial


xml.cdata!(
render( :partial => "javascript" )
)

Читать дальше »

вторник, 11 ноября 2008 г.

file_column и ImageMagick в XSLT-шаблонах

Решил предоставить пользователю выбор размеров изображении в шаблоне XSLT.

Исходные: К любому сообщению пользователь может прикрепить одно изображение. Само изображение хранится в разных версиях (используем file_column + ImageMagick). И вот и решил я: раз уж юзер может использовать собственные XSLT-шаблоны, нужно дать ему возможность выбирать и размеры изображений (версию).
Вот примерно так у меня хранятся изображения.

Модель image.rb


class Image < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
VALID_EXTENSIONS = ["gif", "jpeg", "jpg", "png"]
file_column :name,
:magick => {:versions => {
:pic => {:crop => "1:1", :size => "33x33!", :attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }},
:mini => {:crop => "1:1", :size => "50x50!", :attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }},
:middle => {:size => "500x375>",:attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }},
:thumb => {:crop => "148:111", :size => "148x111!", :attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }}
}
}
validates_file_format_of :name, :in => ["gif", "png", "jpg", "GIF", "PNG", "JPG"]
end


Модель post.rb


class Post < ActiveRecord::Base
...
has_one :image, :as => :imageable, :dependent => :destroy
...
end

Ну это так... были вводные данные. Теперь перейдём непосредственно к XML/XSLT.

XML: blog.rxml


xml.tag!("posts") do
@posts.each do |post|
xml.tag!("post", :id => post.id){
xml.tag!("title") do
xml << link_to(post.title, :controller => "blog", :action => "post", :id => post.id)
end
xml.tag!( "created_at", post.created_at.strftime("%b %d, %Y") )
if @image = post.image
xml.tag!("image"){
xml.tag!("src-wide", url_for_file_column("image", "name", "wide") )
xml.tag!("src-thumb", url_for_file_column("image", "name", "thumb") )
xml.tag!("src-middle", url_for_file_column("image", "name", "middle") )
}
end #image
xml.message(post.message)
}
end
end

Ну и, собственно XSLT-темплейт

XSLT: blog.xsl


<xsl:template match="posts">
<xsl:apply-templates select="post" />
</xsl:template>

<xsl:template match="post">
<div class="blog-post" id="blog-post{@id}">
<h2><xsl:copy-of select="title/*" /></h2>
<span class="highcolor2"><xsl:value-of select="created_at" /></span><br />
<div class="blog-body">
<xsl:apply-templates select="image" />
<p><xsl:value-of select="message" /></p>
</div>
</div>
</xsl:template>

<xsl:template match="post/image">
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of select="src-thumb" />
</xsl:attribute>
<xsl:attribute name="class">thumb</xsl:attribute>
</xsl:element>
</xsl:template>

Вуа-ля! Теперь если пользователь захочет отображать изображения другого размера, ему просто нужно будет заменить <xsl:value-of select="src-thumb" /> например на <xsl:value-of select="src-middle" />.
Читать дальше »

XML термин CDATA

Элемент CDATA содержит в себе текстовые данные, которые не должны быть проанализированы XML-парсером.


Дополнение: по-умолчанию, парсер воспринимает их как PCDATA.


Такие символы как "<" и "&", содержащиеся в тексте, вызовут ошибку XML.


Символ "<" XML-парсер интерпретирует как начало нового элемента. А символ "&" – как начало сущности.


Некоторые текстовые данные, например JavaScript, могут содержать множество символов "<" или "&". Чтобы избежать ошибок, такие блоки должны быть определены как CDATA.


Всё внутри секции CDATA игнорируется XML-парсером.


Секция CDATA начинается с "<![CDATA[" и заканчивается "]]>".


Пример использования CDATA


Читать дальше »

понедельник, 10 ноября 2008 г.

Найти родительский элемент javascript

Не моё, нашлось в закладках. Не так давно по работе понадобилось, но когда нашел, додумался до более элегантного в той ситуации решения. Добавляю, чтоб не потерялось :).

Итак, задача: с помощью javascript найти родительский элемент внедренного скрипта.
<span><script type="text/javascript" src="script.js"></span>

Собственно, получить окружающий элемент span.

Был предложен такой способ:

Код javascript


function getSCRIPTParent(src) {
var parent = null;
var scripts;
var i = 0;
var end = 0;
if (getSCRIPTParent.isSupported) {
scripts = document.getElementsByTagName('script');
for (i, end = scripts.length; i < end; i++) {
if (scripts[i].src.indexOf(src) > -1) {
parent = scripts[i].parentNode;
}
}
}
return parent;
}
getSCRIPTParent.isSupported = document.getElementsByTagName ? true : false;

HTML


<span><script type="text/javascript" src="function_lib.js"></script></span>

Как применять (javascript)


var scriptParent = getSCRIPTParent("function_lib.js");

alert(scriptParent);

Копирайты: Finding a script's parent element
Читать дальше »

воскресенье, 9 ноября 2008 г.

CSS: Заметки на полях

В этом посте я опишу как в Blogger размещать ремарки (примечания, заметки) на полях документа. В редакторе шаблонов Blogger добавьте новый CSS-класс "remark":

в этой статье рассказывается, как с помощью CSS создавать заметки на полях
.remark {
font: normal normal 100% Georgia, Times, serif;
color: #1A4676;
width:150px;
border-top:1px dotted #E3635C;
float:left;
position:absolute;
margin-left:-155px;
text-align:right;
}

Сохраните шаблон.

Напишите новое сообщение и добавьте пометку к тексту прямо в тексте поста.
<div class="remark">В этой статье рассказывается,
как с помощью CSS создавать
<a href="http://dotrb.blogspot.com/2008/11/css-remarks-in-margins.html">заметки на полях</a>.</div>
Читать дальше »

Цитаты в Blogger с помощью CSS


Красиво оформить цитаты в блоггере можно при помощи небольших манипуляций с CSS. Этот пример для псевдокласса :first-letter. Вот что должно получиться:
Улучшить водку можно единственным способом -- увеличением объёма бутылки. Все остальные выкрутасы -- опять же замануха для лохов, умеющих читать.
А. Кочергин

Для выделения цитат Blogger использует тег blockquote. Вот его мы немножко и приукрасим с помощью CSS.

Откройте редактор шаблонов: Настроить - Макет - Изменить HTML и найдите в нём CSS-правило .post blockquote и подкорректируйте его примерно так:
.post blockquote {
display:block; width:400px; line-height:normal; letter-spacing:1px;
font-family: times new roman, serif; font-size:16px;
color:#000; border:1px solid #D3D3CF;
padding:5px; margin:2em auto;
}

.post blockquote:first-letter {
font-size:50px; color:#E3635C; font-weight:bold;
float:left; height:34px; line-height:34px;
margin-top:2px; margin-right:1px;
}

* html .post blockquote:first-letter {
margin-right:-2px; margin-top:3px;
}

Сохраните шаблон.

Теперь создайте новый пост, и напишите в нём цитату. Да хоть вот эту:
<blockquote>Улучшить водку можно единственным способом --
увеличением объёма бутылки. Все остальные выкрутасы -- опять же замануха для лохов, умеющих читать.<br />
А. Кочергин</blockquote>

Опубликуйте сообщение.

Способ подмотрен на CSSplay
Читать дальше »

суббота, 8 ноября 2008 г.

DoS уязвимость в REXML

Найдена DoS уязвимость в библиотеке REXML, включенной в стандартную библиотеку Ruby. Так называемая "XML entity explosion" техника атаки может применяться для удаленного отключения любого приложения, парсящего пользовательский XML с использованием REXML.

Большинство Rails-приложений будут уязвимы, поскольку Rails парсит XML предоставляемый пользователем, используя REXML по умолчанию.

Атакующий может вызвать отказ от обслуживания (DoS) заставив REXML парсить документ, содержащий рекурсивно вложенные сущности, например:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE member [
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
<!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">

<!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
<!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">

<!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
<!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">

<!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
]>
<member>
&a;
</member>

Подробнее на английском: DoS vulnerability in REXML
Читать дальше »

Непростое слово entity

Пока шерстил интернет в поисках решения проблемы с ENTITY наткнулся на забавную заметку в архивах xmlhack.ru.
Когда речь идёт об XML, слово entity переводится как «сущность». Но недавно нащёлся ещё один как бы перевод. С bash.org.ru:

Знаете ли вы, что всякий набравший английское слово entity (сущность) по ошибке в русской раскладке, будет немедленно утешен? :-)

Можете попробовать:
Читать дальше »

DOCTYPE ENTITY средствами ruby-xml

Была задача: в генерируемом рельсами XML получить нечто похожее:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE body [
<!ENTITY reg "&#174;">
<!ENTITY mdash "&#8212;">
<!ENTITY nbsp "&#160;">
<!ENTITY ldquo "&#8220;">
<!ENTITY rdquo "&#8221;">
<!ENTITY pound "&#163;">
<!ENTITY trade "&#8482;">
<!ENTITY euro "&#8364;">
<!ENTITY yen "&#165;">
<!ENTITY copy "&#169;">
]>
...

И поскольку, для генерации XML я использую рельсовый RXML билдер, то и выводить надо было rails-методами. Что такое xml.instruct! и как им пользоваться, я давно знаю, но вот с этими entities была и самая проблема.

Нашел в классе Builder::XmlMarkup метод declare! а хули толку? Там настолько "содержательный" пример применения, что хотелось пристрелить разработчиков документации. Пришлось познать, что есть такое Class: Proc в Ruby.

Собственно, вот что в итоге получилось.

XML DOCTYPE ENTITY средствами ruby on rails (layout.rxml)



xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"

entities = {:nbsp => "&#160;", :copy => "&#169;", :reg => "&#174;", :trade => "&#8482;", :mdash => "&#8212;", :ldquo => "&#8220;",
:rdquo => "&#8221;", :pound => "&#163;", :yen => "&#165;", :euro => "&#8364;"}

xml.declare! :DOCTYPE, "body".intern do |x|
entities.each do |key, value|
x.declare! :ENTITY, "#{key}".intern, "#{value}"
end
end


Пользуйтесь! Не забывайте говорить «спасибо» ;) или «thanks» -- кто как приучен :).
Читать дальше »

пятница, 7 ноября 2008 г.

min-height для Internet Explorer

Нашел прекрасное решение проблемы неработающего min-height в Internet Explorer. По утверждению автора работает в IE6, Mozilla/Firefox/Gecko, Opera 7.x+, Safari1.2.

CSS: min-height с инструкцией !important


.minheight100{
border:1px solid #C61A1A;
min-height:100px;
height:auto !important;
height:100px;
}

<div class="minheight100">
<em>Хуже водки -- лучше нет</em><br />
//В. Черномырдин
</div>

Пример:


Хуже водки -- лучше нет
//В. Черномырдин


Другие решения проблемы min-height в Internet Explorer (IE) смотрите в рубрике «Прочитать полностью» :)

IE-хак с underscore


 min-height: 200px;
_height: 200px; /* хак для IE */

comment-hack для IE


/* for understanding browsers */
.container {
width:20em;
padding:0.5em;
border:1px solid #000;
min-height:8em;
height:auto;
}
/* for Internet Explorer */
/*\*/
* html .container {
height: 8em;
}
/**/

Решение с помощью выражений


min-width
#block {
min-width:100px;
width:expression(this.width < 100? ‘100px’: this.width);
}
min-height
#block {
min-height:100px;
width:expression(this.height < 100? ‘100px’: this.height);
}

Читать дальше »

четверг, 6 ноября 2008 г.

Подсветка синтаксиса для блога

Многим людям, пишущим технические статьи для Веб часто требуется подсветка синтаксиса в блоках кода на страницах. Желательно, чтобы она была реал-таймовая (javascript) иначе дополнительное "раскрашивание" собственного кода может напрочь загубить всякое желание что-либо писать.

Погуглив по интернету, нашел сравнительно небольшой javascript-модуль, который не страшно втиснуть непосредственно на страницу.

Для начала определим стили для подсветки. Каким шрифтом, цветом будут выводиться комментарии, каким строки, какая будет подсветка синтаксиса для функций.

Правила CSS для подсветки:


/* Syntax Highlighting */
.S{color:green} /*Строки*/
.func{color:blue}/* Юзер-функции синие */
.C{color:orange}/* Комменты оранжевые */
.kwrd{font-weight:bold}/* Ключевые слова полужирные */
.R{color:gray}
.xml{color:red;}


Сам javascript-модуль для подсветки синтаксиса дам подкатом. В uncompressed-виде он довольно объёмный. Вот тут-то мне и пригодится инструмент для конвертации HTML кода.

javascript для подсветки синтаксиса:



<script type="text/javascript">
function syntax(code){
var comments = []; // Тут собираем все каменты
var strings = []; // Тут собираем все строки
var res = []; // Тут собираем все RegExp
var all = { 'C': comments, 'S': strings, 'R': res };
var safe = { '<': '<', '>': '>', '&': '&' };

return code
// Маскируем HTML
.replace(/[<>&]/g, function (m)
{ return safe[m]; })
// Убираем каменты
.replace(/\/\*[\s\S]*\*\//g, function(m)
{ var l=comments.length; comments.push(m); return '~~~C'+l+'~~~'; })
.replace(/([^\\])\/\/[^\n]*\n/g, function(m, f)
{ var l=comments.length; comments.push(m); return f+'~~~C'+l+'~~~'; })
// Убираем regexp
.replace(/\/(\\\/|[^\/\n])*\/[gim]{0,3}/g, function(m)
{ var l=res.length; res.push(m); return '~~~R'+l+'~~~'; })
// Убираем строки
.replace(/([^\\])((?:'(?:\\'|[^'])*')|(?:"(?:\\"|[^"])*"))/g, function(m, f, s)
{ var l=strings.length; strings.push(s); return f+'~~~S'+l+'~~~'; })
// Выделяем ключевые слова
.replace(/(var|function|typeof|new|return|if|for|in|while|break|do|continue|switch|case)([^a-z0-9\$_])/gi,
'<span class="kwrd">$1</span>$2')
// Выделяем скобки
.replace(/(\{|\}|\]|\[|\|)/gi,
'<span class="gly">$1</span>')
// Выделяем имена функций
.replace(/([a-z\_\$][a-z0-9_]*)[\s]*\(/gi,
'<span class="func">$1</span>(')
// Возвращаем на место каменты, строки, RegExp
.replace(/~~~([CSR])(\d+)~~~/g, function(m, t, i)
{ return '<span class="'+t+'">'+all[t][i]+'</span>'; })
// Выставляем переводы строк
.replace(/\n/g,
'<br/>')
// Табуляцию заменяем неразрывными пробелами
.replace(/\t/g,
'&nbsp;&nbsp;');
}
</script>

Скрипт взят отсюда: скрипт подсвечивающий себя сам

Для вызова обработчика вам понадобится примерно следующий код.
Замечание: У меня все вставки кода находятся в тегах <pre>. Если у вас для этого используется, например, другой тег, но с каким-то определенным классом, то вместо getElementsByTagName используйте getElementsByClass.

javascript для вызова обработчика:


<script type="text/javascript">
var els = document.getElementsByTagName('pre');
for (var j=0; j < els.length; j++) {
var elt = (els[j]);
elt.innerHTML = syntax(elt.innerHTML);
}
</script>



Как добавить подсветку синтаксиса в Blogger?

1. CSS. Добавьте приведенные выше CSS-инструкции в ваш шаблон.
Настроить - Макет - Изменить HTML
Если затрудняетесь найти, где у вас в шаблоне расположены CSS-инструкции, просто вставьте перед строкой ]]></b:skin>

2. Добавление первого блока javascript.
Настроить - Макет - Элементы страницы
В самом низу страницы нажмите "Добавить гаджет" и выберите HTML/JavaScript

3. Добавление второго блока javascript. То же самое, что и для первого.
Внимание: блоки (гаджеты) должны располагаться в том же порядке, как они расположены в этом сообщении - "первый" над "вторым".

P.S. Гораздо естественнее было бы их вставить одним блоком или даже прописать непосредственно в шаблоне, но по непонятным причинам Blogger мне этого сделать не позволил. Читать дальше »

Как вставить код HTML в блог

Чтобы вставить HTML код в сообщение блога, чтобы он не интерпретировался как команды HTML, нужно все символы < заменить на &lt;, а символы > на &gt;. Всё это можно проделать в обычном текстовом редакторе. А можно воспользоваться онлайн-конвертором HTML, например Quick Escape.

Чтобы все пробелы в HTML-коде не заменялись одним, вставляйте полученный HTML-код между тегами <pre>Ваш HTML-код</pre>

Кстати, неплохо бы как-то оформить этот самый код. У меня в блоге, например, такое правило CSS для тегов pre.

pre {
margin:0px;
background-color: #F9FAEA;
overflow: auto;
}
Читать дальше »

среда, 5 ноября 2008 г.

Рендер partial .rhtml в .rxml

Для добавления partial .rhtml в .rxml - документ (с последующим отображением его после XSL-трансформации), проделаем следующее:

XML: фрагмент store.rxml


# partial
xml.tag!("store-description"){
xml << render( :partial => "store_description" )
}

Применим правила XSL-трансформации для вывода фрагмента HTML без окружающих тегов.

XSLT: фрагмент store.xsl


<!-- # Render Partial -->
<xsl:apply-templates select="//store-description" />

<xsl:template match="store-description">
<xsl:copy-of select="node()" />
</xsl:template>
Читать дальше »

вторник, 4 ноября 2008 г.

XSLT обход набора элементов

Для обхода элементов коллекции можно использовать <xsl:for-each>, но лично я предпочитаю использовать шаблоны. Т.е. связку
<xsl:apply-templates> и <xsl:template match="">.

Допустим, есть некий магазин @store с определенным набором товаров
@items = @store.items

Фрагмент кода store.rxml:


# Store items
xml.tag!("items") do
@items.each do |item|
xml.tag!("item", :id => item.id) do
xml.tag! "item-name" do
xml << (link_to truncate(item.name, 20), :controller => "store", :action => "item", :id => item.id)
end
xml.tag! "item-description", truncate(item.description, 100)
xml.tag! "item-price", "#{item.currency}#{item.price}"
end
end # items.each
end


Это сгенерирует следующий XML:


<items>
<item id="13">
<item-name><a href="/customstore/item/13">Lucky Number</a></item-name>
<item-description>Navy lucky number 13</item-description>
<item-price>$12.00</item-price>
</item>
<item id="16">
<item-name><a href="/customstore/item/16">Leather ...</a></item-name>
<item-description>Leather is a material created through the tanning of hides and skins of animals</item-description>
<item-price>$17.00</item-price>
</item>
<item id="75">
<item-name><a href="/customstore/item/75">Adobe Photoshop ...</a></item-name>
<item-description>Lorem ipsum dolor sit amet, conse...</item-description>
<item-price>$23.00</item-price>
</item>
</items>


Применим следующие правила XSL-трансформации:


<xsl:apply-templates select="//items" />

<xsl:template match="items">
<xsl:apply-templates select="item" />
</xsl:template>

<xsl:template match="item">
<div class="item" id="item{@id}">
<h2><xsl:copy-of select="item-name/*" /></h2>
<p><xsl:value-of select="item-description" /></p>
<span class="price"><xsl:value-of select="item-price" /></span>
</div>
</xsl:template>


P.S. Для отображения copy-of item-name ссылкой, используем вывод без родительского тега. Читать дальше »