суббота, 20 ноября 2010 г.

[Blogger.com] Скрипт для отображения списка похожих статей — обновленная версия

Новая версия скрипта для отслеживания похожих сообщений блога. Основные изменения:

  • Основная часть скрипта вынесена во внешний файл. Теперь не нужно помещать в шаблон больше двух страниц (10 килобайт) текста скрипта.
  • Добавлен плоский режим без разделения выдачи по ярлыкам.
  • Добавлена возможность сортировать ярлыки по вручную задаваемому приоритету.
  • Реализована возможность игнорировать ярлыки низкого приоритета, если сообщению назначены ярлыки высокого приоритета.

Принцип работы

Скрипт имеет 2 режима работы: с группировкой ссылок на посты по ярлыкам и плоский (общим списком). Принцип работы скрипта в режиме группировки:

  • Берётся список ярлыков текущего поста, из него отбрасываются ярлыки, занесенные в настройках в список игнорируемых.
  • Запрашивается с блога информация о постах, соответствующих оставшимся ярлыкам. (Параметр relposts_queryPostsPerLabel указывает, по сколько постов запрашивать для каждого ярлыка).
  • Полученные посты группируются по ярлыкам с учётом настроек переименования ярлыков.
  • В каждой группе удаляются лишние посты, если их количество превышает указанное в параметре relposts_showPostsPerLabel
  • Каждой группе постов назначается приоритет, заданный в настройках.
  • Группы ссылок на посты показываются на странице. Группы отображаются в порядке их приоритета, заданного в настройках. (Если у двух групп приоритет одинаков, первым показывается группа, идущая раньше по алфавиту.)
  • При показе групп проверяются параметры relposts_showLabels и relposts_prioDelta, и при выполнении соответствующих условий, вывод прекращается. (Подробнее ниже, в описании настроек.)

В плоском режиме скрипт работает иначе:

  • Берётся список ярлыков текущего поста, из него отбрасываются ярлыки, занесенные в настройках в список игнорируемых.
  • Запрашивается с блога информация о постах, соответствующих оставшимся ярлыкам. (Параметр relposts_queryPostsPerLabel указывает, по сколько постов запрашивать для каждого ярлыка).
  • Каждому посту назначается приоритет, равный сумме приоритетов ярлыков, по которым он пересекается с текущим постом. (Т.е. если у текущего поста ярлыки А, Б и В, и некий пост имеет ярлыки А, В и Г, то этот пост получит приритет, равный сумме приоритетов для ярлыков А и В.)
  • Посты сортируются по приоритету.
  • На странице отображаются ссылки на посты. Количество задаётся параметром relposts_showPostsPlainMode.

Настройка и установка

Аналогично изначальной версии скрипта, находим в шаблоне место, куда будем вставлять код. Обычно оно после строки <data:post.body/>.

Пишем туда:

<!--[relposts]-->
<b:if cond='data:blog.pageType == &quot;item&quot;'>
<b:if cond='data:post.labels'>
<div class='relposts'>

 <div id='relpostsdataheader'></div>
 <div id='relpostsdatalisting'></div>

 <script type='text/javascript'>

 // Сюда будем вписывать настройки

 </script>

 <script type='text/javascript'>
 relposts_sourceLabels = []
 <b:loop values='data:posts' var='post'>
  <b:loop values='data:post.labels' var='label'>
   relposts_sourceLabels.push(&quot;<data:label.name/>&quot;);
  </b:loop>
 </b:loop>
 </script>

 <script type='text/javascript' src='http://izhurnalscripts.googlecode.com/svn/trunk/relposts.js'></script>
</div>
</b:if>
</b:if>
<!--[/relposts]-->

Внутри тега script, где написано «Сюда будем вписывать настройки», следует поместить настройки скрипта. Впрочем и без настроек по умолчанию всё работает — можете сохранить шаблон и проверить. :)

Настройки (общие для обоих режимов):

  • relposts_headerPlain — использовать плоский или обычный режим. Значения: true, false.
  • relposts_excludeLabels — список ярлыков, которые следует игнорировать. Значение: массив строк.
  • relposts_queryPostsPerLabel — Количество постов, запрашиваемых для каждого ярлыка с блога. Значение: число.
  • relposts_renameLabels — таблица для переименования ярлыков. Если при переименовании названия 2-х или более ярлыко совпадают, посты этих ярлыков объединяются в выдаче. Значение: ассоциативный массив.
  • relposts_labelPrio — таблица приоритетов ярлыков. Обратите внимание: имена ярлыков даются в таблице в уже переименованном виде. Ярлыки, для которых приоритет не указан в таблице, имеют приоритет 1. Значение: ассоциативный массив.

Настройки, использущиеся в режиме группировки по ярлыкам:

  • relposts_excludeDups — исключать ли повторяющиеся ссылки в разных ярлыках. Значения: true, false.
  • relposts_showPostsPerLabel — сколько максимально постов отображать для каждого ярлыка. Если постов с блога запрошено больше, чем число relposts_showPostsPerLabel, посты выбираются случайным образом. Значение: число.
  • relposts_showLabels — сколько максимально ярлыков отображать. Ярлыки отображаются, начиная с более высокого приоритета, и до тех пор, пока не будет выведено relposts_showLabels ярлыков. Значение: число.
  • relposts_prioDelta — ограничение на разницу приоритетов между ярлыками. Берётся приоритет максимального ярлыка и ярлыки выводятся до тех пор, пока разница между приоритетом следующего ярлыка и приоритетом первого не превысит значение relposts_prioDelta. Значение: число.
  • relposts_header0 — Текст, который будет показан, если похожих постов не найдено. Значение: строка.
  • relposts_header1 — Текст, который будет показан, если найдёны похожие посты только по одному ярлыку. Если в строке есть фрагмент __LABEL__, он заменяется на название ярлыка. Значение: строка.
  • relposts_headerN — Текст, который будет показан, если похожие посты найдены более чем по одному ярлыку. Значение: строка.

Настройки, использущиеся в плоском режиме:

  • relposts_showPostsPlainMode — сколько максимально постов показывать. Посты показываются, начиная с самых приоритетных. Значение: строка.
  • relposts_headerPlain — текст заголовка. Значение: строка.

Значения опций по умолчанию:

relposts_headerN"Похожие статьи:"
relposts_header1"Еще статьи из категории «__LABEL__»:"
relposts_header0""
relposts_headerPlain"Похожие статьи:"
relposts_plainModefalse
relposts_showPostsPlainMode5
relposts_showPostsPerLabel5
relposts_queryPostsPerLabel10
relposts_excludeDupsfalse
relposts_showLabels1000
relposts_excludeLabels[]
relposts_renameLabels{}
relposts_labelPrio{}
relposts_prioDelta10000

