Ne v kontakte Asocial programmer's blog

Аспекты реализации нового движка блога

Feature image

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

Технические требования

  • Язык программирования: PHP 5.1+ В принципе, я мог бы себе позволить и использовать PHP 5.3, мигрировав блог на мою VPS, но я не вижу в этом большой необходимости, тем более, что хостинг от EOMY за много лет показал себя с лучшей стороны.
  • СУБД: MySQL. Здесь выбор тоже практически очевиден: MySQL есть на любом хостинге и мне привычно с ним работать.
  • Фреймворк: Yii Framework Выбор фреймворка — тема не простая, так что ее я прокомментирую отдельно.
  • Миграция и обратная совместимость: весь контент должен быть перенесен и адаптирован к новому движку, все ссылки в постах должны остаться действующими, со старых URL постов должен быть редирект на соответствующие новые.

Yii Framework

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

Помимо этого есть еще плюсы в его копилку:

  • Фреймворк сам по себе написан очень хорошо и работает быстро
  • Фреймворк быстро развивается и не отягощает себя поддержкой устаревших технологий (камешек в сторону CakePHP)
  • Есть внушительный централизованный репозиторий расширений, которые реализуют наиболее сложные фитчи “из коробки”.
  • Наконец, есть базовый скелет блога на Yii, на написании которого построен официальный тьюториал. Кроме того, я нагуглил довольно много попыток развить эту основу до состояния нормального движка, которые надо внимательно изучить и, возможно, взять за основу.

Этот вечер я посвятил просмотру репозитория расширений и нашел там много полезного для себя и будущего движка :-)

С чего начать?

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

  • Bliig — произвел на меня наиболее положительное впечатление, судя по всему более-менее серьезная разработка.
  • YiiBlog — развитие Yii Blog Demo с официального сайта. Суда по всему, автор, как и я, затачивает его исходя исключительно из собственных пожеланий, которые немного расходятся с моими. Но все же он заслуживает рассмотрения, хотя и во вторую очередь.
  • Yii BlogDemo Extended — другая попытка развить демо-приложение блога. К сожалению, развитие не имеет четкого направления и поэтому в нем появилась такая глупость как флеш-часы. Кроме того, проект уже год никак не развивается, поэтому он пригоден разве что для подсматривания идей решения разных задач, но не как полноценная основа.
  • YiiApp — попытка содать универсальный каркас приложения на Yii. Попытка, судя по всему, достойная, но для меня не очень подходящая.
  • yay-cms — простая CMS на базе Yii. В качестве основы для блога подходит плохо, но в отношении создания обычных сайтов проект интересный, поэтому заслуживает упоминания.

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

Внимательное изучение этих проектов мне, видимо, еще предстоит, но я вижу два наиболее вероятных варианта:

  1. Взять за основу Bliig и танцевать от него.
  2. Взать за основу официальное демо, а найденные проекты использовать как шпаргалки для подсматривания решений.

Open Source

Я до сих пор еще не принял окончательного решения, но скорее всего движок будет приватным по двум причинам:

  1. Я не хочу тратить время на оказание поддержки по движку.
  2. Я допускаю, что в движке могут быть баги. Потенциальным взломщикам будет гораздо легче их найти, если исходники будут общедоступны.

Техзадание для движка блога

Feature image

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

За эти три года я достаточно много работал с Drupal’ом и могу с чистой совестью подтвердить: из него можно построить сайт абсолютно любой сложности и с любым мыслимим и немыслимым функционалом. Засада лишь в том, что такая мощь мне на этом блоге не нужна, тем более, что за нее приходится платить тяжеловесностью сайта. Поэтому в качестве отправной точки я решил составить список требований которые я предьявляю к движку блога. Этому и будет посвящен пост.

Общее назначение движка

Движок предназначен для ведения (преимущественно) однопользовательских персональных блогов.

Пользовательская система

  • Движок должен поддерживать многопользовательскую модель.
  • Контроль доступа с помощью механизма ролей. Набор ролей фиксирован: админ, блоггер, комментатор.
  • Анонимный пользователь имеет роль комментатора.
  • Желательна поддержка авторизации как по логину-паролю, так и через сторонние сайты (Twitter, Google, Open ID). Оптимально, если будет возможность привязки к одной учетке нескольких методов авторизации.

