[EVO] Иконки социальных сервисов в MODX или история торжества разума над ленью

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

Стал тормозить с 1 января 2013 мой хостинг на majordomo.ru и потому встал вопрос перезда с него на что-то более приличное. Пользовался до этого и sprinthost.ru, но там есть одна штука – ограничение на количество файлов. А как назло у меня сделаны превьюшки через плагин TVImageResize, который создает кучу папок и картинку режет в 5 разрешениях, что совершенно не экономично. Поэтому просто тупо перенести сайт не интересно, нужно слегка оптимизировать его. То есть переработать.

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

Социальные иконки

Думаю, что социальные сети настолько прочно вошли в нашу жизнь в интернете, что расписывать что это такое нет смысла – практически все имеют аккаунты в Одноклассниках, ВКонтакте, Facebook и других. Даже появился термин SMO – продвижение сайта через социальные сети.

Вот один из элементов — кнопки-ссылки на социальные сети. Кнопки на сайты веб-мастера ставят 2 видов:
  1. Сслыки на группу в социальной сети (их я рассматривать не буду – это слишком просто и неинтересно)
  2. Кнопки типа «поделится с друзьями»

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

Один из таких сервисов прекрасно описал Виктор Ефимов в цикле статей по созданию блога. Он использовал сервис от Яндекс. Вот только там есть проблема – кнопки маленькие и не красивые. Есть еще один сервис share42.com, которые позволеят уже не из 5-8 кнопок выбирать, а делать кнопки на 42 сервиса. Причем можно выбирать размер кнопок, а сами они боле-менее красиво сделаны.

Но у таких сервисов есть один минус – javascript. Он весит, он тормозит отображение страницы. Однако до поры до времени я пользовался сам вервисом от Яндекса. Ну и при преработки своего сайта решил сделать красиво и быстро.

Социальные кнопки и MODX

Как ни странно, оказалось, что на MODX ставить нужно точно так же эти иконки, как и на простой html сайт – прописать стили руками, вставить javascript, прописать в html спецконструкцию для вывода этих кнопок.

Правда нашелся один человек, который написал сниппет sRadio – Александр Шарапов. Но такой сниппет мне не подошел – там всего 6 кнопок. Однако в описании и обсуждении меня зацепила фраза, что идея сниппета была взята с сервиса share42.com.

Ах, как было бы хорошо – взял вызов сниппета, прописал что нужно и вуаля! Но увы, реальность жестока – нужно делать самому. Лень не прошла!

Как устроены кнопки социальных сервисов


В сниппете sRadio делается простой вывод блока div с нужными ссылками, которым в бекграунд укладываются картинки сервисов из спрайта. Вся изуминка в ссылки, которую формирует сниппет – там подставляется pagetitle страницы и его uri.

В принципе это работает, но не совсем так, как в кнопках Яндекса. Тут нет всплывающего окна, где все происходи, а перекидывает все в основном окне, что явно не удобно. Но иде понятна.

Дальше я решил разобраться: а как же устроены кнопки в сервисе share42.com? Благо теперь есть всякие полезные штучки типа firebug, dragonfly, инспекторы кода и так далее. Вот в Chrome я и воспользовался «посмотреть исходный код элемента».

Сначала я сформировал что мне хотелось бы увидеть у себя на сайте и размеры. Ну и нажал «предосмотр»

Тут одна тонкость – если смотреть код страницы, то будет показано как отдает сервер, а через код элемента – как видит браузер. Скопировать как html и вставить в любой текстовой редактор было дело 1 минуты – больше искал как же скопировать код.

Вот что получилось (даю только 2 ссылки):
<div class="share42init" data-url="http://share42.com" data-title="Share42.com - Скрипт кнопок социальных закладок и сетей" data-top1="110" data-top2="20" data-margin="-70">
  <span id="share42">

    <a rel="nofollow" style="display:inline-block;vertical-align:bottom;width:24px;height:24px;margin:0 6px 6px 0;padding:0;outline:none;background:url(image.php?i=google-plus,yaru,vkontakte,odnoklassniki,facebook,twitter,mail-ru,blogger,livejournal,liveinternet,moi-krug,evernote,bobrdobr,google-bookmarks,yandex,memori,browser&size=24&share42&) -0px 0 no-repeat" href="#" onclick="window.open('https://plus.google.com/share?url=[(site_url)][~[*id*]~]', '_blank', 'scrollbars=0, resizable=1, menubar=0, left=200, top=200, width=550, height=440, toolbar=0, status=0');return false" title="Поделиться в Google+" target="_blank"></a>
    