Приоритеты ярлыков реализованы не только для указания порядка, в котором будут выводиться ярлыки, но и для того, чтобы иметь возможность прерывать вывод после определённых ярлыков.

Пример настройки. Допустим, у нас есть ярлыки, имеющие максимальный приоритет, и если сообщению назначен один из этих ярлыков, ярлыки более низкого приоритета следует игнорировать. Для определённости возьмём в качестве образца ярлыки из этого блога: javascript и перевод. Выставляем им приоритет, а значение relposts_prioDelta ставим равным 0. Тогда в случае, когда у поста есть какой-либо из этих ярлыков, остальные ярлыки будут игнорироваться:

<script type='text/javascript'>
 var relposts_prioDelta = 0;
 var relposts_labelPrio = {
  'javascript' : 2,
  'перевод' : 2
 };
</script>

вторник, 16 ноября 2010 г.

[Blogger.com] Как сделать, чтобы на разных страницах отдельные элементы блога были разными

Описываю, как сделать, чтобы определённая часть блога имела разный вид на разных страницах/постах/разделах.
Пост написан для по просьбе FUSESOUND. Всяким программистам и прочим гикам типа меня достаточно краткого справочника, а нормальным людям более подробный мануал лишним не будет.

четверг, 11 ноября 2010 г.

[Blogger.com] Реализация карты или оглавления для блога с разбиением на рубрики/категории

Вроде как вступление

Вот и обещанное «нечто удивительное» для blogspot-а — полнофункциональный скрипт для создания оглавления или карты сайта.

Практически каждый, кто завёл блог на blogspot, рано или поздно задаётся вопросом, каким образом на этой платформе можно сделать разделение статей по рубрикам и добавить оглавление. И к сожалению, напрямую Blogger.com такую возможность не поддерживает — всё, что есть в нашем распоряжениии, это лента постов, которым мы можем назначать ярлыки, и возможность фильтровать посты по отдельным ярлыкам.

В этой ситуации, распространённый способ сделать «категории» — использовать вместо них ярлыки, а в качестве карты сайта использовать длинную-длинную выдачу списка сообщений, в которой оставлены только лишь заголовки, а текст сообщений скрыт при помощи CSS. Все эти «улучшения блога» описаны на множестве сайтов, посвященных «хакам для blogspot» — и преподносятся там как невероятное откровение, хотя им примерно столько же лет, сколько самому blogspot-у. (На самом деле, как я уже упоминал, 90% этих сайтов почти целиком содержат переводы с английского и копипаст друг друга, и если вы видели один такой сайт, значит вы видели все. Впрочем, это вполне типично для русской блогосферы вообще, по любой тематике. Реально что-то новое для блогспота можно увидеть, от силы, на 4-х англоязычных блогах.)

Но не всё так печально, как кажется. В нашем распоряжении имеется rss-лента блога и javascript, а значит, приложив каплю терпения, мы можем получить рубрики, оглавления, и вообще что угодно, что можно только получить на снове анализа сообщений из rss. Именно так, без всякой магии, заработал виджет Календарь, и именно так работает скрипт, которому посвящена данная статья.

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

Обзор возможностей

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

  • Считать с блога сообщения по заданным в настройках ярлыкам и сгруппировать их в категории. Например, допустим, у вас блог о растениях, и вы используете ярлыки «Комнатные цветы», «Садовые цветы» и «Плодовые культуры». Вы хотите, чтобы всё, что связано с цветами, отображалось в оглавлении в одной категории, а всё, что связано с ягодами/фруктами, в другой. Тогда в настройках вы задаёте, что «Плодовые культуры» — это отдельная категория, а вот «Комнатные цветы» и «Садовые цветы» следует объединить в категорию «Цветы». Также для каждой категории можно задать описание — дополнительный текст, который будет показан после заголовка категории.
  • Для каждого сообщения отобразить дату, заголовок со ссылкой на сообщение, описание сообщения и картинку. Что именно из этого нужно показывать, а что нет, можно задать в настройках.
  • Автоматически сформировать для каждого сообщения описание на основе начала текста сообщения. В настройках вы можете задать и свои собственные описания для конкретных сообщений.
  • Найти в посте первую картинку и использовать её в качестве иллюстрации. Также есть возможность задать картинку и вручную.
  • Отсортировать сообщения по дате публикации или названию — в прямом или обратном порядке.

пятница, 5 ноября 2010 г.

[всячина] Хроники веб-девелопера: о IE, запятых, PHP и снова о getElementsByClassName

Убил полвечера на отладку скрипта только потому, что у меня нет под рукой компьютера с Windows, и баги в IE мне пришлось «отлаживать» через скриншоты и переписку по электронной почте. При этом еще и отнимая время у человека, не имеющего к программированию ни малейшего отношения.

В итоге, как обычно и бывает с IE, виной всему оказались не мои кривые руки, а альтернативное восприятие действительности разработчиками браузера. Настолько альтернативное, что они уже 10 лет как не могут починить парсер, а в 5-м издании javascript специально для них добавлено особое разъяснение.
Да-да, — запятые — если вы, не ходя по ссылке, догадались, что дело было в запятых, то вы молодец. А я — не молодец, я про них забыл и твердо верил, что как написано в спецификации, так оно и обязано работать.

Попутно узнал о самом коротком определении IE из-под javascript с использованием этого бага. А так же — внезапно — о том, что «многие языки для реализации и массивов, и хэшей используют один и тот же тип данных» (пунктуация цитаты не сохранена — хоть тут дайте запятую поставить нормально). Напомню, что в число «многих языков» входит PHP... и, собственно, никто больше не входит.
PHP разрушает мозг, ну вы в курсе.

Еще выяснилось, что в отдельных случах IE8 таки настаивает на своём и по-прежнему «не поддерживает это свойство или метод». Я наугад потыкал код, но кажется, это привело лишь к тому, что теперь на этом блоге в IE вообще никак не работаёт скрипт дат, а проверить не на чем. Да и чёрт с ним. На следующей неделе доберусь до ноутбука, на котором установлена винда, там и посмотрим, что опять не так с getElementsByClassName.

