Powered by CodeIgniter

Уроки

(28)
14
16 голосов
Учиться, учиться и еще раз учиться — развитие личности идет таким путем.
Доброе утро, друзья, и хороших выходных!
Продолжаем серию уроков по запросам страждущих. Сегодня мы поможем bafoed реализовать бб-код [hide=x], идея о котором пришла к нему совсем недавно.
Реализация снова будет представлена в виде отдельной шестеренки. Попробуем осмыслить логически, что предстоить сделать:
  • Добавить кнопку в редактор (самое важное!)
  • Добавить правило для парсера
  • Проверить «на лету» баллы пользователя
Шестеренке надо дать имя, и, не мудрствуя, назовем ее hide.
Файловая структура будет обычная.

Файловая структура шестеренки Hide


Решим, что ББ-код будет доступен в двух ипостасях — с параметром и без. С параметром он будет показываться только тем, у кого рейтинг выше выбранной цифры, а без него — тем, кто зарегистрирован на сайте.
Поехали.

Файл конфигурации

title = Hide description = Hide BB-code, show inner content only to validated users group = plugins core = 1.x version = 1.0 enabled = TRUE position = 10 Обратите внимание на параметр position. Все шестеренки грузятся в порядке очереди, который определяется как раз этим параметром. Если вы хотите поменять их местами — поиграйтесь с ним.
В начала (позиции 0-5) грузятся компоненты ядра, поэтому рекомендую загружать свои труды уже после них.
В процессе создания этого урока, я забыл про этот параметр, и не мог понять около минуты почему же руки хуки шестеренки не дотягиваются до парсера. Все оказалось просто — парсер загружался позже. Я поменял их очередность, просто выставив position на 10, зная что парсер где-то в самом начале находится.

Файл перевода

[gears] hide = "Hide" hide_description = "Позволяет скрыть содержимое блока от незарегистированных пользователей или от тех, чья карма меньше указанного числа." [hide] button_help = "Скрыть текст." dialog = "Укажите минимальное значение рейтинга для просмотра блока. Оставьте поле пустым или нажмите Esc для сокрытия содержимого только от незарегистированных пользователей." alert_unreg = "Внимание! Вы не можете видеть содержимое блока до тех пор, пока не авторизируетесь или зарегистрируетесь на сайте." alert_rating = "Внимание! Вы не можете видеть содержимое блоко, в силу того, что ваш рейтинг меньше %d."

Стили

