Показаны сообщения с ярлыком Blogger.com. Показать все сообщения

суббота, 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 можно сделать реально круто выглядящее оглавление — но мне лень.

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

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

  • Считать с блога сообщения по заданным в настройках ярлыкам и сгруппировать их в категории. Например, допустим, у вас блог о растениях, и вы используете ярлыки «ÐšÐ¾Ð¼Ð½Ð°Ñ‚ные цветы», «Ð¡Ð°Ð´Ð¾Ð²Ñ‹Ðµ цветы» и «ÐŸÐ»Ð¾Ð´Ð¾Ð²Ñ‹Ðµ культуры». Ð’Ñ‹ хотите, чтобы всё, что связано с цветами, отображалось в оглавлении в одной категории, а всё, что связано с ягодами/фруктами, в другой. Тогда в настройках вы задаёте, что «ÐŸÐ»Ð¾Ð´Ð¾Ð²Ñ‹Ðµ культуры» — это отдельная категория, а вот «ÐšÐ¾Ð¼Ð½Ð°Ñ‚ные цветы» и «Ð¡Ð°Ð´Ð¾Ð²Ñ‹Ðµ цветы» следует объединить в категорию «Ð¦Ð²ÐµÑ‚Ñ‹». Также для каждой категории можно задать описание — дополнительный текст, который будет показан после заголовка категории.
  • Для каждого сообщения отобразить дату, заголовок со ссылкой на сообщение, описание сообщения и картинку. Что именно из этого нужно показывать, а что нет, можно задать в настройках.
  • Автоматически сформировать для каждого сообщения описание на основе начала текста сообщения. Ð’ настройках вы можете задать и свои собственные описания для конкретных сообщений.
  • Найти в посте первую картинку и использовать её в качестве иллюстрации. Также есть возможность задать картинку и вручную.
  • Отсортировать сообщения по дате публикации или названию — в прямом или обратном порядке.

вторник, 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>

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

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

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

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

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

вторник, 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 г.