Ну и самое главное-то чуть не забыл сказать. Мы тут с amateurblogger подумали-подумали, и решили еще что-нибудь радикально улучшить в этом буржуйском блогспоте. Поэтому скоро вас ждёт нечто более удивительное, чем какой-то там календарь. Удивительное будет выходить в свет по частям, по мере готовности частей к релизу.
Stay tuned!

вторник, 2 ноября 2010 г.

[Blogger.com] Примеры стилей для виджета календаря

Примеры оформления виджета календаря при помощи CSS:

<style type='text/css'>

.iacalendar table {
 background-color: #888;
}

.iacalendar table td {
 background-color: #ddd !important;
 text-align: center  !important;
 font-family: Arial !important
}

.iacalendar .wday_cell {
 font-weight: bold !important
}

</style>

<style type='text/css'>

.iacalendar table td {
 text-align: left  !important;
 font-family: Arial !important;
 font-size: 10pt !important;
 color: #ddd !important;
}

.iacalendar .wday_cell, .iacalendar .month_year_cell {
 font-weight: bold !important;
 color: #999 !important;
}

.iacalendar .month_year_cell {
 text-align: center !important;
}

.iacalendar .cell a {
 color: #888 !important;
 text-decoration: none !important;
}

.iacalendar .cell a:hover {
 color: #888 !important;
 text-decoration: underline !important;
}

</style>

<style type='text/css'>

.iacalendar table {
 border: 1px solid #888;
 -webkit-border-radius: 5px;
 -moz-border-radius: 5px;
 border-radius: 5px;
}

.iacalendar table td {
 text-align: center  !important;
 font-family: Arial !important
}

.iacalendar .wday_cell {
 font-weight: bold !important
}

.iacalendar .month_year_cell {
 border-bottom: 1px solid #888;
}
</style>

<style type='text/css'>

.iacalendar table {
 border: 1px solid #888;
}

.iacalendar table td {
 text-align: center !important;
 font-family: Monospace !important
}

.iacalendar .wday_cell {
 font-weight: bold !important
}

.iacalendar .month_year_cell {
 border-bottom: 1px solid #888;
}

.iacalendar .cell a {
 display: block;
 background-color: #ddd;
 text-decoration: none !important;
}

</style>

пятница, 29 октября 2010 г.

[утилиты онлайн] Экранирование строк для JavaScript

Эта утилита позволяет экранировать любой текст для использования в качестве строки-литерала JavaScript или наоборот: преобразовать строку-литерал JavaScript в обычный текст. Можно экранировать спецсимволы JavaScript или все символы за пределами ASCII, а также экранировать тег <script>, поскольку он недопустим внутри кода JavaScript на странице HTML.

четверг, 28 октября 2010 г.

[Blogger.com] Виджет для Blogger: календарь с возможностью просмотра архива блога.

Итак, свершилось. То, о чём все блогеры на blogspot так долго мечтали, глядя на ЖЖ, доступно прямо здесь и сейчас, достаточно лишь нажать одну кнопку в конце этого поста. Идея виджета принадлежит amateurblogger, а её воплощением в коде занимался ваш покорный слуга. Пока другие перепечатывают друг у друга одни и те же скрипты, гаджеты и уловки, мы таки просто сделаем что-нибудь полезное. Это было лирическое вступление, а теперь к делу.

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

Ссылка с даты календаря ведёт на соответствующий пост, если вы в этот день написали только одно сообщение, или же на страницу с кратким содержанием постов, если в тот день было больше одного сообщения. (Если вы не пользуетесь разделением на краткое и полное содержание сообщений, то, разумеется, сообщения будут там показаны целиком.) Кстати, при просмотре страниц сообщений и страниц навигации по блогу, календарь будет показывать не текущий месяц, а тот месяц к которому относятся отображаемые на данной странице сообщения.

[утилиты онлайн] RegExp.escape: Экранирование строки при формировании регулярных выражений в javascript (функция и рабочий пример)

Часто возникает необходимость экранировать строку для использования внутри регулярного выражения в Javascript. Рассмотрим, как это сделать.

[утилиты онлайн] Экранирование спецсимволов html в html entities и обратно

Простая утилита, позволяющая заменять специсимволы html на соответствующие entities и обратно. Заменяет символы больше и меньше, амперсанд, кавычки и апострофы, а также символ новой строки (на тег br). Работает без перезагрузки страницы: просто вставьте текст в верхнюю область ввода и переместите курсор в нижнюю.

Экранирование HTML тегов

Возможность показать часть тегов в тексте «как есть» в HTML не предусмотрена, поэтому сиволы <, > и " приходится заменять специальным обозначением:

вторник, 26 октября 2010 г.

[Blogger.com] Скрипт для отображение списка похожих статей

Для блогспота существует множество реализаций виджета похожих постов, начиная от простого списка ссылок и заканчивая навороченными и стильно оформленными виджетами. Для своего блога я перебрал несколько таких скриптов, но ни один из них меня не устроил по тем или иным причинам. Поэтому, взяв за основу код с hoctro.blogspot.com, я написал свой собственный. Собственно, сам скрипт был написал и опубликован еще полгода назад, но изначальная публикация исчезла вместе с удалённым аккаунтом в ЖЖ.

Что же такого может мой скрипт и чего я не нашел в уже готовых виджетах?
Во-первых, это возможность настраивать заголовок скрипта, чтобы он гармонировал с содержимым вашего блога. Согласитесь, если, например, у вас блог посвящен кулинарии и рецептам, то надпись «Еще похожие статьи на тему "Салаты":» будет выглядеть крайне странно. Гораздо лучше написать что-то вроде «Еще рецепты из рубрики "Cалаты":».

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

В-третьих, я добавил возможность исключать из поиска отдельные ярлыки. На примере кулинарного блога: если, скажем, вы используете ярлык «нет фото», чтобы отметить рецепты, для которых вы еще не добавили фотографию готового блюда, то скорее всего, вам захочется, чтобы такой ярлык игнорировался при показе посетителям списка похожих рецептов.

И в-четвертых, возможность изменять имена ярлыков и объединять несколько ярлыков в один.

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

понедельник, 11 октября 2010 г.

[Blogger.com] Ссылки постраничной навигации

На Blogger стандартная навигация по страницам архива и отдельным сообщениям оригинальностью не блещет. Две стандартные ссылки «Предыдущие» и «Следующие», да ссылка на главную между ними. Помимо того, что это не оригинально, это, в первую очередь, еще и противо-интуитивно и не удобно: совсем не понятно, почему «Предыдущее» ведет на следующую страницу, а «Следующее» — на уже просмотренную. Здесь временна́я направленность противоречит логической. На мой взгляд, гораздо лучше использовать слова «Раньше» и «Позже».

