пятница, 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 скачать можно тут.


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

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

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

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

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

среда, 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 г.

[советы по настройке] Переключение режимов отображения отступов в Notepad++ (wrap indent mode)

Продолжаем настраивать Notepad++.

Для отображения списков (особенно, вложенных) отформатированных при помощи отступов табуляцией, удобен режим, в котором отступ от табуляции получает не только первая строка абзаца, а весь абзац целиком. «Мотор» Notepad++ — компонент для редактирования текста  Scintilla — поддерживает такой режим, но в меню редактора не вынесено никаких команд, позволяющих его включить. К счастью, плагин NppExec позволяет решить эту задачу.

Открываем окно редактирования скриптов NppExec: «Дополнения» → «NppExec» → «Execute». Пишем туда такой текст:
sci_sendmsg SCI_SETWRAPINDENTMODE 1
npp_console 0
Что этот скрипт обозначает:
Команда sci_sendmsg посылает компоненту Scintilla сообщение SCI_SETWRAPINDENTMODE с параметром 1, которое заставляет его включить требуемый режит отступов.
Команда  npp_console 0 закрывает открывшееся окно консоли, куда выводятся сообщения при выполнении скриптов NppExec.

Нажимаем кнопку «Save» и сохраняем скрипт под именем SCI_SETWRAPINDENTMODE_1.

Затем заменяем в первой команде 1 на 0:
sci_sendmsg SCI_SETWRAPINDENTMODE 0
npp_console 0
и сохраняем под именем SCI_SETWRAPINDENTMODE_0.

Теперь вынесем скрипты в меню. Закрываем окно «Execute» и идем в «Дополнения» → «NppExec» → «Advanced Settings». В разделе «Menu Item» выбираем из выпадающего списка SCI_SETWRAPINDENTMODE_1 и рядом в поле редактирования пишем желаемое имя пункта меню, например, Set Wrap Indent Mode On; нажимаем кнопку «Add/Modify».Аналогично добавляем SCI_SETWRAPINDENTMODE_0 вторым пунктом меню.
В верхней части окна ставим флажок «Place to Macros submenu».

Перезапускаем редактор. Теперь в меню «Макросы» доступны пункты для переключения режима отступов:

Меню Макросы с созданными пунктами

Режим Wrap Indent выключен

Режим Wrap Indent включен

[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 лого.

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

[советы по настройке] Исправляем выделение текста в Notepad++ клавишами Shift+Home и Shift+End

В «продвинутом» редакторе Notepad++ имеется проблема с выделением текста клавишами Shift+Home и Shift+End в режиме переноса строк. Дело в том, что эти сочетания по умолчанию выделяют текст до начала/конца физической строки в файле (т.е. до символов перевода строки), в то время как во всех остальных редакторах они выделяют текст до начала/конца экранной строки.  (Что есть правильно, поскольку всегда и везде Home и End перемещают курсор именно к границе экранной, а не физической строки.)

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

Итак, чтобы исправить работу этих команд, делаем следующее. Открываем в меню «Опции» → «Горячие клавиши» → «Scintilla Commands» и прокручиваем там список вот до этого места:

Абракадабра в левом столбце — это внутренние названия команд редактора. Нас интересуют следующие:
  • SCI_VCHOMEWRAP — перемещение курсора к началу экранной строки.
  • SCI_VCHOMEWRAPEXTEND — выделение текста до начала экранной строки.
  • SCI_LINEENDWRAP — перемещение курсора к концу экранной строки.
  • SCI_LINEENDWRAPEXTEND — выделение текста до конца экранной строки.
Аналогичные названия команд, не содержащие в себе WRAP, работают с физической строкой вместо экранной.

Свяжем сочетание Shift+Home с командой SCI_VCHOMEWRAPEXTEND. Для этого дважды щелкаем по строке с именем команды и в открывшемся окне задаём нужное сочетание: из списка выбираем Home, ставим флажок напротив Shift, нажимаем кнопку Add и затем Ok.

Теперь сочетание клавиш связано с новой командой, но еще необходимо удалить это сочетание у предыдущей команды. Дважды щелкнув по строке SCI_VCHOMEEXTEND, открываем окно привязки клавиш. Чтобы убрать привязку к Shift+Home, выбираем в выпадающем списке None и нажимаем Apply и затем Ok. (Почему нельзя просто нажать Remove для удаления привязки? Потому что «The Remove button will remove the selected shortcut from the list (you can remove all but the last). To remove a shortcut if more than one is present, use the Remove button. To remove a shortcut if it is the only one, set it to 'None' and Apply». Грёбаный пиздец. Не спрашивайте меня. Примите это как есть.)
Ну или вы можете вместо None задать другое сочетание, если выделение до начала физической строки вам может иногда понадобиться. Только следите, чтобы выбранное сочетание не конфликтовало с какой-нибудь другой командой: предупреждать о таких конфликтах Notepad++ не умеет, просто тупо что-нибудь не будет работать.



Аналогично вышенаписанному, связываем Shift+End с командой SCI_LINEENDWRAPEXTEND и убираем привязку у команды SCI_LINEENDEXTEND. После этого советую перезапустить редактор, поскольку окончательно настройки в файл конфигурации он сохраняет только при закрытии.

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

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

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

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

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

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

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