Pull to refresh
-3
0
​Василий Пупкинъ @tenshi

User

Send message

Smarty против XSLT

Reading time 5 min
Views 6.2K
Очень распространено заблуждение о том, что xslt — это сплошные тормоза, а smarty — наше всё. Отставим в сторону лаконичность синтаксиса смарти и удобство поддержки xslt, а устремим наш пристальный взор именно на скорость их работы.

Рисовать мы будем нечто чуть более сложное чем «привет мир» — дерево. Это не даст нам использовать копипасту и заставит повторно использовать код для вывода узлов. Количество их пусть будет небольшим — 100 штук.

Поехали!
Total votes 94: ↑50 and ↓44 +6
Comments 323

Внедрение SVG изображений на страницу

Reading time 2 min
Views 23K
В простейшем случае svg-картинка внедряется следующим способом:
<object type="image/svg+xml" data="pucture.svg">
</object>

Это работает везде, кроме ИЕ, который SVG изначально не поддерживает. Для него надо установить следующий плагин:
download.adobe.com/pub/adobe/magic/svgviewer/win/3.x/3.03/en/SVGView.exe

Его следует прописать в аттрибуте codebase. Тогда при заходе на страницу пользователю будет предложено установить его. Пара кликов, перезагрузка страницы, одобрение использования плагина на сайте, и можно наслаждаться поддержкой SVG графики.
вырезанные откровенные сцены! спешите видеть!
Total votes 27: ↑22 and ↓5 +17
Comments 45

Притча о шаблонах

Reading time 8 min
Views 1.8K
 — Здравствуй *с широко развевающейся по лицу улыбкой* дружок.
 — Ваа! *с ярким блеском в широко распахнутых глазах* Тётя Ася приехала!
 — Да, и у меня есть для тебя новая сказка *присела и взяла малыша за руки* хочешь послушать?
 — Конечно! *слегка смутился и отвёл взгляд* Мне тут дядя такие страшные истории рассказывал…
 — Ну, надеюсь моя история тебя не испугает *потрепала его по волосам* Она должна научить тебя мыслить шаблонно.
 — Эээ? *лицо перекосилось от недопонимания* Это как?
 — М… сейчас узнаешь *подмигнула и взяла на ручки* Вот когда тебе нужно вставить переменные в строку — ты как поступишь?
 — Ну… *взял карандаш и чирканул на лежащей рядом бумажке* примерно так:
var query= 'xxx'
var resultCount= 512
var message= 'По запросу <kbd>' + query + '</kbd> найдено страниц: ' + resultCount

 — Ты ничего не забыл? *победоносно подняла голову*
 — Да вроде нет… *уткнулся носом в код, ещё раз внимательно его проверяя*
 — Что, если пользователь введёт… *выдержала многозначительную паузу и добавила*
какого же порева она там добавила?
Total votes 232: ↑157 and ↓75 +82
Comments 164

Оформление кода → Атомы

Reading time 2 min
Views 915
Клиентское приложение принято разделять на 3 основных слоя: данные, поведение и оформление. Для каждого слоя используется свой язык: html, javascript и css, соответственно. Связь между ними осуществляется через некоторые идентификаторы: имена тэгов, классов, идентификаторов. Но к сожалению, в большинстве случаев они сильно завязаны на контекст использования, что усложняет поддержку и рефакторинг.

Несколько примеров:
  1. var user= new User( 'tenshi' )
  2. var isUser= anElement.hasClassName( 'user' )
  3. var container= document.getElementById( 'user' )
Тут мы видим много различных сущностей имеющих одно имя: имя переменной, имя конструктора, имя класса, идентификатор. Что если вы заглянули в исходный код страницы и обнаружили у одного элемента класс 'user', которого там быть недолжно? Из-за того, что имя класса не является для вашего приложения атомарной сущностью (то есть требует дополнительный контекст типа var, new, hasClassName, getElementById, чтобы обрести смысл), поиск по строке «user» выдаст вам гору всякого мусора, который придётся разгребать руками.

как быть? что делать?
Total votes 20: ↑7 and ↓13 -6
Comments 10

Оформление кода → Разделитель вначале

Reading time 3 min
Views 2.1K
Применяется, когда у нас есть набор некоторых выражений, разделённых некоторым коротким разделителем, который нужно представить к несколько строк.