Размещение постов и создание статических страниц

  • Движок должен позволять публиковать посты и статические страницы, с разметкой в HTML.

  • Пост включает в себя следующие параметры:

    • Заголовок поста
    • Тело поста
    • Дата публикации
    • Автор
    • Состояние: опубликован или черновик
    • Имя поста для URL
    • Поле для традиционного видеоролика в конце поста
    • Теги
  • Визуальный редактор CKEditor полным набором панелей инструментов.

  • Загрузка файлов и изображений через интерфейс редактирования поста. Желательна интеграция с CKEditor.

  • Создание миниатюр изображений. Желательно иметь возможность задавать размер миниатюр, если “умолчальный” размер не подходил, либо просто отключать миниатюры для конкретных изображений.

  • Планирование постов. Если у поста статус “опубликован”, но дата публикации — в будущем, то он не будет отображен до наступления даты публикации.

  • Блоггеры должны видеть неопубликованные записи, все остальные - нет.

  • Черновики и отложенные записи должны визуально отличаться от обычных постов и друг от друга.

  • Включение/отключение комментирования для конкретных постов.

  • Желательно автосохранение черновиков как в WP.

  • Посты должны быть доступны через RSS.

  • Разделение на тизер и основной текст не требуется.

  • Поддержка размещения листингов кода с соответствующей подсветкой.

Комментирование

  • Возможность комментировать посты и страницы, для которых это не было запрещено.

  • Желательна поддержка древовидных комментариев

  • Комментатор может указать свой ник, сайт и email, все, кроме ника - не обязательно.

  • Желательна возможность логиниться прямо при комментировании.

  • Комментатору доступен ограниченный набор html тегов.

  • Форма добавления комментария имеет визуальный редактор с набором инструменов, ограниченным набором разрешенных тегов.

  • В форму комментирования встроен антиспам, невидимый для пользователей со включенным JavaScript.

  • Возможна подписка на комментарии по email.

  • Для блоггеров каждого комментария должны быть дополнительные опции:

    • Редактировать
    • Удалить
    • Удалить ссылку на сайт комментатора (для упрощения выноса спамовых ссылок)
    • Удалить все ссылки из текста поста.
  • Желательно иметь возможность детектирования скрытых ссылок в комментариях.

  • Желательно экспортировать комментарии в RSS

Многоязычность

  • Интерфейс должен поддерживать как минимум два языка: английский и русский.
  • Весь контент может быть привязан к одному из языков. Если привязка не задана, он отображается для любого языка.
  • Комментарии наследуют языковую привязку от поста или страницы, к которой они относятся.

Интерфейс

  • Шаблон должен быть отделен от логики и быть максимально простым.

  • Должна быть поддержка управления верхним меню и меню в сайдбаре.

  • Сайдбар справа.

  • Следующие виджеты должны присутствовать в сайдбаре:

    • Редактируемое меню
    • Облако тегов
    • Блогролл
    • Архив по месяцам
    • Последние комментарии и посты
  • Комментарии располагаются под постом.

  • Форма добавления комментария - под всеми комментариями.

  • У каждого комментария есть кнопки “Ответить” и “цитировать выделенное”.

  • На главной и на страницах отображения тегов должно присутствовать разбиение на страницы.

  • Поддержка вида для печати

  • Желательно редактирование постов и комментариев в упрощенном режиме с помощью ajax

  • Желательно удаление комментариев через ajax

  • Интерфейс должен приемлемо вести себя при отключенном JS или CSS

Требования к ядру

  • Кэширование всего, чего можно.
  • Желательна оптимизация CSS и JavaScript.
  • Желательно правильное и автоматическое расставление мета-тегов <meta name="robots">, <link rel=”alternate” type=”application/rss+xml”> и <link rel="canonical">
  • Генерация xml-карты сайта, содержащей ссылки на:
    • Главную
    • Посты
    • Статические страницы
    • Страницы тегов

Итог

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

