В старом Disqus, так называемом Disqus Classic, была возможность настраивать то, как будет отображаться количество комментариев к статьям. Например, если комментариев нет, на ваше усмотрение Disqus мог писать «0 комментариев», «Комментарии отсутствуют», «Нет комментариев» и тп. В Disqus 2012 такая возможность пропала. Раньше проблема решалась временным переключением на старый Disqus, но теперь и этой возможности нет.

А я как раз давно подумывал над тем, чтобы перейти с такого отображения числа комментариев:

… на такое:

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

В связи с тем, что в свое время я сказал Disqus’у выводить просто число комментариев безо всяких там слов, а возможности как-то это изменить теперь нет, спрашивается, что делать-то? Погуглив немного я не смог найти какой-либо воркэраунд. Пришлось придумывать свой.

Оказалось, что Disqus отдает информацию о числе комментариев к заданному множеству статей в ответ на запрос типа:

http://disqus.com/forums/ID/get_num_replies.js?url1=URL1&url2=URL2&…

Здесь ID — это идентификатор вашего сайта в Disqus, а URL1, URL2 и тд — адреса статей, для которых требуется получить количество комментариев. В ответ приходит JavaScript, который ищет на текущей странице отрывки кода вроде:

< a href = «http://example.ru/bebebe#disqus_thread» > число комментариев < / a >

… и заменяет текст внутри тэга на число комментариев.

Я набросал такой скрипт:

<?php
// error_reporting(E_ALL);
$secret = «SECRET!» ;
header ( «Content-type: text/javascript» ) ;

if ( ! isset ( $_GET [ ‘q’ ] ) || ! isset ( $_GET [ ‘s’ ] ) ||
md5 ( $secret . $_GET [ ‘q’ ] ) != $_GET [ ‘s’ ] ) {
echo «// invalid query checksum n » ;
exit ;
}

if ( rand ( 1 , 512 ) == 1 ) {
// удаляем файлы, созданные более суток назад
echo «// you are lucky, cleaning cache… n » ;
system ( «find ./cache -mtime +1 -delete» ) ;
}

