WikiPatterns: «маленькие хитрости»

Два шаблона, связанные отношением «многие-ко-многим»

Например, авторы и научные статьи, часть из которых написана в соавторстве.
Заводим два шаблона Article и Person

1. Поле с мультиселектом

В редакторе статьи можно выбрать автора(ов) из списка.
В инсталляторе шаблона Article определяем поле с мультиселектом и привязываем его к таблице шаблона Person

<field>
    <name>authors</name>
    <description>Авторы</description>
    <type>tmultselect table="advontotypes_wpPerson" field="name" key="id"</type>
</field>

NB Данные хранятся в поле authors в формате :id1::id2::...:

2. Агрегатор с фильтром

На странице автора отображается список статей, автором или соавтором которых он является.
В шаблоне one.txt шаблона Person определяем агрегатор статей с фильтром по полю authors.

{ldelim}{ldelim}templatesum for="[абсолютный адрес корневой страницы статей]" name="Article" collectall=0
hidepagenumbers=1 filter="authors:{$data.id}" {rdelim}{rdelim}

Простой фильтр по шаблону

написать

Решения для sum.txt

Основные

Вызов action из шаблона с передачей параметров

{ldelim}{ldelim}myaction code="{$data.code}"{rdelim}{rdelim}


Вызов форматтера: использовать форматтеры нельзя, т.к. содержимое форматтера обновляется только при пересохраниении. Однако, форматтеры div и span можно воспроизводить, вставляя обычный html-код.

<#<div class="show"><div class="light no-padding">#>
...
<#</div></div>#>

Отображать/скрывать элементы данных

Показывать активную или неактивную ссылку, в зависимости от того, прикреплен ли PDF-файл

{if $page.data.pdf != ""}
    <a href="{$system.rooturl}sites/socmodel.com/files/articles/{$page.data.pdf}" style="color:#333;">#>{$page.data.title}<#</a>
{else}
    <span style="color:#999;">#>{$page.data.title}<#</span>
{/if}


Показывать или не показывать картинку, в зависимости от того, указан ли url

{if $data.img != ""}
    <div style="float:right; margin-left:15px;" class="thumbnail"><img src="{$system.rooturl}sites/socmodel.com/files/person_foto/{$data.img}"/></div>
{/if}


Захват данных в капчу и проверка наличия содержания (работает только для sum, т.к. one генерируется только один раз в момент сохранения текущей страницы и действует потом для всех страниц.

{capture name=desc}{$data.docdesc}{/capture} 
...
{if $smarty.capture.desc|count_characters > 1}
{$data.docdesc}
----
{/if}

Отображать/скрывать страницы

По умолчанию $viewall установлен в false и ссылки на закрытые страницы просто не отображаются. Чтобы изменить шаблон, можно выводить html-код в экшне, а можно пропинать Влада, чтобы он добавил переменную {$hasaccess}.


Во freidenberg.ru ссылки на страницы, доступ к которым закрыт, отображаются через шаблон с модификатором disabled, но это достигается за счет чита агрегатора {{templatesum}}

if ($viewall) { // выводятся невидимые
    foreach($pages as $key => $page) {
        if (!$this->HasAccess("read", $page["supertag"]))
            $modifier = "disabled";
        else
            $modifier = "enabled";
        echo $this->Format($this->Format(Wptrn_ProcPage($this, $restpl["tplfile"], 'sum'.($modifier==''?'':'.'.$modifier), $page["id"])),"post_wacko");
         }
} else { // классический templatesum
    echo $this->Format($this->Format(Wptrn_ProcPages($this,$restpl["tplfile"],'sum'.($modifier==''?'':'.'.$modifier),$pages)),"post_wacko");
}


{ldelim}{ldelim}freisumlevel2{rdelim}{rdelim}
{ldelim}{ldelim}freisumcreate levels="12"{rdelim}{rdelim}

Переключатель режимов отображения

Чтобы добавить переключатель режимов, нужно написать экшн-алиас templatesum, в котором задаются параметры и выводится строка переключателя:

<?php
  if($this->symAlnum($_REQUEST["view"]))
    $modifier = $_REQUEST["view"];
  echo '<div style="font-size:0.9em;">Режим:';
  echo '<a href="'.$this->href('','','skip='.$_REQUEST["skip"]).'">текстовый</a>';
  echo ' | <a href="'.$this->href('','','skip='.$_REQUEST["skip"].'&view=alt').'">факсимильный</a>';
  if ($this->IsAdmin()) echo ' | <a href="'.$this->href('','','view=word').'">для MS Word</a>';
  echo '</div>';
  $name = "FreiLevel3";
  $for = "!";
  $sortby = "code";
  $sortorder = "ASC";
  $viewall = false;
  $max = 15;
  $pagenumstyle = "list";
$saverequest = "view";
  $showpager = "topbottom";
  include('extensions/WikiPatterns/actions/templatesum.php');
?>

Решения для one.txt

Ссылка на родительскую страницу.

<#<h2><a href="{$system.rooturl}{$page.pretag}">{$page.prename}</a></h2>

NB Если родительская страница лежит в корне, вместо prename нужно писать pretag, т.к. у prename откусывается первая буква (символ «/» в случае подстраниц)


Добавление агрегаторов с фильтрами (см. раздел Два шаблона, связанные отношением «многие-ко-многим»).

{ldelim}{ldelim}templatesum for="[абсолютный адрес корневой страницы статей]" name="Article" collectall=0
hidepagenumbers=1 filter="authors:{$data.id}" {rdelim}{rdelim}

Для разработчика: особенности реализации

Физически связь шаблонов со страницами осуществляется следующим образом




ВЛАДУ: Была заменена функция в AdvOntology

function utilConditionsToSQL($conditions, $tableadd = "") {
    $query = "1"; // TRUE, compatible with old MySQL
    foreach ( $conditions as $concept => $val ) {
        if ($this->_kernel->symSome ( $concept, 'A-Za-z0-9_' )) {
//            $query .= " AND (" . $tableadd . $concept . " in " . $this->wrapListToSQL ( $val ) . ") ";
            $query .= " AND  " . $tableadd . $concept . " like '%:".$val.":%' ";
        }
    }
    return $query;
}


&this->page = Array ( [id] => 5749 [tag] => Администрирование/Обсуждение [supertag] => administrirovanie/obsuzhdenie [time] => 2012–11–22 00:28:37 [body] => ... [body_r] => ... [body_toc] => ...[owner] => SiteAdmin [user] => SiteAdmin [latest] => Y [handler] => page [comment_on] => [super_comment_on] => [hits] => 0 [lang] => ru [description] => [keywords] => )