Традиционный египетский способ представления:
  1. var userList= [
  2.     { name: 'Tom', Age: 5, race: 'cat' },
  3.     { name: 'Jerry', Age: 3, race: 'mouse' },
  4.     { name: 'Spike', Age: 11, race: 'dog' }
  5. ]
* This source code was highlighted with Source Code Highlighter.

Обратите внимание, что в конце каждой строчки стоит запятая, кроме последней — там запятой быть не должно. Проблема в том, что при перестановке строчек местами и прочей копипасте ускоряющей процесс написания кода, нужно очень внимательно следить за запятыми, а так как они не навиду, это неизбежно приводит к ошибке.

Представление с разделителем вначале:
  1. var userList=
  2. [  { name: 'Tom', Age: 5, race: 'cat' }
  3. ,  { name: 'Jerry', Age: 3, race: 'mouse' }
  4. ,  { name: 'Spike', Age: 11, race: 'dog' }
  5. ]
* This source code was highlighted with Source Code Highlighter.

что это за хрень?!?
Total votes 62: ↑24 and ↓38 -14
Comments 96

Организация пакетов с помощью css-suki

Reading time 5 min
Views 1.8K
Стили и соответствующие им картинки группируются в однин модуль. Для каждого модуля — отдельная директория. Ссылки к картинкам задаются относительно родительской директории. Например, для модуля «pager» создаётся одноимённая директория, в которую кладётся один или несколько css с произвольным названием (например, с тем же — «pager.css»), рядом с ним картинка «pager-current_bg.png», ссылка к которой выглядит так "../page/pager-current_bg.png". Картинка из примера задаёт фон для элемента содержащего номер текущей страницы в пэйджере. Имена картинок складываются из имени элемента (pager-current, pager-next, pager-prev..), расположения картинки (bg, top, left, top-left, icon..) и модификаторов (hover, active, selected..), разделённых между собой подчёркиванием. Сложный пример: pager-next_icon_hover.png

Группировка в модуль происходит по родству. Например, в модуле «text» могут содержаться стили для стандартных элементов гипертекста (em, strong, q..), в «form» — стили для элементов форм, в «table» — всё, что касается таблиц. Разметка выполняется как описано в статье про независимые элементы.

Бонусом от этих шаманств является высокая степень независимости визуальных модулей друг от друга, что позволяет легко переносить их между проектами и пакетами не заботясь о порядке их подключения. Некоторые модули требуют подключения вначале (например, css-reset) — их можно именовать добавляя в начале цифру (например, «0_reset»).

Как было упомянуто выше, модули собираются в пакеты — простой группировкой по директориям. Пакет конечному пользователю приходит одним файлом. Разработчик же может переключиться в режим загрузки всех css файлов по отдельности.
Читать дальше →
Total votes 25: ↑15 and ↓10 +5
Comments 16

Разметка независимыми элементами

Reading time 3 min
Views 3.4K
Развивая идею вёрстки независимыми блоками мы постепенно придём к вёрстке независимыми модулями, а пока остановимся подробней на сабже…

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

Вёрстка страницы — процесс расположения элементов на странице в соответствии с дизайном.

Вёрстка бывает:
  • Табличная. Страница представляет из себя одну большую таблицу с мелкими ячейками. Каждый элемент занимает несколько смежных ячеек образующих прямоугольную, не пересекающуюся с остальными, область.
  • Блочная. Страница делится на крупные блоки, те на более мелкие, и так далее до нужной степени детализации.
  • Слоёная. Элементы позиционируются абсолютно, независимо от расположения остальных элементов.
Разметка текста — обогащение текста специальными машиночитаемыми условными обозначениями.
Читать дальше →
Total votes 42: ↑19 and ↓23 -4
Comments 34

Независимо перегружаемые свойства

Reading time 7 min
Views 686
Стандартный механизм перегрузки свойств через методы __get и __set весьма не удобен для практического использования, однако с помощью него можно создать удобный dsl для работы со свойствами. Сразу же пример использования (тут и далее используется паттерн адаптивной типизации, с которым рекомендуется предваритильно ознакомиться):