Текст ссылок Blogger берёт из своих внутренних переменных, но нам способа настроить их не предоставляет. Поэтому находим в шаблоне сегмент nextprev и правим наживую.

Было:
<b:includable id='nextprev'>
  <div class='blog-pager' id='blog-pager'>
    <b:if cond='data:newerPageUrl'>
      <span id='blog-pager-newer-link'>
      <a class='blog-pager-newer-link' expr:href='data:newerPageUrl'
      expr:id='data:widget.instanceId + &quot;_blog-pager-newer-link&quot;' 
      expr:title='data:newerPageTitle'><data:newerPageTitle/></a>
      </span>
    </b:if>

    <b:if cond='data:olderPageUrl'>
      <span id='blog-pager-older-link'>
      <a class='blog-pager-older-link' expr:href='data:olderPageUrl' 
      expr:id='data:widget.instanceId + &quot;_blog-pager-older-link&quot;' 
      expr:title='data:olderPageTitle'><data:olderPageTitle/></a>
      </span>
    </b:if>

    <a class='home-link' expr:href='data:blog.homepageUrl'><data:homeMsg/></a>

  </div>
  <div class='clear'/>
</b:includable>
Стало:
<b:includable id='nextprev'>
  <div class='blog-pager' id='blog-pager'>
    <b:if cond='data:newerPageUrl'>
      <span id='blog-pager-newer-link'>
      <a class='blog-pager-newer-link' expr:href='data:newerPageUrl' 
      expr:id='data:widget.instanceId + &quot;_blog-pager-newer-link&quot;' 
      title='Позже'>← Позже</a>
      </span>
    </b:if>

    <b:if cond='data:olderPageUrl'>
      <span id='blog-pager-older-link'>
      <a class='blog-pager-older-link' expr:href='data:olderPageUrl' 
      expr:id='data:widget.instanceId + &quot;_blog-pager-older-link&quot;' 
      title='Раньше'>Раньше →</a>
      </span>
    </b:if>

    <a class='home-link' expr:href='data:blog.homepageUrl'><data:homeMsg/></a>

  </div>
  <div class='clear'/>
</b:includable>

Можно на этом не остановиться и пойти дальше. Например, убрать лишнюю ссылку на главную, предвинуть ближе к друг другу 2 наши ссылки и поместить между ними тире. Итоговый вариант кода:
<b:includable id='nextprev'>
  <div class='blog-pager' id='blog-pager'>
    <b:if cond='data:newerPageUrl'>
      <span id='blog-pager-newer-link'>
      <a class='blog-pager-newer-link' expr:href='data:newerPageUrl' 
      expr:id='data:widget.instanceId + &quot;_blog-pager-newer-link&quot;' 
      title='Позже'>← Позже</a>
      </span>
      <b:if cond='data:olderPageUrl'>
        —
      </b:if>
    </b:if>

    <b:if cond='data:olderPageUrl'>
      <span id='blog-pager-older-link'>
      <a class='blog-pager-older-link' expr:href='data:olderPageUrl' 
      expr:id='data:widget.instanceId + &quot;_blog-pager-older-link&quot;' 
      title='Раньше'>Раньше →</a>
      </span>
    </b:if>
  </div>
  <div class='clear'/>
</b:includable>
И соответствующие правки в CSS:
#blog-pager-newer-link {
  float: none;
  margin-left: 0px;
  display: inline;
 }

#blog-pager-older-link {
  float: none;
  display: inline;
 }

#blog-pager {
  text-align: center;
  font-weight:bold;
 }
Что получилось, можно увидеть внизу любой страницы этого блога.

воскресенье, 10 октября 2010 г.

[блогеру на заметку] Установка, чтение и удаление cookie средствами JavaScript

Методы для работы с cookie из JavaScript:
function setCookie(name, value, expires, path, domain, secure) {
    if (!name || !value) return false;
    var str = name + '=' + encodeURIComponent(value);
    
    if (expires) str += '; expires=' + expires.toGMTString();
    if (path)    str += '; path=' + path;
    if (domain)  str += '; domain=' + domain;
    if (secure)  str += '; secure';
    
    document.cookie = str;
    return true;
}

function getCookie(name) {
    var pattern = "(?:; )?" + name + "=([^;]*);?";
    var regexp  = new RegExp(pattern);
    
    if (regexp.test(document.cookie))
    return decodeURIComponent(RegExp["$1"]);
    
    return false;
}

function deleteCookie(name, path, domain) {
    setCookie(name, null, new Date(0), path, domain);
    return true;
}
Пример использования. Сериализация одномерного массива в cookie:
// Получаем текущее время и дату.
var d = new Date();
// Увеличиваем дату на 6 месяцев.
d.setMonth(d.getMonth() + 6);
// Сохраняем массив current_color в cookie current_color на 6 месяцев.
setCookie('current_color', current_color.join(','), d);
Чтение cookie и десериализация массива:
var color = getCookie('current_color');
if (color) {
    eval('current_color = [' + color + ']');
}

Сервис экранирования спецсимволов онлайн

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

Экранирование спецсимволов HTML и XML

Экранирование символов в строках Javascript

Экранирование символов в регулярных выражениях Javascript

суббота, 9 октября 2010 г.

[блогеру на заметку] CSS-свойство box-shadow + Firefox = эпичные тормоза и лаги

Сегодня обнаружил сайт, на котором Firefox тормозит и лагает вплоть до того, что почти невозможно прокручивать страницу. При этом на соседних вкладках другие сайты ведут себя вполне нормально. (Обычно если Firefox тормозит, то весь целиком.)

Стало любопытно разобраться, в чём проблема. Скрипты в качестве подозреваемого сразу отпадают, поскольку у них алиби NoScript. Сохранил страницу на диск и стал мучить её исходный код. После непродолжительного сеанса научного тыка, основной источник лагов обнаружился в виде CSS-свойства box-shadow. Ну а после исключения еще и свойства border-radius, всё стало совсем шоколадно.
В самом деле, вот обсуждение проблемы на форуме проекта, а вот и соответствующий багрепорт, который висит в багзилле в состоянии UNCONFIRMED с 2008-го года. Да. И, как пишут там в комментариях, в бете 4-й версии баг по-прежнему присутствует. Ведь все силы разработчиков ушли на то, чтобы сплагиатить из Opera большую красную кнопку.

