magr0s 07 февраля 2015 3 19
Недавно в одной из моих тем-вопросов (про Update рабочего сайта) Вы рассказали про интересный плагин. Чесно сказать загорелся.
Сейчас готов к переводу существующего проекта ну примерно процентов на 70%. Осталось выяснить как же правильно реализовать некоторые моменты.

Генерирование таблиц на основе данных БД.
как это сейчас
есть сниппет showTable с параметром tablecontent
в сниппете на основании этого параметра на первом этапе делается выборка данных и генерируются строки таблицы.

$rows .= $modx->getChunk('chunk', $params);

на втором этапе генерируется непосредственно таблица

/*
* @params thead , rows
*/
$output = $modx->getChunk('table', $params);

на каждую таблицу приходится 2 собственных чанка (thead, rows) и один обвертка для таблицы (table)

Вопрос заключается в том как это красиво должно быть реализовано в новой среде.
Хотелось бы собрать таблицу непосредственно в шаблоне.
19 комментариев
guru881
guru88 07 февраля 2015г в 12:34 #
Для этого достаточно в шаблон заглянуть, допустим в формировании таблицы товаров в письме клиенту.
если ты получил данные в массив, скажем $params, дальше по стандарту.
для этого понадобится перебрать массив {foreach $params.rows as $rows}


<table border="0" cellpadding="5" cellspacing="3" style="width:100%;border-collapse:separate;">
	<tbody>
        {foreach $order_data.object as $product}
		<tr>
			<td style="width:170px;border-bottom:1px solid #ccc;"><img src="{$site_url}{snippet name=phpthumbof  params="input=`{$Path}upload/photos/{$product.sm_article}_0.jpg`&options=`w=120&h=120&zc=0`"}"></td>
			<td style="background:#eee;">				
					<u>{$product.pagetitle}</u>	
			
					Артикул: {$product.sm_article}		
			
					Количество:	{$product.quantity}	
                    Размер: {str_replace('S_','',$product.size)}	
					Цена: {$product.price} руб.
	
			</td>
		</tr>
        {/foreach}
		<tr>
			<td><b>Стоимость доставки</b></td>
			<td style="background:#eee;"><b>{$properties.delivery} руб.</b></td>
		</tr>
		<tr>
			<td><b>Общая сумма заказа</b></td>
			<td style="background:#eee;"><b>{$order_data.sum + $properties.delivery} руб.</b></td>
		</tr>
	</tbody>
</table>
m
magr0s 07 февраля 2015г в 12:39 #
откуда рождается в примере $order_data.object?
сниппеты вроде как не могут возвращать ничего кроме строк
guru881
guru88 07 февраля 2015г в 12:51 #
Зато процессоры могут возвращать массив. Все зависит от ситуации, письмо формируется в запросе из процессора submit
$this->modx->smarty->fetch($tpl), и массивы с переменными подключаются заранее $this->modx->smarty->assign('order_data', $data);
Fi1osof1
Fi1osof 07 февраля 2015г в 15:53 #
сниппеты вроде как не могут возвращать ничего кроме строк
Вот поэтому мы сниппеты и не используем (на самом деле не только по этому, но на самом деле иногда все-таки используем, к примеру, для вызова некешируемого Смарти-блока тип [[!smarty?tpl=`....tpl`]]).
m
magr0s 07 февраля 2015г в 13:04 #
процессоры не принимают параметры.
значить, получатся для каждой таблицы придется создавать свой процессор
guru881
guru88 07 февраля 2015г в 13:10 #
Кто такое сказал? Вот 2 примера по реализации. В обоих случаях результат вернет в переменную $result.


{assign var = params value = [
        "limit" => 30,
        "getPage" => 1,
        "query" => {$smarty.get.query}
    
    ]}

