Продолжаем серию уроков по запросам страждущих. Сегодня мы поможем bafoed реализовать бб-код [hide=x], идея о котором пришла к нему совсем недавно.
Реализация снова будет представлена в виде отдельной шестеренки. Попробуем осмыслить логически, что предстоить сделать:
- Добавить кнопку в редактор (самое важное!)
- Добавить правило для парсера
- Проверить «на лету» баллы пользователя
Файловая структура будет обычная.
Решим, что ББ-код будет доступен в двух ипостасях — с параметром и без. С параметром он будет показываться только тем, у кого рейтинг выше выбранной цифры, а без него — тем, кто зарегистрирован на сайте.
Поехали.
Файл конфигурации
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) грузятся компоненты ядра, поэтому рекомендую загружать свои труды уже после них.
В процессе создания этого урока, я забыл про этот параметр, и не мог понять около минуты почему же
Файл перевода
[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 подхватываются движком автоматически и склеиваются в один файл на выходе. Нам же кнопка нужна только в редакторе, поэтому мы выносим скрипт в произвольным образом названную подпапку.По аналогии с кнопкой
Файл /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 можно дополнить функционал вашего сайта.


Вот еще бы алгоритм рейтинга доработать, например за пост попавший на главную юзер получает дополнительные баллы — это из разряда стимулов к активному постописательству.
Хочу спросить, а чем переменная %d отличается от переменной %s из языкового файла?
%s — строка.
Почитай доку к sprintf.