Жизнь со вкусом

Feature image

Этот пост несколько выбивается из общей канвы блога, но я просто не могу промолчать. Что нужно настоящему программисту для счастливой жизни? Думаю, все согласятся, что в этот список точно входят интересная работа, комфорт дома и на рабочем месте и, конечно же, вкусная еда, приготовленная любимой девушкой. Вот о последнем и пойдет речь.

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

Извиняюсь перед теми, кто читает и думает «Ну хватит уже душу травить!», и перехожу к содержательной части. С этого момента все те вкусные рецепты, о которых я только что говорил, иллюстрируются и публикуются заботливой Олиной рукой лапой на ее кулинарном блоге. Так что все голодные программисты России могут вооружаться посудой и ссылкой на блог и приступать к изготовлению вкусной и полезной еды для себя любимых. Или, если вам повезло так же, как и мне, вооружать своих девушек. А если вы не будете забывать им помогать (с мытьем посуды, например), то у вас все шансы вкусно кушать не только по большим праздникам :-)

Ну и для затравки опубликую несколько фотографий блюд, приготовленных по этим рецептам (заголовки кликабельны).

π-рог

w_a58301a4.jpg

Песочное печенье «Пески Времени»

w_05790914.jpgw_90344263.jpg

Бисквитный тортик

w_b0163c67.jpg

Мини-тортики по-кошачьи

А это вообще эксклюзив, рецепт пока не опубликован ;-)

w_9cb4c53e.jpgw_c292f04f.jpg

 И просто немного капучино.

w_485ebc31.jpg

Длинная задержка перед запросом пароля в SSH

Микро-заметка для себя и для тех, кто столкнется с аналогичной проблемой.

Симптоматика

При попытке подключиться к удаленному хосту по ssh между установлением соединения и запросом пароля возникает длинная пауза (секунд 15-30). Она может появляться и пропадать в зависимости от того, из какой сети вы подключаетесь, однако никак не корреллирует со скоростью доступа.

Решение

В файле /etc/ssh/sshd_config установить следующие параметры:

GSSAPIAuthentication no

После этого неприятная пауза исчезнет.

Собираем bash, запускающийся где угодно.

Feature image

Ну, если быть честным, то не совсем где угодно, а на любом дистрибутиве линукса. Возможно, так же заработает и на других *NIX системах, хотя я в этом и не уверен: проверить не на чем, а знание матчасти в этом отношении подкачало.

И так, наша цель собрать минималистичный bash свежей версии, без зависимостей и не требующий установки, чтобы потом запускать его с флешки или, как в моем случае, для выполнения скриптов для bash 4 в условиях CentOS 5.5, поставляющегося с ископаемым bash 3.2.

Кстати, только сегодня узнал, что на той неделе вышел CentOS 5.6, с более актуальными версиями софта, но в моем случае это ничего не меняет.

Для пущего осложнения жизни собирать будем 32-битный bash (чтобы запускался и на 32-х и на 64-х битах) в 64-битной Ubuntu.

Далее, пошаговые инструкции:

  1. $ sudo apt-get install build-essential gcc-multilib Это мы устанавливаем инструменты для сборки + библиотеки для кросс-компиляции под x86 (помним, что Ubuntu у нас x86_64 и компилятор в ней по дефолту тоже 64-битный).
  2. $ wget http://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz && tar -xzf bash-4.2.tar.gz && cd cd bash-4.2/ Качаем и распаковываем исходники bash. Я привел ссылку на актуальную на момент написания этого поста версию, однако возможно, вам в будущем захочется bash 4.3 или даже 5.0 ;-)
  3. $ export CC="gcc -m32" CFLAGS="-m32" Это и есть главная хитрость, необходимая для сборки 32-битного bash. То ли я не до конца разобрался, то ли у них Makefile корявый, но каждой из этих опций по отдельности недостаточно для сборки не под текущую архитектуру. Равно как и не работают параметры –host и –target у скрипта ./configure.
  4. $ ./configure --enable-static-link --without-bash-malloc Конфигурируем сборку. Параметр –enable-static-link требует статически линковать исполняемый файл с необходимыми библиотеками, тем самым минимизируя зависимости, а –without-bash-malloc устраняет один не вполне понятный для меня конфликт при линковке. Так же возможно вам захочется добавить свои параметры, включив дополнительный функционал. В моем случае нужен был –enable-array-variables, ради которого все и затевалось.
  5. $ make Собираем :-) Если у вас многоядерный процессор, можно добавить параметр -j N, где N - количество параллельных потоков сборки. Обычно его рекомендуют ставить равным удвоенному количеству реальных ядер. Кстати, в моем случае этот параметр существенно ускорил сборку, так что игнорировать его не стоит.

