+9.35
Рейтинг
20.17
Сила

Юрий Сергеев

Рекомендация к использованию: Наследование шаблонов

На примере будущего jQuery-шаблона для ПриветСочи.ру решил выложить мини-инструкцию использования наследования шаблонов, сильно сокращающий количество часто повторяющегося Smarty-кода.

Коротко о файлах в примере (ссылка на архив внизу):

  • topic.prototype.tpl — прототип топика, содержащий всю повторяющуюся разметку. Использованы вложенные конструкции типа
    {block name=...}
  • topic_link.tpl, topic_photoset.tpl, topic_question.tpl, topic_topic.tpl — файлы, наследующие и заменяющие/дописывающие некоторые блоки прототипа топика (topic.prototype.tpl)
  • topic.social.tpl — включение с кодом кнопочек публикации в разные соц-сети.


Коротко о содержании файлов:

Посмотрев файлы примера, не сложно заметить, что файлы topic_*.tpl содержат:
  1. в начале каждого файла наличиствует код
    {extends file=topic.prototype.tpl}
  2. минимум специфической разметки, обрамленной в конструкции
    {block name=... флаг}
    — это замены и дополнения блоков. Флаг может либо отсутствовать (что означает полную замену содержимого блока), либо принимать принимать значения:
    • append — дописывает в конец содержимое блока к наследуемому блоку.
    • prepend — дописывает в начало содержимое блока к наследуемому блоку.
    • hide — скрывает блок (насколько я понял, если добавить в блок прототипа, то по умолчанию блок будет скрыт).
    • nocache — запрещает кеширование содержания блока (а это вообще актуально для LS?).


Документация


ZIP-архив с примером

Репозитории бесплатных расширений

Что здесь?

Стихийный список открытых репо на github и google-code (и прочих), в которых можно принять участие (форкнуть, модифицировать).

Оставляйте в комментах ссылки, а я буду добавлять их в топик.

Оглавление


Читать дальше →

ORM для встроенных модулей

Пока еще модули Topic, Comment, User… не являются наследниками ORM классов, а зачастую хочется использовать преимущества ORM в плагинах, дополняющих данные модули. Скажем релейшены.

Конечно, можно отредактировать класс модуля жестко:
заменить
extends Module

на
extends ModuleORM

Только придется прописывать еще в методе Init():
parent::Init();

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

Читать дальше →

Правильный способ модификации enum в плагинах.

Проблема заключается в том, что некоторые плагины заменяют поле target_type таблицы comment, тем самым создавая свои новые типы комментариев, но затирая при этом уже добавленные. Разработчики упрощают себе жизнь, ограничиваясь строкой в dump.sql (пример из плагина «компании»)
ALTER TABLE `prefix_comment` 
	MODIFY target_type enum('topic','talk','company','clan') 
	DEFAULT 'topic';

В список риска попадает практически всё, где используется target_type enum: favourite, vote, comment_online.

При установки нескольких таких плагинов начинается бардак. Такие недоработки я заметил в следующих плагинах: «Компании», «Объявления», «Вопросы и ответы», «Места и события». Так делать нельзя. Программист разберется и исправит ошибку, но что делать обычным людям, далеким от php и sql, которые просто используют движок и несколько таких плагинов?

Тру кодером оказался Алексей Волков, разработчик «Комментариев для статических страниц». При установке плагина он в функции Activate проверяет target_type и добавляет новое поле только если его там нет, сохраняя при этом его старое содержимое. Не спросясь разрешения Алексея (надеюсь он меня простит — за правое дело радею) выкладываю часть кода, отвечающего за это.

$oDb = $this->Database_GetConnect();
$sql = 'SHOW COLUMNS FROM  `'.Config::Get('db.table.comment').'`';
$aRows = $oDb->select($sql);
foreach ($aRows as $aRow) {
	if ($aRow['Field'] == 'target_type') break;
}