$cache = «./cache/» . md5 ( $secret . $_GET [ ‘s’ ] . floor ( time ( ) / ( 30 * 60 ) ) ) ;
if ( file_exists ( $cache ) ) {
$numbers = file_get_contents ( $cache ) ;
echo «// cached n » ;
} else {
$url = «http://disqus.com/forums/eaxme/get_num_replies.js?» .
$_GET [ ‘q’ ] ;
$data = file_get_contents ( $url ) ;
preg_match ( «/var num_replies = ‘([^’]*)’/» , $data , $matches ) ;
$numbers = $matches [ 1 ] ;
file_put_contents ( $cache , $numbers ) ;
}
?>
(function () {
var nodes = document.getElementsByTagName(‘a’);
var disqus_nodes = [];
var _node_is_disqus = function(node) {
return (node.href.indexOf(‘#disqus_thread’) >= 0);
}
var i;
for (i = 0; i < nodes.length; i++) {
try {
if (_node_is_disqus(nodes[i])) {
disqus_nodes.push(nodes[i]);
}
} catch(e) {
}
}
var num_replies = ‘ <?php echo $numbers ?> ‘.split(‘,’);
var replies_count, link_text;
for (i = 0; i < disqus_nodes.length; i++) {
link_text = »;
template = »;
replies_count = parseInt(num_replies[i], 10);
if (replies_count !== undefined && !isNaN(replies_count)) {
rem = replies_count % 10;
if (replies_count > 10 && replies_count < 15) {
template = ‘{num} комментариев’;
} else if (rem > 1 && rem < 5) {
template = ‘{num} комментария’;
} else if (rem == 1) {
template = ‘{num} комментарий’;
} else {
template = ‘{num} комментариев’;
}
link_text = template.replace(‘{num}’, replies_count);
}
if (link_text) {
try {
disqus_nodes[i].innerHTML = link_text;
} catch(e) {
if (disqus_nodes[i].innerText) {
disqus_nodes[i].innerText = link_text;
}
}
}
}
})();

Скрипт представляет собой своего рода прокси для get_num_replies.js. Он принимает два аргумента — q и s. Первый представляет собой запрос, который должен быть послан get_num_replies.js, а второй — что-то вроде цифровой подписи аргумента q, на всякий случай. Если подпись верна, скрипт шлет запрос на сервер Disqus’а, парсит ответ регулярным выражением , и возвращает немного модифицированный ответ. Чтобы не ходить слишком часто по HTTP, ответы от Disqus’а кэшируются.

Также я добавил в functions.php такой кусок кода:

function comments_number_javascript ( $commentsNumberQuery ) {
echo ‘<script type=»text/javascript» src=»‘ .
‘http://remontka.com/disqus-comments/?q=’ .
urlencode ( $commentsNumberQuery ) .
‘&amp;s=’ . md5 ( «SECRET!» . $commentsNumberQuery ) .
‘»></script>’ ;
}

… вывод постов в index.php, archive.php и single.php изменил следующим образом:

<?php
global $commentsNumberQuery ;
$commentsNumberQuery = «» ;
$postNumber = 0 ;
while ( have_posts ( ) ) :
the_post ( ) ;
$postNumber ++;
$commentsNumberQuery .= «url» . $postNumber . «=» . get_permalink ( ) . «&» ;
?>

… а в footer.php дописал:

<?php
global $commentsNumberQuery ;
comments_number_javascript ( $commentsNumberQuery ) ;
?>
</body>
</html>

В результате я убил сразу трех зайцев:

  • Решил основную задачу — выводить число комментариев в формате «N комментариев»;
  • Немного ускорил работу бложика (меньше картинок, меньше редиректов, кэширование ответа от Disqus);
  • Настроил вывод числа комментариев в полном соответствии с правилами русского языка;

Есть подозрение, что последнего вообще никогда не будет в Disqus. И решение даже получилось почти не костыльным. В общем, я доволен. А вы что скажите?

P.S. Кстати, можете меня поздравить. Это мой двухсотый пост в этом блоге.

Дополнение: К сожалению, описанный здесь API жестко привязывается к URL статьи. Если вы решите изменить этот URL, число комментариев станет перманентно равно нулю. Для решения этой проблемы можно дергать http://disqus.com/embed/comments/?f=FORUM&t_i=POSTID , где FORUM — это идентификатор вашего сайта, например eaxme , а POSTID — идентификатор поста в urlencode, например 18014%20http%3A%2F%2Fremontka.com%2F%3Fp%3D18014 , и выдирать оттуда число комментариев. Только работать это будет несколько медленнее.

admin

Share
Published by
admin

Recent Posts

Консоль удаленного рабочего стола(rdp console)

Клиент удаленного рабочего стола (rdp) предоставляет нам возможность войти на сервер терминалов через консоль. Что…

1 месяц ago

Настройка сети в VMware Workstation

В VMware Workstation есть несколько способов настройки сети гостевой машины: 1) Bridged networking 2) Network…

1 месяц ago

Логи брандмауэра Windows

Встроенный брандмауэр Windows может не только остановить нежелательный трафик на вашем пороге, но и может…

1 месяц ago

Правильный способ отключения IPv6

Вопреки распространенному мнению, отключить IPv6 в Windows Vista и Server 2008 это не просто снять…

1 месяц ago

Ключи реестра Windows, отвечающие за параметры экранной заставки

Параметры экранной заставки для текущего пользователя можно править из системного реестра, для чего: Запустите редактор…

1 месяц ago

Как управлять журналами событий из командной строки

В этой статье расскажу про возможность просмотра журналов событий из командной строки. Эти возможности можно…

1 месяц ago