Если все шаги завершились успешно, то мы должны получить в текущем каталоге исполняемый файл bash, о котором утилита file должна говорить примерно следующее:

1
2
3
$ file bash

bash: ELF **32-bit** LSB executable, Intel 80386, version 1 (GNU/Linux), **statically linked**, for GNU/Linux 2.6.15, not stripped

Обратите внимание на выделенные жирным фрагменты. Если они отличаются, то значит при сборке что-то пошло не так, и bash собрался 64-х битный, либо со внешними зависимостями.

Если хочется, можно немного уменьшить размер бинарника, сделав $ strip bash.

У меня это дало экономию аж в 202365 байта.

Теперь этот файл можно копировать куда угодно и запускать, а он должен работать.

Прощай, FriendFeed

Удалил нафиг ленту блога из френдфида. Хочу видеть реальное количество подписчиков. А заодно и сам аккаунт на френдфиде снес, все равно пользоваться так и не научился.

Удобная разработка букмарклетов

В процессе работы над Pastemark (пост-анонс) мне понадобилось, во-первых, написать довольно сложный букмарклет и, во-вторых, сделать динамическую генерацию букмарклетов с разными параметрами. Не возьмусь претендовать на новизну, а лишь просто поделюсь найденным мною подходом.

О букмарклетах

Для тех, кто с ними еще не сталкивался с букмарклетами, букмарклет — это разновидность закладки, но от обычной закладки он отличается тем, что вместо адреса страницы в ней записан скрипт, как правило не очень большой.

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