[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>

среда, 8 сентября 2010 г.

[Blogger.com] Отображение количества комментариев с учётом русской морфологии. Добавляем человечности blogspot-у.

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

Ð’ англоязычных блогах такой проблемы не возникает: в зависимости от числа комментариев, шаблон выбирает нужную форму слова: comment или comments. Поскольку у них нет зубодробительной системы падежей и согласования существительного с числительным, простая проверка на равенство единице решает все проблемы. Ð’ русскоязычных же блогах мы можем наблюдать «0 коммент.», «1 коммент.», «2 коммент.» вместо «0 комментариев», «1 комментарий», «2 комментария» и Ñ‚.п. Сегодня мы попытаемся этот недостаток исправить.


В зависимости от числа, слово комментарий принимает следующие формы:
  • 0 — комментариев
  • 1 — комментарий
  • от 2 до 4 включительно — комментария
  • от 5 до 9 включительно — комментариев
  • от 10 до 19 включительно — комментариев
  • от 20 до 99 включительно — так же, как для соответствующих чисел от 0 до 9
  • от 100 и до бесконечности — так же, как для соответствующих чисел от 0 до99
В виджете Blog добавим две подключаемых секции:
<b:includable id='commentcounthelper' var='i'>
    <b:if cond='data:i % 10 == 0'>
        комментариев
    <b:else/>
        <b:if cond='data:i % 10 == 1'>
            комментарий
        <b:else/>
            <b:if cond='data:i % 10 &lt; 5'>
                комментария
            <b:else/>
                комментариев
            </b:if>
        </b:if>
    </b:if>
</b:includable>
<b:includable id='commentcount' var='i'>
    <data:i/>
    <b:if cond='data:i % 100 &gt; 19'>
        <b:include name='commentcounthelper' data='post.numComments'/>
    <b:else/>
        <b:if cond='data:i % 100 &lt; 10'>
            <b:include name='commentcounthelper' data='post.numComments'/>
        <b:else/>
            комментариев
        </b:if>
    </b:if>
</b:includable>

Сегмент commentcount в переменной i получает количество комментариев, выводит его, а затем выводит слово комментариев, если число попадает в диапазон от 11 до 19. Для чисел вне диапазона вызывается сегмент commentcounthelper, который выводит слово в нужной форме для остальных чисел.
Для того, чтобы обрабатывались любые числа, анализируется не непосредственно число комментариев, а остаток от деления на 100 или на 10.

Далее в коде виджета изменим код, выводящей число комментариев, чтобы из него вызывался сегмент commentcount. Первый фрагмент кода выводит число комментариев при просмотре поста на главной, в архиве, поиске и т.п.
Находим нужный фрагмент:
<span class='post-comment-link'>
<b:if cond='data:blog.pageType != &quot;item&quot;'>

<b:if cond='data:post.allowComments'>
<a class='comment-link' expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><b:if cond='data:post.numComments == 1'>1 <data:top.commentLabel/><b:else/><data:post.numComments/> <data:top.commentLabelPlural/></b:if></a>
</b:if>
</b:if>
</span>
И заменяем в нём всё, что заключено внутри тела ссылки на вызов сегмента commentcount:
<span class='post-comment-link'>
<b:if cond='data:blog.pageType != &quot;item&quot;'>
<b:if cond='data:post.allowComments'>
<a class='comment-link' expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><b:include name='commentcount' data='post.numComments'/></a>
</b:if>
</b:if>
</span>

Второй фрагмент кода выводит число комментариев непосредствено на странице поста перед списком комментариев:
<h4>
<b:if cond='data:post.numComments == 1'>
1 <data:commentLabel/>:
<b:else/>
<data:post.numComments/> <data:commentLabelPlural/>:
</b:if>
</h4>
Модифицируем:
<h4><b:include name='commentcount' data='post.numComments'/></h4>

Вот и всё. Готово.

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

[Blogger.com] Скрытие сообщений в блоге

Заметка Постраничная разбивка против плагиата в блоге addstips-site.blogspot.com натолкнула меня на мысль попытаться реализовать аналог постраничной разбивки сообщений для блогов на Blogspot. Идея следующая: если бы могли скрыть часть сообщений из потока сообщений на главной странице, страницах поиска (к которым относятся также страницы с выборкой по тегам и т.п.) и в архиве, то такие скрытые сообщения мы могли бы использовать как отдельные страницы для длинных статей, оставляя в заглавном посте только краткое вступление и оглавление.

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

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

Два других возможных варианта: показывать только сообщения, содержащие определённый ярлык и показывать сообщения, содержащие хотя бы один ярлык, скрывая сообщения без ярлыков. Второй вариант мы и попробуем сегодня реализовать.

В выбранном нами шаблоне находим код, отвечающий за выдачу сообщений. В моих экспериментах я использовал стандартный шаблон Simple ((с) Josh Peterson).

    <b:loop values='data:posts' var='post'>
      <b:if cond='data:post.isDateStart'>
        <b:if cond='data:post.isFirstPost == &quot;false&quot;'>
          &lt;/div&gt;&lt;/div&gt;
        </b:if>
      </b:if>
      <b:if cond='data:post.isDateStart'>
        &lt;div class=&quot;date-outer&quot;&gt;
      </b:if>
      <b:if cond='data:post.dateHeader'>
        <h2 class='date-header'><span><data:post.dateHeader/></span></h2>
      </b:if>
      <b:if cond='data:post.isDateStart'>
        &lt;div class=&quot;date-posts&quot;&gt;
      </b:if>
      <div class='post-outer'>
      <b:include data='post' name='post'/>
      <b:if cond='data:blog.pageType == &quot;static_page&quot;'>
        <b:include data='post' name='comments'/>
      </b:if>
      <b:if cond='data:blog.pageType == &quot;item&quot;'>
        <b:include data='post' name='comments'/>
      </b:if>
      </div>
      <b:if cond='data:post.includeAd'>
        <b:if cond='data:post.isFirstPost'>
          <data:defaultAdEnd/>
        <b:else/>
          <data:adEnd/>
        </b:if>
        <div class='inline-ad'>
          <data:adCode/>
        </div>
        <data:adStart/>
      </b:if>
      <b:if cond='data:post.trackLatency'>
        <data:post.latencyJs/>
      </b:if>
    </b:loop>

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

<b:includable id='post1' var='post'>
      <div class='post-outer'>
      <b:include data='post' name='post'/>
      <b:if cond='data:blog.pageType == &quot;static_page&quot;'>
        <b:include data='post' name='comments'/>
      </b:if>
      <b:if cond='data:blog.pageType == &quot;item&quot;'>
        <b:include data='post' name='comments'/>
      </b:if>
      </div>
      <b:if cond='data:post.includeAd'>
        <b:if cond='data:post.isFirstPost'>
          <data:defaultAdEnd/>
        <b:else/>
          <data:adEnd/>
        </b:if>
        <div class='inline-ad'>
          <data:adCode/>
        </div>
        <data:adStart/>
      </b:if>
      <b:if cond='data:post.trackLatency'>
        <data:post.latencyJs/>
      </b:if>
</b:includable>

Добавляем в код внутри цикла условие для показа и скрытия сообщений, которое будет вызывать созданный сегмент:

    <b:loop values='data:posts' var='post'>
      <b:if cond='data:post.isDateStart'>
        <b:if cond='data:post.isFirstPost == &quot;false&quot;'>
          &lt;/div&gt;&lt;/div&gt;
        </b:if>
      </b:if>
      <b:if cond='data:post.isDateStart'>
        &lt;div class=&quot;date-outer&quot;&gt;
      </b:if>
      <b:if cond='data:post.dateHeader'>
        <h2 class='date-header'><span><data:post.dateHeader/></span></h2>
      </b:if>
      <b:if cond='data:post.isDateStart'>
        &lt;div class=&quot;date-posts&quot;&gt;
      </b:if>
      <b:if cond='data:post.labels'>
        <b:include name='post1' data='post'/>
      <b:else/>
        <b:if cond='data:blog.pageType == &quot;item&quot;'>
          <b:include name='post1' data='post'/>
        <b:else/>
          <b:if cond='data:blog.pageType == &quot;static_page&quot;'>
            <b:include name='post1' data='post'/>
          </b:if>
        </b:if>
      </b:if>
    </b:loop>

Готовый результат можно посмотреть в тестовом блоге.

Какие подводные камни и проблемы возможны у такого метода:

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

Скрытые сообщения всё равно видны в виджете Архив.
Решение 1. Не использовать древовидное представление для виджета Архив. В плоском представлении убрать из шаблона виджета отображение количества сообщений, поскольку оно не соответствует числу видимых сообщений. (Пример там же.)
Решение 2. Не использовать виджет Архив, реализовать навигацию по архиву через гаджет на javascript с умной фильтрацией сообщений.

Скрытые сообщения видны в RSS.
Решение: Фильтровать RSS при помощи Yahoo Pipes. О применении Yahoo Pipes я напишу отдельную статью в неопределённом будущем.

Комментарии на разных фрагментах многостраничной  статьи.
Скорее всего, стоит разрешить комментарии только для одной из частей многостраничной статьи.


Модифицированный код шаблона Simple (включая исправление для виджета Архив) можно посмотреть здесь.

Update. Исправлена ошибка в условии, приводившая к скрытию статичных страниц. Спасибо вот этой статье за то что вовремя попалась мне на глаза и позволила сообразить, что такая ошибка имеет место.

[Blogger.com] Оптимизация блога на платформе blogger для поисковых систем

И снова рубрика «Blogger для начинающих».
Статья подготовлена по материалам сайта addstips-site.blogspot.com.

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

Все описанные далее изменения вносятся в шаблон в шапке (тэг head) шаблона после строчки <b:include data='blog' name='all-head-content'/>.

Заголовок страницы

По умолчанию в шаблоне стоит такой код для вывода заголовка страницы:
<title><data:blog.pageTitle/></title>
Переменная pageTitle содержит название блога, соединённое с названием текущей страницы. Если вас это не устраивает, заменяем на вот такой код:
<b:if cond='data:blog.pageType == "index"'>
<title><data:blog.title/></title>
<b:else/>
<title><data:blog.pageName/></title>
</b:if>
Теперь на главной будет отображаться в заголовке с названием блога, а на остальных — непосредственное название страницы.

Описание страницы в метатеге description

Поисковики не любят дублирование одного и того же описания на разных страницах, поэтому метатег description с описанием сайта выводим только для главной страницы:
<b:if cond='data:blog.pageType == "index"'>
<meta content='описание блога в целом и (или) его главной страницы' name='description'/>
</b:if>

Для страниц постов можно сформировать description на основе заголовка и названия блога:
<b:if cond='data:blog.pageType == "item"'>
<meta expr:content='data:blog.pageName+ " / название вашего блога "' name='Description'/>
</b:if>

Запрет индексации архивов

Для уменьшения количества дублей контента, запрещаем индексацию архивов.
<b:if cond='data:blog.pageType == "archive"'>
<meta content='NOINDEX,FOLLOW' name='ROBOTS'/>
</b:if>

Ссылка rel canonical на основной адрес

Необходимо добавить ссылку на основной адрес вашего блога (блог.blogger.com), поскольку контент блога дублируется на www.блог.blogger.com. При помощи этой ссылки указываем  поисковику, что блог.blogger.com — основной адрес, а адрес с www — зеркало.
<b:if cond='data:blog.pageType == "index"'>
<link expr:href='data:blog.homepageUrl' rel='canonical'/>
</b:if>

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

[Blogger.com] Язык шаблонов Blogspot: Тэги для подстановки данных.

(Перевод статьи Layouts Data Tags)

Как уже было сказано в статье Тэги для содержимого виджетов, подстановка в шаблон актуальных данных осуществляется конструкцией <data:имя/>, где имя — название конкретной переменной, содержащей данные. Конкретный набор доступных переменных зависит от типа текущего виджета.

Глобально доступные данные

Этот набор переменных применим к старнице в целом и доступен из любого виджета, а также вне виджетов.
  • blog.title: Заголовок блога.
  • blog.pageType: Тип текущей страницы: 'item', 'archive' или 'index'.
  • blog.url: URL текущей страницы.
  • blog.homepageUrl: Адрес главной страницы блога.
  • blog.pageTitle: Заголовок текущей страницы, сформированный из заголовка блога и дополнительной информации, такой как название текущего сообщения и Ñ‚.п..
  • blog.encoding: Используемая кодировка.
  • blog.languageDirection: Направление письма для языка блога: "ltr" или "rtl" (слева направо и справа налево).
  • blog.feedLinks: Ссылки на фиды.

Page Header

Простой виджет, чья задача вывести две переменные: загголовок и описание блога.
  • title: Заголовок блога.
  • description: Описание блога.

Blog Posts

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

    • url: URL фида.
    • name: Имя фида.
    • feedType: Тип фида (Atom или RSS).
    • mimeType: MIME тип.
  • olderPageUrl: Если имеются сообщения, более старые, чем сообщения на текущей странице, это поле содержит ссылку на предыдущие сообщения. Контекстно зависит от типа страницы. (Не на всех страницах есть ссылка.)
  • olderPageTitle: Заголовок ссылки на предыдущие сообщения.
  • newerPageUrl: Аналогично olderPageUrl, но для более новых сообщений.
  • newerPageTitle: Аналогично olderPageTitle, но для более новых сообщений.
  • commentLabel: Текст, используемый для отображения количества комментариев, например "comments".
  • authorLabel: Текст, используемый для отображения автора сообщения, например "posted by."
  • timestampLabel: Текст, используемый для отображения даты сообщения, например, "posted at."
  • postLabelsLabel: Текст, отображаемый перед списком ярлыков сообщения, например, "labels for this post."
  • backlinksLabel: Текст, используемый для отображения числа ссылок на сообщение, например, "links to this post."
  • posts: Список сообщений для текущей страницы. Каждый элемент списка содержит следующее:

    • dateHeader: Дата сообщения. Присутствует только если это первое сообщение в списке, опубликованное в указанный день, Ñ‚.е. для для всех сообщений, относящихся к одной дате, дата указывается только перед самым верхним.
    • id: Числовой идентификатор сообщения.
    • title: Заголовок сообщения.
    • body: Содержимое сообщения.
    • author: Отображаемое имя автора.
    • url: Ссылка на страницу сообщения.
    • timestamp: Timestamp. Ð’ отличие от dateHeader, присутствует в каждом сообщении.
    • labels: Список ярлыков сообщения. Каждый элемент списка содержит следующее:

      • name: Текст ярлыка.
      • url: URL страницы, перечисляющей все сообщения с данным ярлыком.
      • isLast: True или false. Указывает, является ли ярлык последним в списке. Используется для правильной расстановки знаков препинания и/или разметки.
    • allowComments: 'True' если разрешено оставлять комментарии к сообщению.
    • numComments: Число оставленных комментариев.
    • showBacklinks: Отображать ли обратные ссылки на данное сообщение.
    • numBacklinks: Число ссылок.
    • addCommentUrl: URL формы добавления комментария.
    • emailPostUrl: URL формы 'email this post'.
    • editUrl: URL формы редактирования сообщения.
    • feedLinks: Список фидов для данного сообщения. Каждый элемент спсика содержит следующее:

      • url: URL фида.
      • name: Название фида.
      • feedType: Тип фида (Atom или RSS).
      • mimeType: MIME тип фида.
    • comments: Список всех комментариев сообщения (только на страницах типа item). Каждый элемент списка содержит следующее:

      • id: Числовой идентификатор комментария.
      • body: Тело комментария.
      • timestamp: Время создания комментария.
      • author: Отображаемое имя автора комментария (или 'Anonymous').
      • authorUrl: URL профиля автора комментария, если комментарий не анонимный.
      • deleteUrl: URL для удаления комментария.
      • isDeleted: Был ли комментарий удалён. (Текст удалённых комментариев заменяется заглушкой.)

Blog Archives

  • title: Заголовок виджета.
  • style: Используемый стиль: 'MENU', 'FLAT' или 'HIERARCHY'.
  • data: Список с архивыми записями:

    • name: Название для данного интервала времени, например, "August 2006."
    • url: Ссылка на страницу, содержащую сообщения из данного интервала.
    • post-count: Количество сообщений в данном интервале.

Profile Widget

Для блога с единственным автором, виджет Profile содержит следующую информацию:
  • title: Заголовок виджета.
  • userUrl: URL профиля автора.
  • location: Местарасположение автора, взятое из профиля.
  • aboutme: Информация «ÐžÐ±Ð¾ мне», взятая из профиля.
  • displayname: Отображаемое имя автора.
  • photo: Фото, состоящее из следующего:

    • url: URL изображения.
    • width: Ширина изображения в пикселях.
    • height: Высота изображения в пикселях.
    • alt: Текст для атрибута "alt".
Для групповых блогов виджет содержит следующую информацию:
  • title: Заголовок виджета.
  • authors: Список авторов, содержащий следующее:

    • displayname: Отображаемое имя автора.
    • userURL: URL профиля автора.
Если в шаблоне необходимо обрабатывать оба варинта, можно использовать переменную team для их различения: <b:if cond='data:team=="true"'> (display multiple authors) </b:if>

Text / HTML / JavaScript Widget

  • title: Заголовок виджета.
  • content: Содержимое виджета.

Feed Widget

Виджет Feed динамически загружается при помощи Google AJAX APIA при отображении блога в браузере и его стиль можно изменить только при помощи CSS.
  • title: Заголовок виджета.
  • feedUrl: URL фида.

Picture Widget

  • title: Заголовок виджета.
  • sourceUrl: URL изображения.
  • width: Ширина.
  • height: Высота.
  • caption: Название изображения.

Labels Widget

  • title: Заголовок виджета.
  • labels: Список ярлыков:

    • name: Название ярлыка.
    • count: Количество сообщений с данным ярлыком.
    • url: Ссылка на страницу, показывающую сообщения с данным ярлыком.

List Widget

  • title: Заголовок виджета.
  • items: Элементы списка.

Link List Widget

  • title: Заголовок виджета.
  • links: Список ссылок::

    • name: Текст.
    • target: URL.

Logo Widget

  • fullButton: URL лого.

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

[Blogger.com] Язык шаблонов Blogspot: Тэги для содержимого виджетов

(Перевод материала Widget Tags for Layouts)

среда, 1 сентября 2010 г.

[Blogger.com] Язык шаблонов Blogspot: Тэги для описания элементов страницы.

Обновлено: 9 сентября 2015

Этот пост открывает серию публикаций, посвященных синтаксису шаблонов Blogspot.