<a rel="nofollow" style="display:inline-block;vertical-align:bottom;width:24px;height:24px;margin:0 6px 6px 0;padding:0;outline:none;background:url(image.php?i=google-plus,yaru,vkontakte,odnoklassniki,facebook,twitter,mail-ru,blogger,livejournal,liveinternet,moi-krug,evernote,bobrdobr,google-bookmarks,yandex,memori,browser&size=24&share42&) -24px 0 no-repeat" href="http://my.ya.ru/posts_add_link.xml?URL=[(site_url)][~[*id*]~]&title=[*pagetitle*]" title="Поделиться в Я.ру" target="_blank"></a>

Для лучшего чтения я разделил на строки этот код.
При внимательном анализе можно заметить, что здесь тот же принцип – div – span – a*n. Весь код идет в href собитии onklick! Причем легко понять, что можно заменить только адрес и название и я получу готовую кнопку.
Далее идет дело техники. Все лишнее удаляем и получам вот такой код
<div class="share42init">
  <span id="share42">
    <a rel="nofollow” class=”social-ico gp” href="#" onclick="window.open('https://plus.google.com/share?url=[(site_url)][~[*id*]~]', '_blank', 'scrollbars=0, resizable=1, menubar=0, left=200, top=200, width=550, height=440, toolbar=0, status=0');return false" title="Поделиться в Google+" target="_blank"></a>

Проверил – работает. Но ведь заставлять все это сново и сново парситься MODX не интересно – нужно просто автоматизировать.
PHP – это hypertext preprocessor
Используем всю мощь языка php и заменим сразу где нужно адрес и название страницы. А для этого используем одну из основных функций – str_replace. Описание этой функции – php.net и любой учебник php.
Продумаем логику:
1. Получаем в переменную шаблон (проверяем)
2. Получаем адрес страницы вызова
3. Получаем название страницы вызова
4. Записываем в массив плейсхолдеры шаблона title и uri
5. Записыаем значения этих плейсхолдеров в массив
6. Вызываем замену одних плейсхолдеров на занчение
7. Выводим шаблон
Никакой супер логики и чудеса программисткой мысли – последовательное выполнение. Вот код

<?php
$tpl = (isset($tpl)) ? $tpl : null;  
$pagettle = $modx->documentObject['pagetitle'];
$pageuri = $modx->makeUrl($modx->documentIdentifier, '', '', 'full');

if ($tpl) { 
	if ($modx->getChunk($tpl)) {
		$template = $modx->getChunk($tpl);
	} else {
		return '<div class="error-msg">Указанный в вызове сниппета <b>sRadio</b> чанк не найден.</div>';
	}
}

$paleholders = array("[+uri+]", "[+title+]");
$date = array($pageur, $pagettle);

$output = '<div class="smicons">';
$output .= str_replace($paleholders, $date, $template);
$output .= '</div>';
return $output;
?>

Код написан по исходнику sRadio, который я использовал как пример.
Шаблон к этому сниппет
Написать такой код – 5 минут даже для человека, не знакомого с программированием. А самый интересный здесь … шаблон!
А вот и он:

<a rel="nofollow" class="social-ico ico-gp" href="#" onclick="window.open('https://plus.google.com/share?url=[+uri+]', '_blank', 'scrollbars=0, resizable=1, menubar=0, left=200, top=200, width=550, height=440, toolbar=0, status=0');return false" title="Поделиться в Google+" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-ya" href="http://my.ya.ru/posts_add_link.xml?URL=[+uri+]&title=[+title+]" title="Поделиться в Я.ру" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-vk" href="#" onclick="window.open('http://vk.com/share.php?url=[+uri+]&title=[+title+]', '_blank', 'scrollbars=0, resizable=1, menubar=0, left=200, top=200, width=554, height=421, toolbar=0, status=0');return false" title="Поделиться В Контакте" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-od" href="#" onclick="window.open('http://www.odnoklassniki.ru/dk?st.cmd=addShare&st._surl=[+uri+]&title=[+title+]', '_blank', 'scrollbars=0, resizable=1, menubar=0, left=200, top=200, width=550, height=440, toolbar=0, status=0');return false" title="Добавить в Одноклассники" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-fb" href="#" onclick="window.open('http://www.facebook.com/sharer.php?u=[+uri+]&t=[+title+]', '_blank', 'scrollbars=0, resizable=1, menubar=0, left=200, top=200, width=550, height=440, toolbar=0, status=0');return false" title="Поделиться в Facebook" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-tw" href="#" onclick="window.open('http://twitter.com/share?text=[+title+]&url=[+uri+] ', '_blank', 'scrollbars=0, resizable=1, menubar=0, left=200, top=200, width=550, height=440, toolbar=0, status=0');return false" title="Добавить в Twitter" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-mr" href="http://connect.mail.ru/share?url=[+uri+]&title=[+title+]" title="Поделиться в Моем Мире@Mail.Ru" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-lj"  href="http://www.livejournal.com/update.bml?event=[+uri+]&subject=[+title+]" title="Опубликовать в LiveJournal" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-ev" href="http://www.evernote.com/clip.action?url=[+uri+]&title=[+title+]" title="Добавить в Evernote" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-bd" href="http://bobrdobr.ru/add.html?url=http%3A%2F%2Fshare42.com&title=[+title+]" title="Забобрить" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-gb" 
href="http://www.google.com/bookmarks/mark?op=edit&output=popup&bkmk=[+uri+]&title=[+title+]" title="Сохранить закладку в Google" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-zy" href="http://zakladki.yandex.ru/newlink.xml?url=[+uri+] &name=[+title+] " title="Добавить в Яндекс.Закладки" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-mm" href="http://memori.ru/link/?sm=1&u_data[url]=[+uri+]&u_data[name]=[+title+]" title="Сохранить закладку в Memori.ru" target="_blank"></a>
<a rel="nofollow" class="social-ico ico-bb" href="" onclick="return fav(this);" title="Сохранить в избранное браузера" target="_blank"></a>

