[EVO] Расширение настроек сайта

Многие любят и активно юзают настройки сайта через [ [getField?name=`tv_name` ....] ]], создавая ресурс где все эти настройки в TV лежат. Но вот незадача, каждая такая настройка = 1 запросу, а значит и время генерации больше + неудобно.

А что если делать также, но вызов на странице будет [(cfg_footer_phone)], [(cfg_icq)] и тд… удобно правда…

Решение: CfgTv


//<?php
/**
 * CfgTv 0.1
 * Save TV as system setting from some resourse 
 * 
 *
 * @category    plugin
 * @version     1.0.0b
 * @author		  Bumkaka
 * @internal    @properties &ids=ID ресурсов настроек;text;347 &prefix=Префикс;text;cfg_
 * @internal    @events OnBeforeDocFormSave
 * @internal    @modx_category Manager and Admin
 */

$e =& $modx->event;
switch ($e->name ) {
    case 'OnBeforeDocFormSave':
  		$list_id=explode(',',$ids);
  		if (!in_array($_POST['id'],$list_id)) return;
  		$SQL="SELECT * FROM ".$modx->getFullTableName('site_tmplvars').";";
  		$result=$modx->db->query($SQL);
 			while($row=$modx->db->getRow($result)) {
        $TVNAME[$row['id']]=$row['name'];
      }
  		foreach($_POST as $key=>$value){
        	if (substr($key,0,2)!='tv') continue;
        	$id=substr($key,2,strlen($key));
        	$name=$prefix.$TVNAME[$id];
        	$settings[$name]=$value;
        	$SQL="SELECT * FROM ".$modx->getFullTableName('system_settings')." WHERE `setting_name`='".$name."'";
        	$count=$modx->db->getRow($modx->db->query($SQL));
        if (!empty($count['setting_name'])){
    			$SQL="UPDATE ".$modx->getFullTableName('system_settings')." SET `setting_value`='".$value."' WHERE `setting_name`='".$name."'";
        	$modx->db->query($SQL);
        } else {
          $SQL="INSERT into ".$modx->getFullTableName('system_settings')." SET `setting_name`='".$name."',`setting_value`='".$value."'";
        	$modx->db->query($SQL);
        }
  		}
    break ;
}


на событие OnBeforeDocFormSave. и наслаждаемся.

Если возникает потребность передать снипетту параметр с помощью такой настройки, и сниппет в чанке, необходимо немного поправить парсер на более правильную последовательность парсера МОДх (будет уже в d5 и b5, март-аперль):


// combine template and document variables
$source= $this->mergeDocumentContent($source);
// replace settings referenced in document
$source= $this->mergeSettingsContent($source);
// replace HTMLSnippets in document
$source= $this->mergeChunkContent($source);
// insert META tags & keywords
$source= $this->mergeDocumentMETATags($source);
// find and merge snippets
$source= $this->evalSnippets($source);


Строку
$source= $this->mergeSettingsContent($source);
еще раз поставить перед
$source= $this->evalSnippets($source);


выйдет:


// combine template and document variables
$source= $this->mergeDocumentContent($source);
// replace settings referenced in document
$source= $this->mergeSettingsContent($source);
// replace HTMLSnippets in document
$source= $this->mergeChunkContent($source);
// insert META tags & keywords
$source= $this->mergeDocumentMETATags($source);
// find and merge snippets
$source= $this->mergeSettingsContent($source);    //bumka
$source= $this->evalSnippets($source);

в 1285 строка приблизительно.

42 комментария

avatar
Если конфиг берется из базы один раз для всего сайта, тогда есть смысл. Я подозреваю, что это так, но не уверен.
  • Shin
  • 0
avatar
Я подозреваю, что это так, но не уверен
Посмотрите внимательней на DocumentParser::getSettings(). Может тогда уверенности будет больше.

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