Файл /gears/hide/css/hide.css:
div.hide{ padding: 5px; border: 1px dotted #CCC; background: #EFEFEF; }

JavaScript

Обратите внимание, что в папке js мы создаем подпапку inline. Дело в том, что скрипты лежащие напрямую в js подхватываются движком автоматически и склеиваются в один файл на выходе. Нам же кнопка нужна только в редакторе, поэтому мы выносим скрипт в произвольным образом названную подпапку.
По аналогии с кнопкой Видео. Зайдем в шестеренку video и скопируем код оттуда, внеся соответствующие изменения.
Файл /gears/hide/js/inline/hide.js:
window.addEvent('domready',function(){ for(name in editor.editors){ var e = editor.editors[name]; e.addButton({hotkey:'h',background:'/gears/hide/img/editor-button.png',action:'hide("'+e.el.id+'")'}) } }); function hide(textarea){ var ed = editor.get(textarea); textarea = $type(textarea) == 'string' ? $(textarea) : textarea; var points = prompt(lang.hide.dialog,''); if(points){ ed.tag('[hide='+points+']','[/hide]'); } else { ed.tag('[hide]','[/hide]'); } }

Хуки

Основная работа, конечно же, происходит именно в хуках. На этот раз мы также обратимся в шестеренке video, чтобы не вспоминать долго и упорно, как же все работает.
Файл /gears/hide/_hooks.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CoGear * * Content management system based on CodeIgniter * * @package CoGear * @author CodeMotion, Dmitriy Belyaev * @copyright Copyright © 2010, CodeMotion * @license http://cogear.ru/license.html * @link http://cogear.ru * @since Version 1.1 * @filesource */ /** * Hide hooks * * @package CoGear * @subpackage Hide * @category Gears hooks * @author CodeMotion, Dmitriy Belyaev * @link http://cogear.ru/user_guide/ */ Cо вступлением все понятно.
/** * Add hide button to editor * * @param object * @return void */ function hide_editor_compile_after_($Editor){ if(acl('editor hide')){ js('/gears/hide/js/inline/hide',FALSE,TRUE); } } Хукнули редатор, добавили кнопку. Если правила editor hide не существует — оно будет создано автоматически. Правило чисто формальное — на отображение кнопки. ББ-код будет работать по-любому.
У функции js три параметра:
  • Путь к скрипту (можно опустить расширение файла) или код скрипта
  • Код скрипта или же ссылка на файл (в данном случае — последний вариант)
  • Отправлять на вывод или вернуть значение.

/** * Add parser rule * * @param object * @return void */ function hide_parser_construct_($Parser){ array_insert($Parser->process['textarea'],'parse_hide',5); array_insert($Parser->process['comment'],'parse_hide',5); } Все просто. Добавляем по правилу в конфиг парсера. Теперь надо создать саму функцию parse_hide.
/** * Parse hide * * @param string * @return string */ function parse_hide($value){ $CI =& get_instance(); // First case — with points measure // Parse preg_match_all('#\[hide=(\d+)\](.*?)\[\/hide\]#',$value,$matches); // If any matches if(!empty($matches)){ // Looping through the cycle for($i = 0; $i < sizeof($matches[0]); $i++){ // If user is authorized if($CI->user->is_logged){ // If points gear is enabled if($CI->gears->points){ // Compare points with input value or allow admin to view everything if($CI->user->get('user_group') == 1 OR $CI->user->get('points') >= $matches[1][$i]){ $replace = $matches[2][$i]; } // Show rating alert else { $replace = t('hide alert_rating',$matches[1][$i]); } } // If points gear is disabled — simply show text to any registred user else $replace = $matches[2][$i]; } // If user is unregistred else { $replace = t('hide alert_unreg'); } // Combine output value $value = '<div class="hide">'.str_replace($matches[0][$i],$replace,$value).'</div>'; } } // Second case — simple hide preg_match_all('#\[hide\](.*?)\[\/hide\]#',$value,$matches); // If there any matches if(!empty($matches)){ // Looping through data for($i = 0; $i < sizeof($matches[0]); $i++){ // If user is logged if($CI->user->is_logged){ $replace = $matches[1][$i]; } // Otherwise else { $replace = t('hide alert_unreg'); } // Combining value $value = '<div class="hide">'.str_replace($matches[0][$i],$replace,$value).'</div>'; } } return $value; }
Надеюсь, что простые комменты на английском доступны всем.

Заключение

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

13:33 ← 27 ноября 2010 Отправить в Твиттер adminadmin  RSS comments 6

Здесь пока ничего нет.

Комментарии (6) ↓

firestar firestar time 15:22 ← 27 ноября 2010 #
походу это really cool…
AlexHolmes AlexHolmes time 18:43 ← 27 ноября 2010 #
Круто, круто. Опечатка только есть:
alert_unreg = «Внимание! Вы не можете видеть содержимое блока до тех пор, пока не авторизируетесь или зарегистрируетесь на сайте.»
alert_rating = «Внимание! Вы не можете видеть содержимое блоко(а?), в силу того, что ваш рейтинг меньше %d.»
inetlover inetlover time 22:50 ← 27 ноября 2010 #
Классный урок! Спасибо! Пригодиться однозначно.

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

Хочу спросить, а чем переменная %d отличается от переменной %s из языкового файла?
Автор
admin admin time 22:53 ← 27 ноября 2010 #
%d — число.
%s — строка.

Почитай доку к sprintf.
inetlover inetlover time 22:59 ← 27 ноября 2010 #
Спасибо, почитаю.
bafoed bafoed time 22:37 ← 10 января 2011 #
спасибо :)