{*processor action="web/catalog/category/products/getdata" ns="modxsite" params="limit=`30`&getPage=`1`" assign=result*}
{processor action="web/filter/catalog" ns="modxsite" params=$params assign=result}
Fi1osof1
Fi1osof 07 февраля 2015г в 15:55 #
Можно и лучше даже так:
{$params = [
        "limit" => 30,
        "getPage" => 1,
        "query" => $smarty.get.query
]}
guru881
guru88 07 февраля 2015г в 15:58 #
Это я из старого шаблона взял, еще ShopModxBox 2.0 :)
Fi1osof1
Fi1osof 07 февраля 2015г в 16:07 #
:)
m
magr0s 08 февраля 2015г в 12:17 #
спасибо за ответы.
отличная картина вырисовывается :)
m
magr0s 09 февраля 2015г в 11:44 #
продолжим…
проект постепенно переходит на новый уровень (пока только на черновиках) а мы продолжаем наращивать заветные проценты.
сегодня на повестке для, и имеем мы дело с фротн-эндом:

Опять же таблица.
Есть процессор getServiceList его задача подключится к таблице my_table в бд и считать от туда информацию.
Вопрос в том как в этот процессор корректно загнать MODX API, ведь хочется получить все вкусняшки, ранее все это делалось через сниппет, но поскольку теперь стоит задача еще и вернуть какой то результат, вариант со сниппетом отвалился.
[code]
{$params = [
«modX» => $modx,
]}
{processor action=«web/tables/getservicelist» ns=«modxsite» params=$params assign=result}
[/code]
это вообще корректно?
тупо в процессоре импортировать api я не хочу
Fi1osof1
Fi1osof 09 февраля 2015г в 13:56 #
Выложите листинг процессора getServiceList куда-нибудь. Какой его главный предок? modObjectGetlistPropcessor или что? Если процессор написан по фэншую, что все должно корректно отработаться, там ответ стандартизированный.
m
magr0s 09 февраля 2015г в 14:31 #
блин да ну ладно. неужели так все просто.
листинг выкладывать смысла нету ответ получен более чем ожидалось, сразу на несколько вопросов, если вдруг чего тогда уже с листингом приду.

если есть возможность, покажите гист на свой процессор который работает со своей таблицей?

как всегда премного благодарен
Fi1osof1
Fi1osof 10 февраля 2015г в 05:34 #
Вот вам ответ.
m
magr0s 18 февраля 2015г в 10:46 #
Здравствуйте.

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

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

Как сделать такой функционал с использованием modxSmarty, в голову пришла только одна мысль. Сделать нечто похожее на то как устроено подключение шаблонов.
Одна страница modal в которой вызывается modal.php (аналог base,php) ну и далее уже по ключу из запроса подсовываем нужный *.tpl модального окна.

Приемлемым ли будет такой механизм? или возможно есть совет по реализации?
Спасибо.
Tramp13571
Tramp1357 18 февраля 2015г в 11:36 #
можно делать это через обращение к коннектору (как обрабатывается корзина в shopmodxbox)
Я по привычке использую другой вариант: создаю документ (например ajax), обязательно некешируемый, и для него создаю шаблон, делаю его статичным и назначаю ему свой php-файл (благодаря расширению templatephp код шаблона может содержать php инструкции) — и там творю что душе угодно. там доступен весь MODX c его вкусностями:

<?php
if($_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest'){
	switch($_REQUEST['action']){
		case 'getmenu':
			$id=(int)$_REQUEST['id'];
			$r=$modx->getObject('modResource',array('id'=>$id,'template'=>20));
			if($r){
				$output=$r->get('content');
				$maxIterations= intval($modx->getOption('parser_max_iterations', $params, 10));
				$modx->parser->processElementTags('', $output, true, false, '[[', ']]', array(), $maxIterations);
				$modx->parser->processElementTags('', $output, true, true, '[[', ']]', array(), $maxIterations);
				$ttl=$r->get('longtitle');
				if(empty($ttl))
					$ttl=$r->get('pagetitle');
				return $output;
			}
			else{
				return 'Ошибка: страница не найдена';
			}
			break;

		case 'service':
			$id=(int)$_REQUEST['id'];
			$r=$modx->getObject('modResource',array('id'=>$id,'template:in'=>array(3,17)));
			if($r){
				$output=$r->get('content');
				$maxIterations= intval($modx->getOption('parser_max_iterations', $params, 10));
				$modx->parser->processElementTags('', $output, true, false, '[[', ']]', array(), $maxIterations);
				$modx->parser->processElementTags('', $output, true, true, '[[', ']]', array(), $maxIterations);
				$ttl=$r->get('longtitle');
				if(empty($ttl))
					$ttl=$r->get('pagetitle');
				$out=json_encode(array('title'=>$ttl, 'content'=>$output, 'alias'=>$r->get('alias')));
				return $out;
			}
			else{
				return json_encode(array('title'=>'Ошибка: страница не найдена', 'content'=>''));
			}
			break;
...
Fi1osof1
Fi1osof 18 февраля 2015г в 12:21 #
Промазал :) Ниже ответил.
Fi1osof1
Fi1osof 18 февраля 2015г в 12:21 #
1. При вызове через коннекторы не вызываются MODX-ивенты, и самое главное — OnHandleRequest, а именно на это событие срабатывает плагин, инициализирующий modxSmarty (объект $modx->smarty). То есть если вызывать процессор через коннектор, в процессоре не будет смарти, а вопрос был именно про смарти. При оформлении заказа у нас процессор корзины вызывается на самой странице безаджаксово, поэтому $this->modx->smarty в процессоре доступен. Если через коннектор его вызывать, то не будет объект $this->modx->smarty и выполнение завершится фатальной ошибкой.

Сразу скажу, что если мне нужен смарти в процессоре при вызове через коннектор, я делаю так: в процессоре дописываю код в initialize()
public function initialize(){
    if(empty($this->modx->smarty)){
        $this->modx->invokeEvent('OnHandleRequest');
    }
    return parent::initialize();
}


2. Старайтесь не использовать этой конструкции if($_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest'){…
Зачем вам она нужна? Если у вас в логике уже прописано switch($_REQUEST['action']), то это уже фильтрует запросы. Какая разница вам аджаксом запрос отправлен или нет? И, на смарти твой пример надо бы переписать, чтобы по сабжу было :)

3. Под каждый запрос шаблон создавать — не кашерно. Просто документу указывать без шаблона, а в контент прописывать путь до смарти-шаблона [[!smarty?tpl=`......`]]. А в нем уже все прописывать что нужно, и если надо отдать именно в JSON, то преобразовываем данные. Самый простой способ — это вызвать подшаблон, полученные данные в переменную зафигачить и преобразовать данные:
{include $tpl_path assign=result}
{json_encode($result)}
Tramp13571
Tramp1357 18 февраля 2015г в 13:39 #
чтобы по сабжу было
Это я для примера показал, что все доступно :)
Просто документу указывать без шаблона, а в контент прописывать путь до смарти-шаблона [[!smarty?tpl=`......`]]. А в нем уже все прописывать что нужно
А вот об этом не догадался, учту, спасибо за науку :)
Fi1osof1
Fi1osof 18 февраля 2015г в 13:44 #
Не за что :)
m
magr0s 23 февраля 2015г в 23:46 #
Здравствуйте.
Стоит ли использовать процессоры для пустяковых запросов? или можно использовать запрос прям в шаблоне при условии что дальше нам данные абсолютно не нужны
Запрос примерно такого характера.

if ($modx->getObject('modResource', $id){
    //... 
}
Fi1osof1
Fi1osof 24 февраля 2015г в 00:39 #
ИМХО однозначно стоит. Я часто этим пользуюсь и считаю это сильной стороной modxSmarty. Только имейте ввиду, что конструкции типа {$doc->set('pagetitle', $value)} будут возвращать во фронт единичку (ибо успех), поэтому в таких случаях делайте {$ok = $doc->set('pagetitle', $value)}. Тогда результат будет присваиваться переменной и Смарти ничего отправлять в паблик не будет.
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.