Кроме того, букмарклет — это практически единственный шанс для честного вебмастера выполнить свой код в контексте чужого сайта (-:

 Когда нужно писать букмарклет?

Собственно, ответ уже дан в предыдущем параграфе. Фактически, букмарклет занимает промежуточную роль между скриптами на сайте и расширением браузера: его функциональность все еще ограничена по сравнению с полноценным расширением, но он уже не привязан к какому-то одному сайту. Еще одна приятная сторона — один и тот же букмарклет может работать во всех браузерах сразу, включая те, которые не поддерживают расширения как таковые (реверанс в сторону мобильных браузеров).

Так как же его написать?

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

Мы все привыкли писать нормальные JS-функции, пользуясь IDE или просто блокнотом, а букмарклеты требуют от нас вытягивать весь код в одну строчку да еще и экранировать, что довольно муторно. Поэтому логично переложить эту работу на программу, а еще лучше — позволить программе самой себя приводить в нужный вид.

И так, прежде всего, нам нужно написать функцию, из которой мы будем делать букмарклет. Здесь нам все близко и знакомо, лишь только вместо привычного синтаксиса

1
2
3
function my_bookmarklet() {
  /* ... */
}

Мы прибегнем к альтернативному варианту:

1
2
3
var my_bookmarklet = function (arg1, arg2) {
  /* ... */
};

Это связано с тем, что в букмарклете нам нужна не именованная функция, а анонимная, чтобы не засорять пространство имен и избежать конфликтов.

Генерация итогового букмарклета

После того, как мы написали функцию, нам нужно превратить ее в букмарклет. Краткости ради я сразу приведу фрагмент кода, выполняющий эту функцию:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// Ключевой момент: делаем из анонимной функции строку с ее исходниками.
var code = my_bookmarklet.toString();
// Вырезаем однострочные и многострочные комментарии.
code = code.replace(/\/\/.*/g, "");
code = code.replace(/\/\*[\s\S]*\*\//, "");
// Заменяем переносы строк пробелами
code = code.replace(/\n/g, " ");
// Вырезаем повторяющиеся пробелы.  Если у вас внутри строковых литералов
// есть повторяющиеся пробелы, то этого лучше не делать.
code = code.replace(/\s+/g, " ");
// Генерируем uri, при этом экранируем спецсимволы.
var link = encodeURI(
  "javascript:void(" +
    code +
    '("' +
    value_for_arg1 +
    '", "' +
    value_for_arg2 +
    '"))'
);

Обратите внимание на переменные value_for_arg1 и value_for_arg2. Если вам нужно (как в моем случае) генерировать параметризованные букмарклеты, то вы можете это легко реализовать, передавая параметры вашей анонимной функции.

Далее с переменной link можно делать все, что хотите — генерировать и вставлять на страницу ссылку с этим значением href, отображать просто так или что вам еще в голову придет.

Грабли

Есть только одни грабли, на которые легко попасться в процессе написания букмарклета таким способом: ни в коем случае нельзя пользоваться какими-либо функциями или переменными, объявленными вне экспортируемой функции, ведь во время исполнения букмарклета (а это почти наверняка произойдет не на вашем сайте и в чужом окружении) все они доступны не будут. Я, кстати, на эти грабли тоже наступил, правда, довольно быстро это обнаружил и исправился.

Итог

В качестве итога еще раз перечислю все бонусы, которые мы получаем при разработке букмарклетов таким способом:

  1. Правильно форматированный код.
  2. Возможность спокойно писать код в вашей любимой IDE.
  3. Простота тестирования - вы можете в считанные секунды сгенерировать тестовый букмарклет и запустить его, не тратя время на его переформатирование оформление.
  4. Возможность динамически генерировать букмакрлеты с разным поведением, за счет использования параметров.

Честно говоря, долго не мог выбрать, какую песню вставить, эту или The Illusionist. Рекомендую обе, они обалденные :-)

Pastemark: перестаем печатать одно и то же!

Feature image

Вот и пришло время анонсировать мини-проект, над которым я работал последнее время.

Предыстория

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

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

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

Идея

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

Для удобства использования я на коленке набросал простенький генератор «для себя». Он принимал id поля и текст, выдавал — ссылку-букмарклет. Потом пришли мысли о том, что не всегда можно найти поле по id и была добавлена поддержка атрибута name, а потом еще и выбор по клику. О генераторе, кстати, будет отдельный пост.

Чем дальше я совершенствовал инструмент, тем больше мне хотелось сделать из него что-то общеполезное, и в итоге я решил сделать из него микро-вебсервис и заодно поупражняться в свистелках и перделках верстке и JavaScript.

Pastemark.

Название сервиса было образовано из двух слов ­— «paste» и «bookmark» (и тут же было переведено моей девушкой на русский как «пастомарка» (-: ).

Вот что в итоге этот сервис умеет:

  1. Автоматическая генерация букмарклета с заданным названием и вставляемым текстом.
  2. Возможность выбора целевого поля по id, name или кликом мыши.
  3. Простой инструмент для автонастройки генератора на нужное поле, тоже выполненный в виде букмарклета. (Бета-тестирование показало, что люди, далекие от веб-разработки совершенно теряются в том, как задать целевое поле).

За кулисами

Поскольку в своей работе я занимаюсь сервер-сайд программированием, этот проект стал для меня хорошим шансом разнообразить дела и поупражняться в верстке и клиентских финтифлюшках. Поэтому в итоге получилось, что основу сервиса я написал за два неполных вечера, а потом еще неделю оттачивал дизайн и лепил маленькие, но удобные плюшки. Например, сайт умеет подсказывать пользователю, что есть более удобная ему локализация, основываясь на содержимом заголовка Accept-Language. И таких мелочей получилось довольно много, что доставило мне массу удовольствия в процессе написания и тестирования :-)

Разместил я новый сервис, кстати на vps от eomy.netреферралкаво имя вселенской жадности). Правда о vps я сказал не просто ради пиара, а чтобы поделиться своей находкой. Недавно я открыл для себя очень интересный веб-сервер cherokee, просто подкупившим меня своею легковесностью и изумительным веб-интерфейсом для его настройки. Уверен, будущее именно за таким софтом - свободным, быстрым и юзабельным.