Сайт тот, кстати, слегка подтормаживает и в других браузерах — еще бы, сохранённая копия страницы вместе со всеми скриптами и картинками весит 1.7 мегабайт. (Не знаю, зачем нужно столько скриптов, но, как говорится, хозяин — барин.) Но даже целому взводу JavaScript-кодеров, которые писали все эти скрипты, не под силу так угробить производительность современного компьютера, как это могут сделать разработчики мозиловского движка рендеринга страниц. И победоносное пришествие CSS3 с настоящими тенями и истинными-скруглёнными-углами опять откладывается на неопределённый срок.

Так что, товарищи блогеры, будьте бдительны, проверяйте свои дизайны на совместимость с популярными браузерами и если что, сносите все эти красивости нахрен. Удобство посетителя важнее красивых теней.

понедельник, 4 октября 2010 г.

[советы по настройке] Настройка минимальной ширины табов в Firefox

Как известно, по мере открытия новых вкладок, в Opera размер табов уменьшается практически неограниченно, а в Firefox вместо этого появляются кнопки для прокрутки списка табов. Прокрутка, на мой взгляд, не очень удобна, но всё руки не доходили погуглить и настроить.
Сегодня узнал о существовании параметра, позволяющего задать для Firefox минимальную ширину таба.
Идём в about:config, находим там параметр browser.tabs.tabMinWidth и выставляем нужное значение. По умолчанию стоит 100, я поставил 30. В результате в окне браузера на экране шириной 1280 пикселей помещается 39 вкладок без прокрутки. Более, чем достаточно.

Также у меня стоит аддон Informational Tab, в котором можно настроить показ кнопок закрытия вкладок, которые при малой ширине табов только мешают.

воскресенье, 3 октября 2010 г.

[советы по настройке] Как вдохнуть новую жизнь в Windows XP

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

Folder Size
Добавляет в Проводник колонки с полным размером каталогов, и количеством файлов и подкаталогов.

Fences
Группировка иконок на рабочем столе в контейнеры.

TaskSwitchXP
Замена стандартного механизма переключения окон. Может отображать миниатюры окон в списке Alt-Tab. Среди дополнительных функций присутствует возможность сворачивать окна в трей щелчком правой кнопки мыши на кнопке "Свернуть" в заголовке окна.

Taskbar Shuffle
Позволяет упорядочивать кнопки на панели задач и иконки в лотке. Также имеется возможность использовать альтернативный метод группирования кнопок: кнопки окон одного приложения всегда располагаются на панели рядом, но при этом не объединяются в один выпадающий список.

Start Killer
Скрывает кнопку Пуск.

LClock
Замена стандартным часам в трее плюс удобный календарь.

iColorFolder
Программа позволяет из контекстного меню назначать цветовые метки папкам.

QTAddressBar
Аналог адресной строки Проводника Висты специально для XP.

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

Colours
Программа позволяет рассмотреть под увеличением любой фрагмент экрана и взять образец цвета с нужного пикселя. Есть возможность сохранять цвета в палитрах. Значение цвета можно скопировать в форматах множества программ, начиная от Фотошопа и заканчивая Делфи.
Программа больше не обновляется, но по ссылке можно скачать последний релиз.

Flypapers
Элегантные «липкие» заметки для рабочего стола. Разработчик тот же, что и у Colours.

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

RandomScreensaver
Запуск случайной заставки из выбранного списка.
И пара замечательных скринсейверов: Actual Earth и Actual Moon.

CopyFilenames
Программа добавляет в контекстное меню пункты для копирования имени файла, а также быстрой замены одного файла другим "в два клика".

[утилиты онлайн] Цветовой калькулятор HSL и RGB

Ниже представлен скрипт, реализующий удобную палитру для выбора и запоминания цвета прямо в браузере. Для работы необходимы JavaScript и cookie.

Возможности калькулятора:

  • Получение цвета в RGB и HLS и преобразование цвета между этими цветовыми пространствами.
  • Получение значения цвета в различных форматах: 2 варианта, используемых в HTML и CSS, проценты, десятичное значение, шестнадцатиричные значения для языков Си, Pascal/Delphi и Visual Basic.
  • Запоминание выбранного цвета между запусками цветового калькулятора (сохраняется в cookie браузера).
  • Хранение палитры из 32-х цветов (сохраняется в cookie браузера).

[блогеру на заметку] Динамическое назначение обработчика onclick в Firefox

Чтобы динамически назначить обработчик на onclick (и на остальные эвенты), интуитивно хочется сделать так:
node.onclick = "blabla()";
(И в Opera это даже работает.)

А правильно — вот так:
node.setAttribute("onclick", "blabla()");
Иначе Firefox молчит и ничего не делает.

Наткнулся сегодня на эти грабли. Давно ничего, выходящего за рамки скрипта из пары строк, на JavaScript не писал и позабывал уж всё.

пятница, 1 октября 2010 г.

[советы по настройке] Опции командной строки для Firefox и других продуктов Mozilla

Оглавление
    1. 1. Как использовать опции командной строки
      1. 1.1. Windows
      2. 1.2. Mac OS X
      3. 1.3. Linux
    2. 2. Профиль пользователя
      1. 2.1. -CreateProfile profile_name
      2. 2.2. -CreateProfile "profile_name profile_dir"
      3. 2.3. -ProfileManager или -P
      4. 2.4. -SelectProfile
      5. 2.5. -ProfileWizard
      6. 2.6. -P "profile_name"
      7. 2.7. -profile "/path/to/profile"
      8. 2.8. -no-remote
      9. 2.9. -migration
      10. 2.10. -installer
      11. 2.11. -resetPref preference
      12. 2.12. -override /path/to/override.ini
    3. 3. Браузер
      1. 3.1. -browser
      2. 3.2. -url URL
      3. 3.3. -private
      4. 3.4. -new-tab URL
      5. 3.5. -new-window URL
      6. 3.6. -search term
      7. 3.7. -preferences
      8. 3.8. -setDefaultBrowser
    4. 4. Mail/News
      1. 4.1. -mail
      2. 4.2. -mail mailto_URL
      3. 4.3. -news news_URL
      4. 4.4. -compose message_options
      5. 4.5. -addressbook
      6. 4.6. -options
      7. 4.7. -offline
      8. 4.8. -setDefaultMail
    5. 5. Календарь
      1. 5.1. -calendar
      2. 5.2. -subscribe URL или -url URL
      3. 5.3. -showdate date
    6. 6. Другие компоненты
      1. 6.1. -editor URL или -edit URL
      2. 6.2. -jsconsole
      3. 6.3. -inspector URL
      4. 6.4. -venkman
      5. 6.5. -chat
    7. 7. XULRunner
      1. 7.1. -app /path/to/application.ini
    8. 8. Chrome
      1. 8.1. -chrome chrome_URL
      2. 8.2. -register chrome_URL
    9. 9. Аддоны
      1. 9.1. -install-global-extension /path/to/extension
      2. 9.2. -install-global-theme /path/to/theme
      3. 9.3. -safe-mode
    10. 10. Локаль
      1. 10.1. -UILocale locale
    11. 11. Startup
      1. 11.1. -turbo
      2. 11.2. -nosplash or -quiet
    12. 12. Удалённое управление
      1. 12.1. -remote remote_command
    13. 13. Разное
      1. 13.1. -silent
      2. 13.2. -console
      3. 13.3. -h или -help или -?
      4. 13.4. -v или -version
      5. 13.5. -osint
      6. 13.6. -requestPending
    14. 14. Недокументированные опции
    15. 15. Правила синтаксиса