if (strpos($aRow['Type'], "'page'") === FALSE)
{
	// - Вносим изменение в поле target_type в таблице prefix_comment
	$aRow['Type'] =str_ireplace('enum(', "enum('page',", $aRow['Type']);
	$sql = "ALTER TABLE `".Config::Get('db.table.comment')."` 
		CHANGE `target_type` `target_type` " . $aRow['Type'] . " 
		NOT NULL DEFAULT 'topic'";
	$oDb->query($sql);
} 


Уважаемые разработчики, не поленитесь обновить свои плагины и внести изменения.

Хотел опубликовать в тематическом блоге, например в «Дополнительные модули и доработки для LiveStreet», но видимо не хватает кармы, это мой первый пост/комментарий вообще на livestreet.ru

PS. в sql запросах типа ALTER проще использовать MODIFY вместо CHANGE, т.к. первый не требует указывать название поля два раза.

Свой блок 4.2 на примере блока популярных записей

Это лишь пример того, что нужно сделать, чтобы добавить свой блок в 4.2

config.php
$config['block']['rule_tops'] = array(
	'action'  => array('index','top'),
	'blocks'  => array( 'topper' => array('avas'=>array('priority'=>1000))),
);


Читать дальше →

История про нагрузку и как я с ней боролся.

Случилось так, что на одном из проектов full time стал переваливать за 1,5 сек и при этом сжирался весь проц. При этом все остальные показали были в норме: база — 0,002 сек, кеш — 0,01 сек.

Пришлось прикручивать профайлер и смотреть, в чем дело.

Виноват оказался Smarty, который из 1,5 секунд работал 1,2 (шаблон, на проекте, используется стандартный с легкими изменениями).

Копаясь дальше нашел самый сложный шаблон comments_tree.tpl, который выполняет в цикле инклюд шаблона comment.tpl.

Проблема решилась отказом от инклюда и переносом содержимого из comment.tpl в comments_tree.tpl.

full time на топиках с 400+ комментариев не превышает 0,4 сек.

Надеюсь кому-то поможет.

Два сайта на одном движке (решено)

Как известно, фреймворк CodeIgniter позволяет использовать один движок для создания нескольких сайтов. Возможно-ли такое с Livestreet? Может быть кто-то уже реализовал такое? У меня 2 проекта на одном хостинге на разных доменах используют каждый свой движок. Сейчас возникла идея еще одного проекта. Хотелось бы использовать один движок для всех трех.
Читать дальше →

Подключение js файлов из конфига плагина

Всем привет

Создал директорию плагина, в ней файл config/config.php
Config::set('head.rules.crop',array(
    'path' => Config::get('path.root.web').'/settings/profile/',
    'js' => array(
        'include' => array(
            Config::get('path.plugins').'/crop/external/cwcrop/ysr-crop.js'
        )
    ),
));
return $config;

Файл не подключается
И как можно подключить файл для всех страниц с использованием конфига плагина?

Новые возможности по переопределению/наследованию классов LiveStreet

В LS появилась новая возможность для разработчиков плагинов — наследование классов. Идея была высказана еще avadim'ом здесь.
Эта возможность позволит удобно переопределять различные методы одного класса (модуля, экшена, сущности, маппера) разными плагинами без конфликтов.
Главное отличие от делегирование — не происходит блокировки переопределения класса для других плагинов. Также есть возможность переопределения одного метода разными плагинами, но здесь разработчикам нужно быть очень осторожными и делать так, чтоб свести вероятность конфликта к минимуму.

Как использовать.
Например, нужно переопределить метод получения пути до аватара у сущности пользователя в плагине Test. В плагине необходимо объявить те классы, которые будут наследоваться. Объявление происходит в свойстве $aInherits:
<?php
class PluginTest extends Plugin {
    
    protected $aInherits=array(
       'entity'  =>array('ModuleUser_EntityUser'=>'_ModuleSide_EntityUser')
    );

    public function Activate() {        
        return true;
    }
    
    public function Init() {        
    }
}
?>

Читать дальше →