Вот на эксперементы и выделение я и потратил около 2 часов своего времени. Но код не будет работать без стилей. Вот что нужно вставить в таблицу стилей:

/* ---------------------------------------------- Social Icons -------------------------------------*/
.smicons {
  display: inline-block; 
  padding: 6px 0 0 6px;
  background: #FFF; 
  border: 1px solid #E9E9E9; 
  border-radius: 4px;
}

.smicons:hover {background: #F6F6F6; border: 1px solid #D4D4D4; box-shadow: 0 0 5px #DDD;}
.smicons a {opacity: 0.5}
.smicons:hover a {opacity: 0.7}
.smicons a:hover {opacity: 1}

.social-ico {
  display:inline-block;
  vertical-align:bottom;
  width:24px;
  height:24px;
  margin:0 6px 6px 0;
  padding:0;
  outline:none;
}
.ico-gp {background:url(../images/icons.png) -0px 0 no-repeat;}
.ico-ya {background:url(../images/icons.png) -24px 0 no-repeat;}
.ico-vk {background:url(../images/icons.png) -48px 0 no-repeat;}
.ico-od {background:url(../images/icons.png) -72px 0 no-repeat;}
.ico-fb {background:url(../images/icons.png) -96px 0 no-repeat;}
.ico-tw {background:url(../images/icons.png) -120px 0 no-repeat;}
.ico-mr {background:url(../images/icons.png) -144px 0 no-repeat;}
.ico-bg {background:url(../images/icons.png) -168px 0 no-repeat;}
.ico-lj {background:url(../images/icons.png) -192px 0 no-repeat;}
.ico-li {background:url(../images/icons.png) -216px 0 no-repeat;}
.ico-mk {background:url(../images/icons.png) -240px 0 no-repeat;}
.ico-ev {background:url(../images/icons.png) -264px 0 no-repeat}
.ico-bd {background:url(../images/icons.png) -288px 0 no-repeat}
.ico-gb {background:url(../images/icons.png) -312px 0 no-repeat}
.ico-zy {background:url(../images/../images/icons.png) -336px 0 no-repeat}
.ico-mm {background:url(../images/icons.png) -360px 0 no-repeat}
.ico-bb {background:url(../images/icons.png) -384px 0 no-repeat}
<code>
Как видите, я не стал мудрить и взял код с share42.com тольковынес в стили. Можно было бы все еще более оптимизировать, но и этого достаточно – наглядно и нет лишнего. Хотя если кто-то предложит свою оптимизацию – буду только рад!
Ну и спрайт нужен так же.
<img src="http://modx.im/uploads/images/00/00/45/2013/01/24/79a468.png"  alt="" />
<h4>Как всем этим пользоваться</h4>
1.	В стили прописываем стили, путь картинки править не забываем так же.
2.	Выкладываем картику, чтобы стили видели спрайт
3.	Создаем шаблон и копируем нужное в шаблон
4.	Создаем сниппет
5.	В шаблоне вызываем сниппет с указанием шаблона
Любуемся результатом
<h4>Выводы</h4>

Вывод социальных иконок стал не просто быстр – а очень быстр! Таким образом браузер пользователя не делает глупую работу по обсчету и замене, а отображает уже готовые картинки. Причем всплывающие окна и так далее – все как и должно быть
Вот только с G+  как лайки так лучше не работать. Мне не понравилось продираться через кучу окн, так что лучше оставить это скрпитом. Я сделал такой шаблон
<code>
<h3>Поделится с друзьми</h3>
      <div>
        <div style="height:38px; padding-top:7px;float:left;"><div class="g-plusone"></div></div>
   			<div style="float:right;">[[social? &tpl=`social`]]</div>
      </div><br class="clear">

Т.е. слева G+ как лайк (и нужно это прежде всего для Google Seach), а далее иконки (много иконок ;) )