Опции командной строки для продуктов Mozilla

Как использовать опции командной строки

Следующий пример показывает использование опции командной строки для открытия менеджера профилей в Firefox:

Windows

Выберите Выполнить в меню Пуск. Введите:

firefox -P

Mac OS X

Откройте окно терминала через  Applications > Utilities и введите:

/Applications/Firefox.app/Contents/MacOS
./firefox-bin -P

Linux

Откройте терминал и введите:

cd Firefox installation directory
./firefox -P

Профиль пользователя

-CreateProfile profile_name

Создать новый профиль с именем profile_name, но не запускать приложение. profile_name не должно содержать пробелов.

firefox -CreateProfile JoelUser

-CreateProfile "profile_name profile_dir"

Создать новый профиль с именем profile_name в каталоге profile_dir directory, но не запускать приложение. Обратите мнимание, что profile_name и profile_dir вместе взяты в кавычки. (Не в SeaMonkey1.x)

Примечание: каталог profile_dir обязан отсутствовать, и профиля с указанным именем так же не должно быть.

firefox -CreateProfile "JoelUser c:\internet\moz-profile"

-ProfileManager или -P

Запустить менеджер профилей. В Linux нужно использовать заглавную P, т.к. строчная запускает режим Purify (обнаружение утечек памяти). На других платформах возможно использование любого регистра.

-SelectProfile

Запустить диалог выбора профиля. Только для SeaMonkey1.x

-ProfileWizard

Запустить Profile Wizard. Только для SeaMonkey1.x.

-P "profile_name"

Запустить приложение с указанным профилем.

firefox -P "JoelUser"

-profile "/path/to/profile"

Запустить с профилем из указанного каталога. Только для Firefox, Thunderbird и SeaMonkey2.x.

-no-remote

Разрешить запуск нескольких копий приложения. (Не в SeaMonkey1.x, который поддерживает только MOZ_NO_REMOTE=1).

firefox -no-remote -P "Another Profile"

-migration

Запустить мастер импорта. (Не в SeaMonkey1.x)

-installer

Запустить мастер миграции с Netscape 4.x. Только для SeaMonkey1.x.

-resetPref preference

Сбросить указанную настройку в значение по умолчанию (список настроек указывается через запятую). Только для SeaMonkey1.x.

seamonkey -resetPref browser.startup.homepage

-override /path/to/override.ini

Заргурить указанный файл override.ini, который перекроет параметры файла application.ini ( browser/app/application.ini). Может быть полезно, чтобы подавить запуск мастера миграции при помощи следующего override.ini. Только для Firefox.

[XRE]
EnableProfileMigrator=0

Браузер

-browser

Start with the browser component. Firefox and SeaMonkey only.

-url URL

Открыть указанный URL в новой вкладке или окне, в зависимости от настроек браузера. -url может быть опущено. Только для Firefox и SeaMonkey. Примечание: При открытии нескольких URL, Firefox всегда открывает их на вкладках нового окна.

firefox www.mozilla.com

-private

Запустить Firefox в приватном режиме, вне зависимости от текущих настроек. Только для Firefox 3.6 и выше.

-new-tab URL

Открыть URL в новой вкладке. Только для Firefox и SeaMonkey2.x.

-new-window URL

Открыть URL в новом окне. Только для Firefox и SeaMonkey2.x.

-search term

Поиск term в поисковой системе по умолчанию. Только для Firefox и SeaMonkey2.x.

-preferences

Открыть окно настроек. Только для Firefox.

-setDefaultBrowser

Установить приложение браузером по умолчанию. Только для Firefox.

Mail/News

-mail

Открыть почтовый клиент. Только для Thunderbird и SeaMonkey.

-mail mailto_URL

Открыть почтовый клиент и создать сообщение с заданным адресом получателя.  Только для Thunderbird.

thunderbird -mail mailto:me@isp.net?subject=hi

-news news_URL

Открыть клиент новостей. Если указан news_URL (опциональный), открыть данную группу новостей. Только для Thunderbird и SeaMonkey.

thunderbird -news news://server/group

-compose message_options

Открыть почтовый клиент. См. правила синтаксиса. Только для Thunderbird и SeaMonkey.

thunderbird -compose "to=foo@nowhere.net"

-addressbook

Открыть адресную книгу. Только для Thunderbird и SeaMonkey.

-options

Открыть окно настроек. Только для Thunderbird.

-offline

Запуск в автономном режиме. Только для Thunderbird и SeaMonkey.

-setDefaultMail

Установить приложение почтовым клиентом по умолчанию. Только для Thunderbird.

Календарь

-calendar

Открыть календарь. Только для Sunbird.

-subscribe URL или -url URL

Подписаться на указанный URL. Только для Sunbird.

-showdate date

Открыть планировщик на указанной дате. Только для Sunbird.

sunbird -showdate 08/04/2008

Другие компоненты

-editor URL или -edit URL

Открыть редактор для указанного URL (URL опционально). Только для SeaMonkey.

seamonkey -edit www.mozilla.org

-jsconsole

Запустить приложение с консолью ошибок.

-inspector URL

Открыть инспектор DOM, если он установлен.(URL опционально)

-venkman

Запуск отладчика JavaScript Venkman, если он установлен.

-chat

Открыть клиент IRC ChatZilla, если он установлен.

XULRunner

-app /path/to/application.ini

Запустить новый процесс, открыв указанное XULRunner приложение. Только для Firefox версии 3 и выше.

Chrome

-chrome chrome_URL

Загрузить указанный chrome.

firefox -chrome chrome://inspector/content

