пятница, 7 октября 2011 г.

Sharepoint 2010: Социальные кнопки

На одном из проектов потребовалось добавить социальные кнопки к некоторой информации на сайте. Например, при отображении новости нужны были эти самые кнопки.
Решил создать контрол, который будет отображать эти самые кнопки. Данные контрол можно будет разместить как на мастер-странице, и так же включить в состав любого нашего элемента управления. Ограничение контрола: при нажатии на социальную кнопку должно происходить добавление ссылки на текущую отображаемую страницу в браузере, т.е. то что есть в адресной строке.
Требования к коду:
  • Т.к. кнопок у нас будет несколько и в будущем появится потребность добавить новую кнопку, то создание конкретной кнопки будет вынесено в отдельный класс, который будет реализовывать нужный интерфейс.
  • Метод интерфейса, описывающий генерацию кнопки, будет возвращать сформированную строку разметки
  • Инициализация последовательно кнопок будет реализовано в методе RenderControl нашего контрола.
  • Кнопки должны быть "наши" , т.е. не стандартные Like и Чирикнуть, а наши заданные кнопки, которые хранятся в ресурсах проекта. Это требования заставило подумать, т.к. не проканало просто добавление скрипта, который генерится утилитами упомянутых выше соц.сетей.
Наш интерфейс:
namespace EAV.Controls
{
    interface ILayoutButton
    {
        string GetLayout(string url, string title, string description, string image);
    }
}
Создадим кнопки для следующих социальных сетей:
ВКонтакте
Обратимся к API.
Сформируем исходящую строку, согласно документации. Параметр url не указывает, т.к. хотим, чтобы брался текущий. Остальные значение получаем из переданных параметров и контекста страницы. Вот какой класс получился.
using System.Text;
using Microsoft.SharePoint;

namespace EAV.Controls
{
    public class VKontakteButton : ILayoutButton
    {
        public string GetLayout(string url, string title, string description, string image)
        {
            StringBuilder text = new StringBuilder();
            text.Append("");
            text.Append("");

            return text.ToString();
        }
    }
}
Обратите внимание, что внешний вид кнопки задаётся параметрами:
  • type: 'custom', 
  • text: 'тут наш html-код кнопки'
Согласно документации, можно добавить еще некоторые параметры. Но для нашей цели этого вполне достаточно.
Пока всё просто.

Twitter
С этой кнопочкой пришлось немного повозиться. Очень долго не мог избавиться от изображения "Твитнуть". Нашёл много всяких статей (см. ниже), которые направили меня на правильный путь решения проблемы. В итоге помогла ссылка №3. В итоге получился следующий класс
using Microsoft.SharePoint;

namespace EAV.Controls
{
    public class TwitterButton : ILayoutButton
    {
        enum type
        {
            none,
            horizontal,
            vertical
        }

        public string GetLayout(string url, string title, string description, string image)
        {
            string format = "";
            return string.Format(format, url, Utility.CutText(title, 120), type.horizontal.ToString());
        }
    }
}
Перечисление type используется для настройки места отображения количества лайков. Благодаря встроенному механизму коротких ссылок у Твиттера, я не прибегаю к сторонним сервисам. Твиттер сам укорачивает ссылки. И помня, что длина сообщения не должна превышать 140 символов, я текст сообщение урезаю до 120 символов, попутно убирая всё форматирование (лишние теги).

LiveJournal
Кросспост в LiveJournal не представляет особого труда. Чтобы был осуществлен кросспост, нужно всего навсего перейти по ссылке http://www.livejournal.com/update.bml?event={0}, где {0} - это закодированный html-код (с помощью HttpUtility.UrlEncode) того, как Вы хотите, чтобы данные выглядели в ЖЖ. Примерный класс выглядит так
using System.Text;
using System.Web;
using Microsoft.SharePoint;