Так что можно сказать одно – пробуйте, творите. Не нужно смотреть есть снипет – делаем, нет сниппета – стоим ждем. Думайте как применить, исследуйте, пробуйте.
Руки не болят только у лодыря!

22 комментария

avatar
Лично мне тоже не нравится то, что иконки грузят сайт. Плюс каждый норовить свой цвет запихать и в итоге получается разноцветный бардак. Беру иконочный шрифт, типа: fontello.com/ ставлю из него иконки к списку ссылок социальных сетей. Работает, хоть и с переходом на страницу социальной сети, без всплывающих окон и прочей мишуры.
avatar
Ну это 1 вариант иконок, который я не рассматриваю. Тут была именно задача сделать «по взрослому» — с всплыващим окном и публикацией анонса материала под аккаунтом пользователя на его личной странички. Вот я и показал, как можно переделать это из javascript в php и в разы увеличить скорость отображения страницы. Тем более, что у меня стоит и реклама от Гугл на скриптах, и погода от Яндекса, и комментарии от DISQUS. Все это пока браузер отработает. Вот думаю как погоду от Яндекса переделать на вывод из php, а там и до рекламы доберусь :)
avatar
То есть минимизация кода сегодня считается детством, я понял.
Мне интересно — как часто вообще нажимают эти кнопки?
avatar
Нет, вы меня не правильно поняли. Просто сделать ссылку с картинкой или без — это просто. А вот сделать со всеми этими плюшками гораздо сложнее. Те, кто в этом разобрался типа Dimox, создали сервисы share42.com. Я лишь привел как можно сделать это самому и при помощи php. Что вы тут обидного нашли, я не понимаю.

Сами кнопки: их количество и нужность. Устанавливать или нет — это каждый решает сам. Тут можно долго спорить до хрипоты. Я ставлю «на всякий случай». Но полезными я считаю только одну «Мне нравится» Google+ — она влияет на поисковую выдачу и хоть какую-то несет обратную связь от пользователя. А ее как раз перевести в php нормально не получается — динамическая.
avatar
Да я не обижаюсь ни капли, с чего вы взяли? Вы молодец, очень интересное решение на самом деле, я просто из тех, кто социальные сети считает злом и кнопки на них тоже) Но это мой личный недостаток)))
avatar
На самом деле я тоже не люблю социальные сети, которые у всех на слуху. Но там сидят потенциальные пользователи. Поэтому нужно этим пользоваться.

А сам я общаюсь на форум и таких сетях типа modx.im :)
avatar
Мне интересно — как часто вообще нажимают эти кнопки?
Ставил давным давно на одном проекте кнопки от яндекса, дабы как раз узнать, сколько на них жмут, так как яндекс выдает по этим кнопкам статистику. Был приятно удивлен. Конечно, счет идет всего на несколько десятков кликов в месяц, но и посещаемость у ресурса тогда была на уровне всего 100-200 уников в день, но нажимали ежедневно и обратные переходы из соцсетей были. Но согласен, далеко не каждому проекту эти кнопки нужны. А Евгений молодец, все простое заведомо гениально :) Чем меньше на сайте скриптов — тем радостнее жить.
avatar
Специально через метрику глянул сайты, с которых перешли. За год.
ВКонтакте — 60
Одноклассники — 56
МойМир — 25