Я жив

Я не умер, не забил, не подался в отшельники :-)

Причина для молчания довольно банальна — в моей жизни наступил довольно интересный период, который поедает массу времени, почти не оставляя времени на блог. Беда в том, что есть масса тем, на которые я хотел бы написать, но они все довольно емкие и требуют времени, которого вечно нет.

Стыд и позор, но последняя запись в этом блоге датируется аж ноябрем и это надо исправлять, чем я и постараюсь заняться. Я даже немного приоткрою завесу тайны и скажу, что это будет цикл статей по внутреннему устройству phpBB с точки зрения модописателя. Естественно, будут посты и на другие темы.

Кодекс саппортера.

Вступление

Сила мира open source — сообщество. Фокус силы — его ядро, те, кто поддерживают, развивают свой любимый продукт. И помогают другим полюбить его. Я пишу для тех, кто волей судьбы стал таким человеком, добровольно взвалив на себя тяжелый труд тех поддержки.

Мы — гики

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

Пользователь заслуживает уважения

Какие бы глупые вопросы он не задавал. Я готов поспорить, что любой из нас начал свое знакомство с IT с глупого вопроса. И на этот вопрос был дан понятный ответ. Прошедшие годы ничего не изменили, и новички по-прежнему имеют право на понятный ответ.

Практически

Уважай себя. Делай так, чтобы тебя уважали другие. «Боятся — значит уважают» — это не про нас. Да и вообще ни про кого, если уж на то пошло.

  1. Будь корректен, ты пример для всех.

  2. Эмоции — плохой помощник, они отвлекают от дела.

  3. Знаешь ответ — ответь. Не знаешь — промолчи. Не уверен, скажи об этом прямо или запроси нужную дополнительную информацию.

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

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

  6. Если времени нет, просто молча пройди мимо. У кого-нибудь другого оно найдется и все будут довольны.

  7. Если кто-то ответил неправильно, поправь и объясни, почему его ответ неправильный. Аргументы в духе «ты идиот и кругом неправ» не канают.

  8. Иди на контакт. Не бойся общаться в личке, если это требуется для решения проблемы. Пользователю будет приятно, что тебе небезразлична его проблема, а тебе — что пользователь будет тебе благодарен.

  9. Если тебе хамят, будь еще корректнее. Умение вежливо отвечать на грубость даст тебе лишь преимущество. Напрашивается на бан — забань, но вежливо и согласно правилам.

  10. Наказывай всех. Если кто-то нарушил правила, то он должен получить наказание, независимо от репутации и стажа.

  11. Будь снисходителен. Если ты видишь, что нарушение несущественно и сделано неумышленно, просто объясни пользователю в личке, в чем он нарушил правила и, что больше так не надо делать.

    Это очень важное правило! Я неоднократно убеждался, что пользователи после такого обращения начинают гораздо тщательнее придерживаться правил, чем после бана или ворнинга. Так же важно это обращение делать именно в личке, ибо всякому будет обидно, если его огрехи будут обсуждаться публично. Найти золотую середину между этим и предыдущим пунктом непросто, но очень важно.

  12. Позволь пользователю исправиться и сними наказание. Для тех, кто нарушил правила не со зла это будет очень хорошим стимулом придерживаться правил.

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

  14. Другие будут уважать тебя тогда и только тогда, когда ты уважаешь других. Так устроен мир.

Если пользователи — дятлы

…то проблема скорее всего в тебе. Не спорю, очень достает отвечать на одни и те же вопросы, но такова твоя обязанность. Если сил больше нет — возьми тайм-аут, отдохни, пока не будешь готов снова и снова давать ссылки на фак. Возможно, этот тайм-аут окажется длинной на всю оставшуюся жизнь, но в этом нет ничего страшного, надо уметь вовремя уйти. Свои нервы дороже.

Я уже постил эту песню, но позволю себе нарушить традицию и вставлю ее еще раз, уж очень она хорошо подходит к ситуации.