class Title extends ProtoObject {<br>    protected $_text= '';<br>    function set_text( $val ){<br>        return $this->aTitleString( $val );<br>    }<br>    function get_text( $val ){<br>        if( empty( $val ) ) return '[untitled]';<br>        return $val;<br>    }<br><br>    function aTitleString( $val ){<br>        aString( &$val );<br>        if( strlen( $val ) > 255 ) $val= substr( $val, 0, 252 ) . '...';<br>        return $val;<br>    }<br>}<br><br>$title= new Title;<br>$title->text= 123;<br>var_dump( $title->text ); // string(3) "123"<br>var_dump( $title->text( '' )->text() ); // string(10) "[untitled]"<br>echo $title;<br>// Title Object<br>// (<br>//     [_text:protected] =><br>// )

Читать дальше →
Total votes 24: ↑5 and ↓19 -14
Comments 16

Адаптивная типизация

Reading time 3 min
Views 880
Суть сего паттерна заключается в том, чтобы задавать типы значений через накладываемые на них ограничения. И при возможности изменять это значение так, чтобы оно вписывалось в эти ограничения.

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

Многие языки не позволяют определять собственные типы. Некоторые языки это позволяют, но выразительных средств зачастую не хватает. Однако, можно опредлить набор функций, каждая из которых на вход принимает значение и на выходе гарантирует, что возвращённое ею значение удовлетворяет всем ограничениям. При этом она может попытаться преобразовать значение так, чтобы оно соответствовало ограничениям, а если ей это не удаётся — должна бросить исключение.

примеры, примеры, примеры
Total votes 20: ↑8 and ↓12 -4
Comments 18

Аккорды с применением высоких технологий

Reading time 14 min
Views 1.2K
Задача заверстать аппликатуру весьма не тривиальна и от того довольно интересна. Я тоже не устоял перед искушением решить её так как считаю правильным.

Помимо стандартных требований типа кроссбраузерности, масштабираемости, печатаемости и компактности, хотелось бы добиться также и возможности просто тупо скопировать аппликатуру и вставить её, например, в текстовый документ. То есть в текстовом виде аккорд должен иметь примерно следующий вид:

Am
O - - -
O F - -
O - R -
O - M -
O - - -
X - - -


O — открытая струна, X — приглушённая, остальные буквы обозначают пальцы.

ну и порево там дальше..
Total votes 54: ↑40 and ↓14 +26
Comments 146

Препроцессинг CSS на клиенте

Reading time 6 min
Views 2.1K
Представьте, что вы пишете блогохостинг и хотите позволить авторам блогов менять свой дизайн. Картиночки там вставлять, цвета менять, пропорции регулировать… Представили? Если хорошо представили, то уже поняли, что без констант и формул в CSS тут не обойтись.

При блуждании по блогам не хотелось бы грузить все стили заново, что неизбежно при серверном вычислении значений, а хотелось бы грузить лишь минимальную разницу — так называемый скин.

Итого, нам нужно грузить в дополнение к данным страницы: скин с константами и стили с формулами. Только две клиентские технологии позволяют сделать это: JS и XSLT. Однако первую очень любят отключать, а вторую отключать просто нет смысла. Поэтому вынесем CSS в XSLT контейнер, а заодно и не забудем про технологию XHTML-инклудов.

а теперь о том как снималось это порно
Total votes 57: ↑44 and ↓13 +31
Comments 57

XML + CSS = счастье

Reading time 4 min
Views 12K
Возрадуйтесь, дети мои, ибо пришёл я к вам с миром и богатыми дарами. Нет, я не принёс вам того, чего вы не видели. И даже не принёс того, чего вы не имели. От чистого сердца вручаю вам то, что всегда лежало у вас под ногами, но вы не замечали того, брезгливо перешагивая, пробегая мимо по своим, несомненно самым важным, делам.

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

Примеси! Я же знаю, вы так устали без наследования. Приходится внедрять лишние классы в элементы или даже, переходить на тёмную сторону силы — копипастить по чёрному.

Отныне! Ваша душа будет чиста как у младенца. Руки в золоте как у царевичей. Дети послушными и приветливыми.

а теперь приступим к съёмкам порева
Total votes 128: ↑98 and ↓30 +68
Comments 53

Притча о потерянном состоянии