-register chrome_URL

Зарегистрировать указанный chrome, но не запускать приложение.

Аддоны

Примечание для Gecko 1.9.2

Опции -install-global-extension и -install-global-themeбыли удалены в версии Gecko 1.9.2 и выше.

-install-global-extension /path/to/extension

Установить указанное расширение в каталог приложения. Необходимы права администратора. (Не в SeaMonkey1.x).

-install-global-theme /path/to/theme

Аналогично для тем. Необходимы права администратора. (Не в SeaMonkey1.x).

Начиная с Firefox 2.0.0.7, использование аргументов -install-global-extension и -install-global-theme ограничено только установкой с локальных и смонтированных по сети дисков. Установка напрямую с network share не поддерживается. [1]

-safe-mode

Запуск приложения без всех расширений. (Не в SeaMonkey1.x)

Локаль

-UILocale locale

Запуск с указанной локалью.

firefox -UILocale en-US

Startup

-turbo

Запуск приложения в режиме Quick Launch. Только для SeaMonkey1.x.

-nosplash or -quiet

Подавить отображение окна-заставки при запуске. Чтобы отобразить заставку, используйте комнаду -splash. Примечание: на некоторых системах заставка отключена по умолчанию. Только для SeaMonkey1.x.

Удалённое управление

-remote remote_command

Выполнить команду remote_command в уже запущенной копии приложения (см. remote control). Примечание: Для SeaMonkey1.x только в системах Unix/Linux.

firefox -remote "openURL(www.mozilla.org, new-tab)"

Разное

-silent

Не открывать окна по умолчанию. Только для Firefox, Thunderbird3.x и SeaMonkey2.x.

-console

Открыть отладочную консоль. Только в Windows.

-h or -help or -?

Вывести список доступных опций командной строки. Обратите внимание, в Windows это работает только в отладочных сборках ( bug 355889 ).

-v or -version

Вывести версию приложения. Обратите внимание, в Windows это работает только в отладочных сборках ( bug 355889 ).

-osint

Tells the application that it is being launched by the OS shell. This should not be specified unless the caller provides all of the functionality provided by the OS shell when launching the application ( bug 384384 ).

-requestPending

Tells the application that there will be a Windows DDE request to open the same url specified on the command line. This should not be specified unless the caller provides all of the functionality provided by the OS shell when launching the application ( bug 354005 ).

Недокументированные опции

  • -print-xpcom-dir
  • -print-xpcom-dirlist
  • -kill
  • -killAll
  • -f
  • -ftimeout
  • -fwait
  • -unsetDefaultMail
  • -foreground
  • GTK options
  • X11 options

Правила синтаксиса

  • Параметры, содержащие пробелы, должны быть заключены в кавычки. Например: "Joel User".
  • Названия опций не зависят от регистра символов.
  • Параметры, за исключением имён профилей не зависят от регистра символов.
  • Пробелы разделяют команды и параметры.
  • Каждая опция сообщения имеет синтаксис поле=значение, например:
    • to=foo@nowhere.net
    • subject=cool page
    • attachment=www.mozilla.org
    • attachment='file:///c:/test.txt'
    • body=check this page
  • Опции сообщения разделяются запятыми, например: "to=foo@nowhere.net,subject=cool page" . Перед или после запятой не должно быть пробелов. Чтобы присвоить несколько значений полю, заключите его в одинарные кавычки, например: "to='foo@nowhere.net,foo@foo.de',subject=cool page" .

Перевод материала с сайта developer.mozilla.org.

[блогеру на заметку] Реализация getElementsByClassName для IE8

Добавил в шаблон блога реализацию метода getElementsByClassName для Internet Explorer, теперь в IE8 нормально отрабатывает скрипт замены дат. В других браузерах, не имеющих поддержки этого метода, код тестировать лень, так как их долей по сравнению с Firefox 3 и IE8 можно спокойно пренебречь.

В отличие от большинства реализаций getElementsByClassName, что попадаются в интернетах, данная встраивается непосредственно в прототипы объектов DOM-дерева и может вызываться как метод любого узла, а не как внешняя функция. Т.е. весь остальной код не придётся переделывать ради совместимости с IE.

<script type='text/javascript'>
    if( typeof document.getElementsByClassName != 'function' ) {
        HTMLDocument.prototype.getElementsByClassName = Element.prototype.getElementsByClassName = function (className) {
            if( !className )
                return [];
            var elements = this.getElementsByTagName('*');
            var list = [];
            var expr = new RegExp( '(^|\\b)' + className + '(\\b|$)' );
            for (var i = 0, length = elements.length; i &lt; length; i++)
                if (expr.test(elements[i].className))
                    list.push(elements[i]);
            return list;
        };
    }
</script>

пятница, 10 сентября 2010 г.

[всячина] Объект не поддерживает это свойство или метод

(Если вы попали сюда в поисках решения проблемы с методом getElementsByClassName в IE, то оно здесь. А ниже — чистый поток сознания.)

Microsoft совершенно зря упускает такую отличную возможность попиарить свой браузер,
Internet Explorer 8 — пробуди в себе телепатию и натренируй интуицию.
Вот какая реклама должна быть у этого браузера.

Сегодня узнал, что в браузере всех времён и народов не работают скрипты, которые я опубликовал вчера и сегодня (первый и второй).

«Средства разработчика», встроенные в этот замечательный продукт, выдали целую гору полезной информации при отладке. А именно:
— Объект не поддерживает это свойство или метод.
Всё. Точка.

Вы... да-да, вот вы, читатель в понтовых очках... что вы там бормочете насчёт указания имени объекта и имени метода? Вы, наверное, какой-нибудь питонист, или, еще хуже, на Ruby пишете? По глазам вижу, привыкли к халяве. Скажите лучше спасибо, что строка с ошибкой указана и даже красиво подсвечена в окошке, чтобы вы в своих очках её хорошо разглядели. Номер символа в строке, правда, указан не верно, но это специально, чтобы не расслаблялись от поблажек.

И я считаю, здесь авторы этой немногословной дзен-программы совершенно зря пошли на поводу у современных быдлопрограммистов, избалованных попсовыми средствами отладки. Настоящий мастер своего дела сам догадается о причине поломки, если что-то пойдёт не так. Незачем сбивать его с толку такими излишними подробностями. Предлагаю избавиться от текстовых сообщений и выдавать всю информацию цифровыми кодами ошибок, как это было в золотую эпоху мейнфреймов.
— 34!
Вот, это благодатное сообщение об ошибке. Ботаник-кун одобряет.