namespace EAV.Controls
{
    public class LiveJournalButton : ILayoutButton
    {
        public string GetLayout(string url, string title, string description, string image)
        {
            string newsfoto = "";
            int height = 0;
            int width = 0;
            string NameSite = "";
            SocialButtons.GetPictureParameter(image, out newsfoto, out height, out width, out NameSite); //Функция получает изображение Новости, ширину и высоту изображения, а также имя сайта

            StringBuilder template = new StringBuilder("");
            if (!string.IsNullOrEmpty(image))
            {
                template.Append("");
            }
            template.Append("
\"\""); template.Append(""); template.Append(""); template.Append(""); template.Append("
"); string text2 = string.Format(template.ToString(), url, title, Utility.CutText(description, 250), //текст новости HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host, //ссылка на сайт NameSite, //Название сайта SPContext.Current.Web.Url + image, //Изображение для Новости width, height).Replace("\r\n", ""); //ширина и высота изображения Новости // Формат контрола на странице string format = @" "; return string.Format(format, HttpUtility.UrlEncode(text2).Replace("+", "%20")); } } }
Также стоит не забывать, что через адресную строку много текста не передашь, поэтому я ограничил длину сообщения 250 символами (без форматирования).
Facebook
На Сайте очень подробно описано API для создания кнопок. Но меня не устраивало то, что пригодилось встраивать iframe на страницу, плюс к тому же не достигалась цель - использование своей иконки. Мне понравился пример под №4 и я взял его за исходный. В итоге получился вот такой класс:
using System.Web;
using Microsoft.SharePoint;

namespace EAV.Controls
{
    public class FacebookButton : ILayoutButton
    {
        public string GetLayout(string url, string title, string description, string image)
        {
            return @"Share on Facebook";
        }
    }
}
Правда в таком варианте мне понабилось реализовать дополнительный функционал в виде Graph API для того, чтобы Facebook правильно считывал информацию, которую нужно публиковать. Для этого я создал новый модуль с одним единственным файлом Elements.xml


  

Данный механизм использует функционал DelegateControl у Sharepoint. В данном случаем используется тег

который размещен в теге head страницы. При активировании фичи с нашим Elements.xml на мастер-странице тег DelegateControl заменяется/дополняется содержимым того, что будет генерировать наш класс EAV.MetaTagger. А содержание класса несложное (регистрируем необходимые meta-теги из Graph API):
using System.Web;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using EAV.Controls;

namespace EAV
{
    public class MetaTagger : WebControl
    {
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            writer.Write(string.Format(@"", "bla"));
            writer.Write(string.Format(@"", "bla"));
            writer.Write(string.Format(@"", "bla"));
            writer.Write(string.Format(@"", "Russia"));
            writer.Write(string.Format(@"", "bla"));
            writer.Write(string.Format(@"", "bla"));
            writer.Write(string.Format(@"", "bla"));
            writer.Write(string.Format(@"", "bla"));

            SPContext context = SPContext.Current;
            if (context != null)
            {
                if (context.ListItem != null && context.List.RootFolder.Url == "Lists/News")//Для элемента новости пропишем дополнительные теги
                {
                    writer.Write(string.Format(@"", Utility.GetTextWithoutTags(context.ListItem["Title"] + "").Replace("\r\n", "")));
                    writer.Write(string.Format(@"", Utility.GetTextWithoutTags(context.ListItem["Lead"] + "").Replace("\r\n", "")));
                    writer.Write(string.Format(@"", SPContext.Current.Web.Url + context.ListItem["Logo"] + ""));
                    writer.Write(string.Format(@"", HttpContext.Current.Request.Url.AbsoluteUri));
                }
            }
        }
    }
}
Результат можно проверить в сервисе. Если всё правильно, то Facebook считает ваши значения со страницы. И тогда можно быть уверенным, что кнопка работает как надо.
Итоговый класс контрола
В итоге класс контрола выглядит так
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;

namespace EAV.Controls
{
    public class SocialButtons : WebControl
    {
        public override void RenderControl(HtmlTextWriter writer)
        {
            IList<ILayoutButton> buttons = new List<ILayoutButton>() { 
                new TwitterButton(),
                new VKontakteButton(),
                new FacebookButton(),
                new LiveJournalButton()
            };

            StringBuilder html = new StringBuilder(@"");
            foreach (ILayoutButton btn in buttons)
            {
                SPListItem item = SPContext.Current.ListItem;
                string url = HttpContext.Current.Request.Url.AbsoluteUri;
                string title = item["Title"] + "";
                string description = item["Lead"] + "";
                string image = item["Logo"] + "";
                html.AppendFormat(@"",
                    btn.GetLayout(url, Utility.GetTextWithoutTags(title).Replace("\r\n", ""), 
                        Utility.GetTextWithoutTags(description).Replace("\r\n", ""), image));
            }
            html.Append("
{0}
"); writer.Write(html.ToString()); base.RenderControl(writer); } public static void GetPictureParameter(string image, out string newsfoto, out int height, out int width, out string NameSite) { //тут мы должны получить ссылку на изображение, её размеры и название сайта } } }
Ссылки

  1. How to Add a Custom Twitter Button to Your Website
  2. Tweet Button
  3. How to create custom Twitter button with short URL
  4. Code to Create Custom Share Buttons for Facebook, Twitter, LinkedIn & Delicious
  5. Кнопки и виджеты социальных сетей для сайта
  6. FaceBook: How to Add a Like Button

Update (09.11.2011): Натолкнулся на интересное форматирование кнопки перепоста в ЖЖ на одном из сайтов и решил поискать документацию как сделать похожее. К сожалению, в ЖЖ такой документации не нашёл, зато увидел подробную инструкцию на многих сайтах. Суть заключается в том, что нужно сформировать тег
Плюс этого решения заключается в том, что нет ограничение для длину сообщения. Так что смотрите, что вам удобнее, то и используйте.

6 комментариев:

  1. Добрый день, имеется сайт-визитка на SharePoint, каким образом на него добавить плагин «Ищите нас на Facebook» ?

    ОтветитьУдалить
    Ответы
    1. Зависит от того каким функционалом должна обладать кнопка. Что требуется делать после того, как пользователь нажал на кнопку?

      Удалить
  2. http://developers.facebook.com/docs/reference/plugins/like-box/ не могу это прикрутить

    ОтветитьУдалить
    Ответы
    1. А что сложно в том, чтобы вставить содержимое скрипта в Content WebPart?

      Удалить
    2. Сложность в том, что я не умею это делать :-) если распишите, буду признателен.

      Удалить
    3. Нужно добавить веб-часть "Редактор содержимого" на страницу, открыть веб-часть на редактирование и вставить сгенерированный код отсюда http://developers.facebook.com/docs/reference/plugins/like-box/

      Удалить

Еще статьи

2leep.com