Привязка записей блока к pick-запросу, URL, домену, сессии и т.п. При создании новой записи, в одном из ее полей сохраняется ключевое значение. При выводе записей, отображаются только записи с необходимым ключевым значением. Данный метод вызывается в tdd-файле многозаписных шаблонов.
$data = [
'block-id'=>9, # Номер блока текущего шаблона.
'field'=>1, # Номер поля, в котором будет храниться данное для связывания.
# Тип поля зависит от сохраняемого данного, на все случаи подойдет тип varchar.
# Для составных ключей используйте массив полей, например: [1, 2].
# Поля будут автоматически преобразованы в индексные (что отразится на переменной $keys).
'value'=>'kazan', # Данное для связывания (строка). Допустимы только url-безопасные строки,
# поэтому рекомендуется произвольные строки кодировать с помощью метода Url::encode().
# Функция urlencode() здесь не годится.
# Для составных ключей используйте массив, например: ['Россия','Новгород']
'unbind'=>true, # Отключить данный метод, то есть, не привязывать записи. Отключать метод
# извне (с помощью оператора if) нежелательно, так как в этом случае метод изменит
# структуру базы данных (уберет индексы). Управление отключением для того или иного
# блока можно производить с помощью экстраданного.
];
Пример привязки к данным сессии (map.tdd)
Tdd::bind(
['block-id'=>$blockInfo['id'], 'field'=>1, 'value'=>$_SESSION['map']['city']],
$keys,
$defaults
);
Допустим, что псевдостраницы создаются путем изменения pick-запросов к полю 3 основного блока 99. URL страницы имеет такой вид: "http://.../?page=9&block=99&p[3]=999".
Кроме этого на странице могут быть другие блоки, которые должны также менять свой контент. Во всех шаблонах этих блоков зарезервируем поле 1 для сохранения значения параметра p[3]. Для примера рассмотрим простой шаблон с текстом в поле 2.
texts.tdd
<?php
$types = [
1 => 'int',
2 => 'text',
];
$fields['hidden'] = [1];
$params['multi-record'] = true;
if (Blox::getScriptName() == 'page')
$value = $_GET['p'][3];
elseif (Blox::getScriptName() == 'edit') // Не обязательно
$value = Request::get($blockInfo['id'], 'pick', 1, 'eq');
Tdd::bind([
'block-id' => $blockInfo['id'],
'field' => 1,
'value' => $value
], $keys, $defaults
);
texts.tpl
<?= $dat['edit'].$dat[2] ?>
Тут нужно пояснить, как вычисляется данное 'value' для метода Tdd::bind. В режиме открывания страницы нужно брать переменную $_GET['p'][3]. При создании новой записи (в режиме редактирования) этой переменной уже нет. Но в системе это данное можно извлечь через метод Request::get(). Более того, данное 'value' можно вообще не вычислять — в режиме редактирования оно будет вычислено в самом Tdd:bind().
На псевдостраницах записи можно привязывать не только к отдельным параметрам запроса, но и ко всему URL. Данный способ, в отличие от предыдущего, является более универсальным, то есть, такие шаблоны можно назначать на любых страницах и псевдостраницах сайта.
При наличии блока навигации, например, созданного с помощью класса Nav, и добавлении метода Tdd::bind() в дескрипторы контентных шаблонов, можно легко создавать псевдостраницы любой структуры.
.tdd
<?php
$titles = [
2 => 'Текст',
];
$types = [
1 => 'varchar(333)',
2 => 'text',
];
$defaults = [
2 => '<h2>Welcome!</h2>',
];
$fields = [
'hidden' => [1],
];
$params = [
'multi-record' => true,
];
Tdd::bind(
[
'block-id'=>$blockInfo['id'],
'field'=>1,
'value'=>Url::encode(Router::getPhref(Blox::getPageHref()))
],
$keys,
$defaults
);
Есть возможность управлять способом связывания через окно редактирования экстраданных. Это касается только штатных данных, описанных в методе Tdd::getByJson().
Для этого в экстраданных нужно создать поле, в которое можно будет записывать JSON-массив настроек в виде строки.
Tdd::bind(
['block-id'=>$blockInfo['id'], 'field'=>1, 'value'=>Tdd::getByJson($xdat[2])],
$keys,
$defaults
);
Данный метод создан для возможности изменить тип привязки записей, не путем редактирования файла дескриптора, а в окне редактирования. Под типом привязки имеется в виду код для параметра value метода Tdd::bind().
Применение метода Tdd::getByJson() не ограничивается методом Tdd::bind(), его можно использовать везде, где требуется эмуляция описанных ниже php-кодов.
Тип | Примеры аргумента | Пример прямого вычисления | Примечание |
---|---|---|---|
phref |
{"type":"phref"}
{"type":"phref", "encode":true}
|
Router::getPhref(
Tdd::getPageHref()
)
| Получение относительного параметрического URL текущей страницы. Если применить ключ "encode", результат будет закодирован с помощью метода Url::encode(). |
session |
{
"type":"session",
"keys":["map","city"]
}
|
$_SESSION['map']['city']
| Получение данных сессии. В ключе "keys" записывается цепочка ключей массива $_SESSION. |
pick |
{
"type":"pick",
"field":1
}
|
$_GET['p'][1]
| Элемент field — то же самое, что параметр field метода Tdd::bind(). Также как и для этого параметра можно указывать массив, например, "field":[1, 2]. Аналогично будет возвращен массив. |
Следующие два кода эквивалентны:
echo Url::encode(Router::getPhref(Blox::getPageHref()));
echo Tdd::getByJson('{"type":"phref", "encode":true}');
С помощью этого метода можно определить, делегирован ли хотя бы один из вышестоящих блоков (предков). Метод работает быстро, когда дело касается текущего блока в контексте вывода страницы.
.tpl
$srcPage = ($blockInfo['delegated-id'] || Tdd::blockHasDelegatedAncestor($block))
? Blox::getBlockPageId($block)
: $page
;
Данный код можно применять, когда блок или его вышестоящий блок могут быть делегированы на другую страницу, и необходимо определить страницу, на которой находится исходный блок.
Для этой цели можно было бы применять только метод Blox::getBlockPageId(), однако метод Tdd::blockHasDelegatedAncestor() помогает ускорить процесс.