Reading time 5 min
Views 1.3K
— Здра…
— А-а-а!
— Ну ты чего?
— Я вас боюсь!
— Чего это?
— Вы вечно меня унижаете…
— Хех, ну ладно, больше не буду.
— Правда?
— Доо, хочешь конфетку с аяксом?
— Конечно!
— Тада давай, лети к нам в Питер. Вот список авиарейсов на которые есть билеты отсортированный по цене: rasp.yandex.ru/search?cityFrom=Санкт-Петербург&cityTo=Москва
— Эм… что-то вы наврали дяденька — там вообще все рейсы из Москвы в Питер, отсортированные по времени отправления.
— Гм… действительно, не хорошо получилось… а значешь почему?
— Нэ?
— Потому что состояние приложения не отражается на uri. Поэтому каждый раз заходя на эту страницу из закладок, тебе придётся заново устанавливать фильтрацию и сортировку.
— Блоо, как же быть?
а далее самые жёсткие порносцены
Total votes 172: ↑124 and ↓48 +76
Comments 44

Hiqus — HIerarhical QUery String

Reading time 10 min
Views 2.8K
Это формат представления древовидных структур данных в виде одной строки в удобном для человека виде. Является обобщением формата «application/x-www-form-urlencoded» и как следствие — обратно совместим с ним. В основе Hiqus лежит всё тот же принцип представления данных в виде пар «ключ-значение» с той лишь разницей, что ключ может быть составным или пустым.

Данный формат уже используется такими монстрами как Яндекс (http://yandex.ru/yandsearch?date=within&text=hiqus&from_day=28&from_month=4&from_year=2009), Гугл (http://www.google.ru/search?as_q=hiqus&hl=ru&num=10&as_qdr=all) и многими другими, кому требуется передавать иерархические данные в строке запроса. Исключение составляют PHP-сайты, для которых традиционно используется свой, не слишком наглядный формат (пример, навскидку не нашёл, но выглядит он примерно так: ?user%5Bid%5D=123&user%5Bname%5D=Nick).
ох, ну и порево же дальше
Total votes 41: ↑27 and ↓14 +13
Comments 72

Кроссбраузерный text-overflow \(^_^)/

Reading time 5 min
Views 27K
В случае, когда текст не влезает в ширину блока, есть несколько вариантов его визуализации:
  1. Разрешить ему вылезать за пределы блока. В большинстве случаев смотрится весьма косячно.
  2. Обрезать текст по границе блока. То же смотрится некузяво.
  3. Обрезать и нарисовать скроллинг. Это вообще жуть какая-то.
  4. Обрезать и сделать плавное затухание к краю так чтобы места обрезания букв не было видно. Сложно применять в случае неоднородного фона. Приходится вручную прятать затухание, когда текст имеет ширину меньше или равную ширине блока.
  5. Укорачивать текст, вставляя вконце многоточие.
О реализации последней стратегии и пойдёт далее речь...

А теперь долгожданное порево
Total votes 80: ↑59 and ↓21 +38
Comments 55

Притча об автоматическом менеджменте виджетов

Reading time 8 min
Views 674
— Здравствуй…
— А-а-а! Памагите! Убивают! \(0_0)/
— Дружок, спокойно, я свой :-\
— Свои незаметно сзади не подкрадываются! \(@_@)/
— А я динамически добавился В-]
— Э-э-э \(~_~)/
— Ясно, не знаешь, как реагировать на такие ситуации? XD
— Ну… как бы… есть мысли… \(=_=)/
— Покажи-ка свой исходник %-)
— Я… эта… стесняюсь… \(._.)/
— Давай, не боись, я же свой ;-)
— Лаааадно \(-_-)/
<body><br>    <script><br>        $(function(){<br>            $('.c-example').wrapInner( '<span class="wrapper" />' )<br>        })<br>    </script><br>    <div class="c-example">epic</div><br></body>
и снова жёсткое порево
Total votes 40: ↑15 and ↓25 -10
Comments 26

Правильное REST кэширование

Reading time 6 min
Views 5.3K
Пусть мы хотим написать свой хабрахабр с блекджеком и прочими прелестями. Страница статьи у нас стостоит из 3 объёмных блоков:
1. собственно текст статьи. меняется очень редко.
2. дерево комментариев. меняется относительно часто, но со временем всё реже и реже.
3. прямой эфир. небольшой, но меняется очень часто.

Допустим, что страница с этой статьёй доступна по адресу ?article:right.cache
Но внутрь неё мы не будем помещать никакого контента, а вынесем его в отдельные ресурсы, как это обычно делается со скриптами и стилями. Внутри ?article:right.cache будет лишь индекс подключаемых ресурсов с версиями.