Нет, серьёзно, я года 2 не запускал IE, а уж скрипты в нём не отлаживал и вовсе с древних времён. И, казалось бы, готов был увидеть там что угодно. Однако «Средства разработчика», выдающие сообщения в духе компиляторов из середины 80-х — к такому я оказался не подготовлен.

P.S.
Разумеется, метод getElementsByClassName в IE8 не поддерживается. Ишь чего захотели, черновики не принятого HTML5 поддерживать — этак никаких денег не хватит. Вон индусы из гугла еще 3-й HTML с английского перевести не могут, а вы от бедных майкрософтских аутсорсеров уже 5-й требуете.

Update. Сделал для IE восход солнца вручную скриптовую реализацию getElementsByClassName.

[Blogger.com] Заменяем надпись «Анонимный» на надпись «Гость» в комментариях блога

Увидел на одном форуме вопрос, как можно в Blogger изменить отображаемое имя у анонимных комментариев. Раз такая проблема возникает (в том обсуждении решения так и не нашлось), написал небольшой скрипт, меняющий имя Анонимный на Гость. Надеюсь, кому-нибудь пригодится.

<script type='text/javascript'>
    var authors = document.getElementById('comments').getElementsByClassName('comment-author')
    for (key in authors) {
        var author = authors[key]
        if (author.innerHTML) {
            author.innerHTML = author.innerHTML.replace(/Анонимный/g, 'Гость')
        }
    }
</script>

Данный код необходимо вставить в шаблон перед закрывающим тегом </body>. Протестировано на стандартном шаблоне Simple.

четверг, 9 сентября 2010 г.

[Blogger.com] Улучшенное отображение даты поста в блоге на Blogger

Сегодня добавим еще больше человечности Blogspot-у и научим его словам вчера и сегодня.

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

В отличие от предыдущей задачи с комментариями, которая была решена при помощи шаблонов, в этот раз нам понадобится javascript.

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

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

Итак, сам скрипт:

<script type='text/javascript'>

    var today = new Date();
    var yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1);

    var months = [ 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля',
        'августа', 'сентября', 'октября', 'ноября', 'декабря'];
    var dateheaders = document.getElementById('content-wrapper').getElementsByClassName('date-header')
    for (key in dateheaders) {
        var dateheader = dateheaders[key]
        var innerHTML = dateheader.innerHTML.replace('&amp;nbsp;', ' ').replace('&amp;#160;', ' ');
        var d = innerHTML.match(/,\s+(\d+)\s+(.+?)\s+(\d+)/)
        for (key in months) {
            if (months[key] == d[2]) {
                d[2] = Number(key)
                break;
            }
        }
        if (d[1] == today.getDate() &amp;&amp; d[2] == today.getMonth() &amp;&amp; d[3] == today.getFullYear())
        {
            dateheader.title = innerHTML
            dateheader.innerHTML = 'сегодня'
        }
        else if (d[1] == yesterday.getDate() &amp;&amp; d[2] == yesterday.getMonth() &amp;&amp; d[3] == yesterday.getFullYear())
        {
            dateheader.title = innerHTML
            dateheader.innerHTML = 'вчера'
        }
    }

</script>

Чтобы подключить скрипт к блогу, достаточно скопировать его и вставить перед закрывающим тегом </body>.

Update. Если у вас во всплывающей подсказке будут появляться лишние span-теги, найдите место в шаблоне блога, где выводятся даты:
<h2 class='date-header'><span><data:post.dateHeader/></span></h2>
И уберите бесполезный тег span:
<h2 class='date-header'><data:post.dateHeader/></h2>

[всячина] А пони тоже кони (сносящая крышу детская песенка)

В зоопарке летом жарко,
Там подстрижен ровный луг,
Скачут пони в зоопарке
День за днем, за кругом круг.
В разукрашенной попоне
И с бесстрашием в груди
Там один печальный пони
Вечно скачет впереди.

А пони - тоже кони,
И он грустит в загоне.
Ему б в лихой погоне
Кого-нибудь спасти,
Чтоб друг его счастливый
Потом погладил гриву,
Все это снится пони,
И пони грустит.

Друг-юннат к нему приходит
Покормить и причесать.
Но его не надо вроде
От разбойников спасать.
Он всегда приносит пончик -
Видно, любит от души.
Пони пончиков не хочет,
Хочет подвиг совершить.

А пони - тоже кони,
И он грустит в загоне.
Ему б в лихой погоне
Кого-нибудь спасти,
Чтоб друг его счастливый
Потом погладил гриву,
Все это снится пони,
И пони грустит.

А красавица пантера
Третий день не ест не пьет,
Из соседнего вольера
Пони знаки подает.
Удивив его немножко,
Чувства лучшие задела.
Ведь пантера - тоже кошка,
В нем мустанга разглядела.

Эту песню мне напела моя девушка, когда мы вспоминали «школьные годы чудесные». В моей школе, видимо, эти пони как-то минули нас стороной на уроках музыки, и с этим бессмертным творением я познакомился только сейчас.
Последний куплет — адский ад, убивающий мозги, как капля никотина — пони лошадь.

Справедливости ради, в инете имеется другой вариант этой песни, где укуренный куплет выпилен заменён на вполне адекватный (текст в конце поста). Так что отойдя от первого шока, считаю, это хорошая детская песенка.

Послушать песенку:


В формате mp3 скачать можно тут.


В зоопарке летом жарко,
Там подстрижен ровный луг,
Скачут пони в зоопаре
День за днем, за кругом круг.
В разукрашенной попоне
И с бесстрашием в груди
Там один печальный пони
Вечно скачет впереди.

А пони - тоже кони,
Об этом помнят пони
Ему б в лихой погоне
Кого-нибудь спасти,
Чтоб друг его счастливый
Потом погладил гриву,
Все это снится пони,
И пони грустит.

Юный друг к нему приходит
Покормить и причесать.
Но его не надо вроде
От разбойников спасать.
Он всегда приносит пончик -
Видно, любит от души.
Пони пончиков не хочет,
Хочет подвиг совершить.

А пони - тоже кони,
Об этом помнит пони
Ему б в лихой погоне
Кого-нибудь спасти,
Чтоб друг его счастливый
Потом погладил гриву,
Все это снится пони,
И пони грустит.

А под вечер затихают
в зоопарке голоса
пони спит, во сне вздыхает,
пони снятся чудеса.
Он в поля конём отважным
Вслед за ветром ускакал.
О большом мечтает каждый,
даже тот кто ростом мал.