19.10.2008

Новый iepngfix.htc

Наверняка многие из вас пользовались популярным скриптом iepngfix.htc, который исправляет полупрозрачные PNG в IE 6. Скрипт умеет фиксить как PNG-изображения <img>, так и PNG заданные бекграундом. Основным недостатком этого инструмента было отсутствие поддержки background-position и background-repeat — эти параметры игнорировались. К счастью, Angus Turnbull, автор iepngfix, недавно выпустил новую версию v2.0 Alpha 3, лишенную этого недостатка. В новой версии добавился еще один файл iepngfix_tilebg.js, в котором находится метод IEPNGFix.tileBG.

UPD. Коллега наткнулся на еще одну JS-библиотеку для исправления полупрозрачных PNG в IE 6 — DD_belatedPNG. Также есть поддержка background-position и background-repeat, но подход принципиально другой: вообще отказ от AlphaImageLoader и вместо этого использование VML.

12.10.2008

XSL: применение шаблона с «внутренним» условием

Часто бывает нужно применить шаблон для элемента только если этот элемент (или его содержимое) удовлетворяет некоторому условию. Простой пример: применить шаблон для элемента <Brands> если внутри есть хотя бы один элемент <Brand>. Рассмотрим несколько вариантов как можно сделать эту проверку.

Вариант 1

<xsl:template match="Something">
    <xsl:if test="Brands/Brand">
        <xsl:apply-templates select="Brands"/>
    </xsl:if>
</xsl:template>

<xsl:template match="Brands">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

Неудачное решение, поскольку, написав проверку в шаблоне для <Something>, мы поместили в этот шаблон знание об особенности трансформации <Brands>.

Вариант 2

<xsl:template match="Something">
    <xsl:apply-templates select="Brands[Brand]"/>
</xsl:template>

<xsl:template match="Brands">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

Немного компактнее, но проблема первого варианта осталась.

Вариант 3

<xsl:template match="Something">
    <xsl:apply-templates select="Brands"/>
</xsl:template>

<xsl:template match="Brands">
    <xsl:if test="Brand">
        <h2>Производители</h2>
        <ul>
            <xsl:apply-templates select="Brand"/>
        </ul>
    </xsl:if>
</xsl:template>

Гораздо лучше. Шаблон для <Something> просто вызывает шаблон для <Brands>, не заморачиваясь о внутреннем устройстве <Brands>. Шаблон для <Brands> сам разбирается как трансформировать <Brands>.

Вариант 4

<xsl:template match="Something">
    <xsl:apply-templates select="Brands"/>
</xsl:template>

<xsl:template match="Brands"/>
<xsl:template match="Brands[Brand]">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

Я предпочитаю этот вариант. Он также хорошо работает и в случае с несколькими условиями — вместо громоздкого <xsl:choose> мы получаем компактные шаблончики.

<xsl:template match="Brands"/>

<xsl:template match="Brands[Brand]">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

<xsl:template match="Brands[count(Brand) > 10]">
    <h2>Много производителей</h2>
    <!-- Выводим бренды в три колонки -->
</xsl:template>