А как глянуть сколько нажимались на кнопках Яндекса?
Комментарий отредактирован 2013-01-24 19:08:00 пользователем jean179
avatar
Да там же, в метрике Содержание — Кнопка «Поделиться»
avatar
Ага, вижу. 77 кликов за год. Вот статистика:
Одноклассники 29
ВКонтакте 27
Twitter 5
Facebook 4
Мой Мир 4
FriendFeed 3
Мой Круг 2
Я.ру 2
LiveJournal 1
avatar
Ну у меня тогда до 100 в месяц доходило, но это напрямую зависит от контента.
avatar
Ага. И от момента. Думаю мою статью о наводнении в Крымску большей части кликали.
avatar
Кажется в коде шаблона я допусти пару косяков — не все урлы вычистил. Только сейчас заметил. Поэтому проверяйте на «боевом хостниге»
avatar
Под кнопки яндекса тоже можно подложить ссылку и заголовок страницы которой будут делиться пользователи. По умолчанию это текущая страница, но можно поставить и другую. Вот пример чанка из revo
<script type="text/javascript" src="//yandex.st/share/share.js" charset="utf-8"></script>
<div class="yashare-auto-init" data-yashareL10n="ru" data-yashareType="[[+type:is=``:then=`none`:else=`[[+type]]`]]" data-yashareQuickServices="[[+service:is=``:then=`vkontakte,facebook,twitter,odnoklassniki,moimir,lj,moikrug,gplus`:else=`[[+service]]`]]" [[+link:notempty=`data-yashareLink="[[+link]]"`]] [[+title:notempty=`data-yashareTitle="[[+title]]"`]]></div>

Как видно, у него 4 параметра, для указания типа кнопки, социальных сервисов, ссылки и заголовка. Соответственно вызов примерно такой
[[$share? &type=`button` &title=`[[*pagetitle]]` &link=`[[~[[*id]]]]` &service=`vkontakte,facebook,twitter`]]


Кстати, я никогда не понимал людей, которые кнопки социальных сетей ставят плагинами. Нахера? Нет, ну секретаршь с блогами «как я тусила на мальдивах» я еще понимаю, но вот для остальных сайтов это уже перебор…
Комментарий отредактирован 2013-01-25 15:18:29 пользователем Agel_Nash
avatar
Для Evo будет аналогичный чанк, только понадобится еще сниппет
<?php
return $modx->parseChunk($modx->getSnippetName(),$modx->event->params,"[+","+]");
?>

И либо подключить в ядро phx (плохой вариант), либо переделать вызовы модификаторов на вызов сниппета if.

А сам вызов будет выглядеть так (при условии, что чанк называется так же, как и сам сниппет)
[[share? &type=`button` &title=`[*pagetitle*]` &link=`[~[*id*]~]` &service=`vkontakte,facebook,twitter`]]
Комментарий отредактирован 2013-01-25 15:25:55 пользователем Agel_Nash
avatar
Нет, Женя, ты привел код из другой области — ты подключаешь в страницу скрипт и даешь ему настройки динамические (зачем — один раз выбрал и вперед!). Фактически, javascript делает только одну вещь — динамически генерирует ссылку с особым строением url + прописывает кое-какие события. Причем все это делается при отображении страница у пользователя. Получается такой алгоритм: запрос серверу — выдача страницы — подгрузка страницы — подгрузка скрипта — обработка страницы — отображение страницы. И так каждый раз каждому посетителю.

Я же захотел уйти от этого. Я просто собрал шаблоны таких урлов с «спионерил» дизайн. А сниппетом только добавляю в структуру урлов название страницы и адрес. Получается такой алгоритм: запрос серверу — генерация страницы — отдача — отображение. Причем все кешируется. Получается быстрее в разы!

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

Еще раз повторю: цель — убрать лишние скрипты и увеличить скорость отображения страницы.
avatar
Ясно. Значит как всегда по диагонали читал))

Кстати, если так хочется полчить статистику сколько человек кликнули по твоим ссылкам поделиться, то можно повесить reachGoal на событие onclick по иконке.
avatar
Ага, принял к сведению. Но легче поискать путь в API метрики — подставить что нужно в урл сслыки.
avatar
Это да. Но в офф. документации этой инфы я не находил. А раз так, то есть вероятность, что API на кнопках будет меняться.
avatar
Если этот вопрос будет интересовать серьезно, то можно будет при изменении путей еще раз проверить какие пути нужно для метрики ну и поправить шаблон. Дела на 2 минуты. А АПИ в любом случае будет меняться постоянно — именно от таких халявщиков как я :).
avatar
А мне понравилось.
Кстати уже давно хочу заняться расширением Сарафанного радио, да все руки не доходят. Вот будет свободных несколько часов, немного перепишу код для большей оптимизации и кастомизации. Возможно добавлю шрифт с иконками соц-сетей (хотя картинки конечно лучше в плане кастомизации).
Комментарий отредактирован 2013-01-27 19:06:03 пользователем a-sharapov
avatar
А, вот и автор! Буду только рад, если вы дополните и расширите свой сниппет. Единственное могу лишь пожелать, чтобы был учтен и вариант кликов через яндекс — чтобы могли клики учитываться.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.