?article:right.cache/content/version:123
?article:right.cache/comments/time:2010-12-01
?live/time:2010-12-01
?style:article/version:666
?script:article/version:333

Указание версии позволяет задать для ресурсов жёсткое кэширование. А для индексного файла, наоборот, зададим необходимость проверять при каждом запросе изменился ли он.

Такая организация гарантирует нам, что при появлении новых комментариев не придётся грузить статью заново. И наоборот, при изменении статьи не надо будет перегружать всё дерево комментариев. А уж про то, что из-за часто меняющегося прямого эфира нам не надо по новой грузить весь контент, и заикаться не стоит ;-)

Важно, чтобы поисковики видели ссылки на ресурсы и могли их проиндексировать. Однако, из поиска люди будут приходить на конкретный ресурс и даже на конкретную его версию. Соответственно, ресурс должен определять загружен ли он по прямой ссылке и если это так, то после загрузки клиентскими средствами редиректить на индекс. Если актуальная версия ресурса не изменилась, то он потом будет взят из кэша. Если же изменилась — будет загружена новая версия. Не такая уж страшная беда, на самом деле ;-)

Реализации с использованием фреймов и аякса довольно банальны, так что воспользуемся хтмл-инклудами.
Читать дальше →
Total votes 35: ↑27 and ↓8 +19
Comments 43

Кроссбраузерные HTML инклуды \(^_^)/

Reading time 7 min
Views 6.4K
Пусть у нас есть простенький хтмльчик index1.htm

<!DOCTYPE html><br><html><br>    <head><br>        <title>Xbrowser HTML includes</title><br>        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><br>    </head><br>    <body><br>        <h1>First file</h1><br>    </body><br></html>

Как известно, хтмл поддерживает инклуды только через iframe/object, но с ними не очень удобно работать из яваскрипта.

Можно, конечно, прописать в каждую подключаемую страницу скрипт типа такого

new function(){<br>    var frame= window.frameElement<br>    if( !frame ) return<br>    var parent= frame.parentNode<br>    var body= document.getElementsByTagName( 'body' )[0]<br>    var child;<br>    while( child= body.firstChild ) parent.insertBefore( child, frame )<br>    parent.removeChild( frame )<br>}

Он переносит своё содержимое в родительский документ и удаляет фрейм. Но в случае отключённоо яваскрипта мы получим окошко ифрейма не подстраивающееся под размер содержимого.
А дальше - жёсткое порево
Total votes 66: ↑52 and ↓14 +38
Comments 132

Притча о пропавшем Стэке

Reading time 3 min
Views 950
— Здравствуй, дружок…
— Дяденька, вы снова расскажете мне сказку?
— Конечно! Какой умненький мальчик!
— А про что?
— М… сегодня я расскажу тебе о том, куда пропадают чересчур самостоятельные мальчики вроде тебя…
— Э! Что значит пропадают?
— Вот то и значит… На, держи огнелиса *протянул, держа за хвост, пылающее пламенем животное* Только осторожно — он горячий!
— Ай-ай-ай! Он брыкается!
— Посади на него огненного жука — мигом успокоится.
— Класс! Действует!
— Ато! Теперь скажи ему:
function throwException( ){
    (void 0)()
}
throwException()

А дальше идёт жёсткое разоблачение
Total votes 155: ↑113 and ↓42 +71
Comments 54

Притча о перехвате ошибок

Reading time 4 min
Views 2K
— Здравствуй, дружок. Хочешь, я расскажу тебе сказку? }:-]
— Конечно, дяденька, а какую? *_*
— Я расскажу тебе как делают детей ^_^'
— ого, как интересно! @_@
— Так вот, слушай. Дети появляются вследствие долгого и изнуряющего процесса разной степени нецензурности. Сейчас я поведаю тебе как появился на свет мой сын %-)
— А вы меня с ним познакомите? *о*
— Не торопи события. Обо всём по порядку. Однажды я наваял такой код:
  1. try {
  2.     throw new Error
  3. } catch( e ){
  4.     if( e != false ) throw e
  5. }
А далее идёт жёсткое порно...
Total votes 42: ↑22 and ↓20 +2
Comments 36

Information

Rating
Does not participate
Location
Ян де нова о-ва
Date of birth
Registered
Activity