Отправил уже диме пул-реквест в сборку. Правда mergeSettingsContent() добавил в каждый вызов parseChunk и runSnippet (А вдруг кто-то захочет в настройках вставить вызов чанка или сниппета? И все это дело в чанке и сниппете. Не хорошо конечно, но все же.)
avatar
Кстати, в топике не указано, но MODX Evolution накалыдвает ограничения на имена системных настроек. Там нельзя исплоьзовать символы в верхнем регистре. Т.е. создав TV параметр PhoneMyCompany вы обломаетесь. Нужно называть phonemycompany.
avatar
То есть любой параметр ТВ я добавляю в чанк как [(cfg_footer_phone)] (например) и не важно назначен он для шаблона или нет, все равно будет выводиться там где выводится сам чанк?
avatar
Именно в этом и прелесть )
только вы в плагине указываете из какого документа тянуть ТВ
avatar
Нет. Только те TV параметры, которые прикреплены к шаблонам которые назначены документам определенным в параметре ids данного плагина. В остальном все верно.
У меня это вот так смотрится
Документ с настройками


Пример чанка где настройки передаются как параметры сниппету (парсер предложеный бумкой не скушает это. Смотрите пулл-реквест который я диме отправил).
avatar
Это очень круто. А отличие от CustomSettings только в том что данные из ТВ берутся и данные в документе заполняются а не в конфигурации, или есть еще преимущества какие-то?
avatar
данные из ТВ берутся и данные в документе заполняются а не в конфигурации,
Да, отличие только в этом.

есть еще преимущества какие-то?
Благодаря MM вы можете кастомизировать права пользователя и спрятать от него ненужные настройки. Т.е. глобальную конфигурацию вы запрещаете в правах пользователя. А через MM разрешаете править только число тегов, допустим. Но API и пути к папке с шаблоном — запрещаете. + вы можете использовать кастомизированные инпуты. Т.е. если нужно логотип выбрать — то тип ввода будет image и пользователь увидит кнопочку обзор. Аналогично если необходимо составить текст письма отправляемый юзеру — выбираете textarea.

CustomSettings же всегда нам предлагает использовать input с типом text. Помимо этого, если контент-менеджеру нужно было дать права на редактирование какой-то настройки, то вы должны были разрешать редактировать всю конфигурацию.
avatar
Кстати, да. Сам вспомнил о сложностях добавления изображения. Спасибо за ценное дополнение.
avatar
о да я теперь понял зачем парсер править)) совсем забыл про количество на страничке и так далее )
а клиенты часто просят выносить это в настройки )
avatar
Нашел багу. Если на странице вывести несуществующий параметр, то у других параментров индекс сдвигается.
avatar
Так плагин на самом деле работает только на OnBeforeDocFormSave

потому к выводу на страничке он не имеет никакого отношения

Ну и делать ошибки не хорошо сниппет Dito у вас тоже не будет работать но это ж не бага?
avatar
Это информация для общественности, если кто-то тоже столкнется с подобным.
Я понимаю, что это не совсем бага, просто нет «зашиты от дурака».

По поводу сравнения с ditto.
В ditto плейсхолеры не сдвинутся, если вывести не существующий.
Например: «tv.catalog_pic» так и останется «tv.catalog_pic».

У меня же, из-за моей невнимательности, получилось следующие: в плейсхолдер «cfg_catalog_pic» попала информация из предыдущего плейсхолдера, а последний плейхолдер, вызванный на странице, стал пустым.
avatar
Т.е. я смогу с помощью @EVAL return $modx->runSnippet поместить в параметр, к примеру, вызов Ditto и затем выводить результат его работы в шаблонах вот так: [(cfg_ditto_news)]?
avatar
Интересное применение нужно попробовать может и заработает
avatar
Ну что-то меня смущает. Нет риска грохнуть админку или затормозить ее работу?
avatar
надо тестить так не скажу
avatar
Вероятно, еще будет иметь значение допустимый размер информации в поле БД.
avatar
удалено
Комментарий отредактирован 2013-03-04 21:51:54 пользователем Extremum
avatar
Собственно непонятно работает плагин. Начал с того что сделал все по инструкции, добавил для вывод телефона и логотипа в шапке тв и нормально вывел их через [(cfg_phone)] и [(cfg_logo)]. Ура-заработало!

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

<ul class="f_contact">
   <li>[(cfg_adress)]</li>
   <li>[(cfg_phone)]</li>
    <li>[(cfg_mail)]</li>
</ul>


И после чего красота вся пропала. Все перемешалось. Заполнено вот так:


Шапка стала выглядеть так:


Футер так:


это баг или фича?
avatar
В общем сам спросил и сам ответил. Это баг. У меня первые два TV были пронумерованы (задан порядок в списке). Причем у логотипа номер 4, а у телефона номер 1 (остальные планировал позже добавить). Сбросил на 0 все порядки — стало по местам все.
avatar
А -забыл добавить что пронумеровал все тв по требуемой очереди не пропуская порядка — тоже все нормально.
avatar
&ids=ID ресурсов настроек;text;347 &prefix=Префикс;text;cfg_
А что писать в настройках плагина? 347 — сюда чей id прописывать?
Комментарий отредактирован 2013-03-13 17:10:45 пользователем tai
  • tai
  • 0
avatar
Туда прописать id страницы на которой выводятся параметры настройки, естественно.
avatar
Обновил версию плагина до 0.2, а так же в комплект добавил сниппет cfgArray. Обновиться можно тут
avatar
Посмотрел видео. Очень крутая штука вышла!
avatar
Ну демка хоть и не совсем удачная (в плане того, что пример глупый). Но зато довольно наглядно получилось, т.к. область применения ограничивается только фантазией.
avatar
Случайно нашел ваш плагин (store + любопытство). Пару лет назад сделал нечто подобное, правда на базе события OnLoadWebDocument и без записи настроек в базу.
avatar
Разница в том, что по данной технике не создаются дополнительные запросы в базу. Настройки даже в модуле пашут $modx->config['bla-bla'] ваш не будет работать
avatar
Спасибо за ответ. Да, я успел оценить эти достоинства и переделал свой плагин. Кстати, получилось 14 строк кода, в вашем варианте есть что попилить ;-)
avatar
У мну за год опыта тоже не мало под собиралось, думаю сейчас его в 10-12 ужать смогу ))
avatar
Добрый день. Сижу, рву волосы на голове, все сделал — результат — не выводится ничего.

Сделал:

1) Создал плагин CfgTv -> В нем:
а)текст содержимого плагина
б)конфигурация плагина ( ids=того ресурса, в которому привязан мой TV и префикс cfg_ )
в)событие (OnBeforeDocFormSave)

2) В нужном мне шаблоне ставлю [(cfg_названиеtv)] (естественно на английском и со строчными буквами)

3) Результат — пусто

В чем может быть проблема (з.ы.версия evo 1.0.12, пробую пока на обычных текстовых TV без сложностей, что-бы разобраться)
Комментарий отредактирован 2013-10-10 10:59:52 пользователем gumoviy
avatar
А после создания плагина вы сохранили указанный документ с заполненным tv?
avatar
аналогичный вопрос
avatar
А в базе в таблице system_settings появились эти настройки с именами cfg_названиеtv?
avatar
:)

bumkaka, akool спасибо, сохранить то я и не сохранял ни разу пока все волосы не повыдергивал. Спасибо, webber теперь таблицы и в базе появились.
avatar
Нужна помощь:
при попытке вставить код Google аналитики получаю ошибку:
Undefined property: DocumentParser::$mstart
« MODX Parse Error »
MODX encountered the following error while attempting to parse the requested resource:
« Execution of a query to the database failed - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '_setAccount', 'UA-38173145-1']); _gaq.push(['_trackPageview']); (functio' at line 1 »
avatar
да 100 раз уже говорили — найдите в коде [( и поставьте пробел между [ и (. Т.е. тег [()] — это тег конфига модха
avatar
Спасибо на добром слове. :)
avatar
Т.е. оптимальный путь такой:
— Создаю нужный TV для настроек, например emailFrom.
— Создаю спец. шаблон, например customSettings, к которому привязываю этот TV (только к этому шаблону).
— Создаю спец. документ с шаблоном customSettings, и в нём задаю нужное значение моего TV.
Ну и, естественно, в конфиге плагина указываю ID моего спец. документа.

Верно?
Комментарий отредактирован 2015-04-17 11:49:08 пользователем Aharito
avatar
да, верно, я еще для этого шаблона лишние поля скрываю, контент и пр. чтобы не мешались
avatar
Да, я уже сделал также. Так, конечно, удобнее.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.