Инструменты пользователя

Инструменты сайта


limb2:ru:howtos:create_new_site_object

Создание с нуля новых объектов сайта

Мы надеемся, что вы уже знакомы с базовыми понятиями Limb2. Что ж, теперь можно попробовать создать свои собственные объекты сайта (site objects).

Сразу уточним, что мы собираемся показать, как создавать наиболее простые объекты сайта. Основная задача данного документа - пролить свет на устройство Limb2. Если вам требуется что-либо сложное, то наверняка вам потребуется изучить исходники или же обратиться к разработчикам. Также мы советуем всем для начала ознакомиться с демо-проектом, выполненном на базе Limb.

Для того, чтобы создать новый объект сайт, вам необходимо будет выполнить следующие действия:

  1. Решить, что это будет за объект: простой объект сайта или же контентный объект сайта, также аттрибуты и требуемую фунциональность.
  2. Создать классы для объектов сайта, отнаследовав их от базовых site_object или content_object
  3. Создать класс db_table для работы с таблицой базы данных в случае, если вы создаете контентный объект сайта
  4. Создать контроллер.
  5. Создать классы действий для реализации функциональности
  6. Создать ini-файлы с локализованными строками (необязательно потребуется)
  7. Создать файлы шаблонов для действий, которые связаны с GUI. (обычно это действия 'display', 'edit', 'create').
  8. Зарегистрировать новый тип объекта в дереве объектов при помощи страницы /root/admin и действия Register New Object.
  9. Назначить права доступа и шаблоны прав доступа к действиям нового контроллера

Планирование

Представим, что нам необходимо сделать какой-нибудь каталог. Представим, что наш каталог будет состоять из иерархически организованных разделов catalog folders. Каждый такой раздел может содержать элементы каталога catalog objects.

Для того, чтобы реализовать нашу идею, нам потребуется 2 типа объектов сайта : some_catalog_object и some_catalog_folder. Ниже мы рассмотрим все необходимые шаги по созданию простейшего каталога при помощи Limb.

some_catalog_folder будет обычным объектоv сайта, так как он не будет иметь никаких дополнительных данных, кроме идентификатора 'identifier' и заголовка 'title'.

some_catalog_object будет контентным объектом, так как содержиn расширенный набор атрибутов:

  • 'identifier' - VARCHAR
  • 'title' - VARCHAR
  • 'description' - TEXT. Описание элемента каталога
  • 'price' - FLOAT. Цена
  • 'image_id' - INTEGER, идентификатор изображения в репозитории медиа-объектов.

Создание классов для объектов сайта

Классы объектов сайта используются для операций загрузки и сохранения данных. Можно сказать, что Limb site_object реализует паттерн ActiveRecord.

Обычно требуется всего лишь отнаследовать от одного из 2 базовых классов: site_object или content_object.

На самом деле мы можем не создавать отдельный класс для раздела каталога, так как в новой версии Limb 2.3+ нет жесткой привязки контроллера к объекту сайта, а стандартного поведения для таких объектов, как раздел каталога - вполне хватает (до Limb 2.3+ в классе объекта сайта необходимо было указывать, какой именно контроллер отвечает за поведение, что ограничивало гибкость). В нашем примере мы все равно сделаем новый класс для раздела каталога, так как мы решили сменить стандартную иконку для раздела каталога. :-)

Что ж, создадим файл для класса some_catalog_folder по пути PROJECT_DIR/core/model/site_objects/some_catalog_folder.class.php со следующим содержимым:

<?php
 
require_once(LIMB_DIR . 'core/model/site_objects/site_object.class.php');
 
class some_catalog_folder extends site_object
{    
  function _define_class_properties()
  {
    return array(
      'class_ordr' => 0,                       //для сортировки элементов дерева. Вначале папки.
      'can_be_parent' => 1,                    // разрешаем иметь дочерние элементы
      'icon' => '/shared/images/folder.gif'    // определяем путь до иконки при отображении в дереве
    );
  }
}
?>

Далее будет класс some_catalog_object. Итак, файл с путем PROJECT_DIR/core/model/site_objects/some_catalog_object.class.php будет иметь следующее содержание:

<?php
 
require_once(LIMB_DIR . 'core/model/site_objects/content_object.class.php');
 
class some_catalog_object extends content_object
{
  function _define_attributes_definition()
  {
    return complex_array :: array_merge(
     parent :: _define_attributes_definition(),
     array(
       'description' => array('search' => true, 'search_weight' => 1), 
       // указывает на то, что это поле будет индексироваться для данного объекта с весом 1
     ));
  }
 
  function _define_class_properties()
  {
    return array( 
      'class_ordr' => 1,           //для сортировки элементов дерева. Элементы каталога - после папок.
       'can_be_parent' => 0,       //дочерние элементы в дереве запрещены
       'auto_identifier' => true   //идентификатор будет генерироваться автоматически.
     );
  }
}
 
?>

Создание классов для работы с таблицами базы данных (db_table classes)

В Limb-е применяется набор классов db_table для абстрагирования вызовов к базе данных. Этот механизм позволяет эмулировать механизм каскадных удалений и упростить часто используемые операции. В настоящий момент эти классы необходимо создавать и синхронизировать с базой данных вручную. Механизм для автогенерации таблиц в базе данных и классов для работых с ними уже разработан и, возможно, в будущем будет выложен в публичный доступ. Сейчас же необходимо создавать таблицы в базе данных и затем описывать их при помощи db_table классов.

Нам придется создать db_table класс только для some_catalog_object, так как необходимости в db_table для some_catalog_folder нет - он является практически стандартным объектом, поэтому все его данные будут храниться в sys_site_object_db_table.

Так как some_catalog_object отнаследован от content_object, он хранит все свои данные в одной из дополнительных таблиц. Это поведение по умолчанию. Для выполнения операций загрузки/удаления/сохранения используется класс db_table с соответствующим названием, то есть в нашем случае по умолчанию будет использован some_catalog_object_db_table.

Конечно, можно явно указать, каким классом пользоваться для хранения данных. Для этого нужно повлиять на свойство db_table_name в классе объекта сайта. Обратите внимание, что суффикс '_db_table' указывать не нужно). Есть 2 способа это сделать:

class some_site_object ...
{
....
  function _get_db_table_name()
  {
    return 'some_table_name';
  }
}

или так:

class some_site_object ...
{
....
  function _define_class_properties() 
  {
    return array(
      [...]
      'db_table_name' => 'some_table_name'
    );
  }
}

Сам класс some_catalog_object_db_table будет иметь следующий вид (PROJECT_DIR/core/db_tables/some_catalog_object_db_table.class.php):

<?php
require_once(LIMB_DIR . 'core/db_tables/content_object_db_table.class.php');
 
class some_catalog_object_db_table extends content_object_db_table
{  
  function _define_columns()
  {
    return array(
      'image_id' => array('type' => 'numeric'),
      'description' => '', //тоже самое, что и array('type' => 'string')
      'price' => array('type' => 'numeric'),
    );
  }
}
?>

Описание колонок и их типы используются для фильтрации данных и приведения типов. Если описания нет, используется тип-строка. Вот список поддерживаемых типов в настоящий момент:

  • 'numeric'
  • 'string'
  • 'boolean'
  • 'date'
  • 'datetime'

SQL код для создания таблицы будет выглядеть следующим образом:

some_catalog_object  CREATE TABLE `alex_catalog_object` (
                       `id` int(11) unsigned NOT NULL auto_increment,
                       `object_id` int(11) unsigned NOT NULL default '0',
                       `version` int(11) unsigned NOT NULL default '0',
                       `identifier` varchar(50) NOT NULL default '',
                       `title` varchar(50) NOT NULL default '',
                       `description` varchar(255) NOT NULL default '',
                       `price` float default NULL,
                       `image_id` int(11) default NULL,
                       PRIMARY KEY  (`id`),
                       UNIQUE KEY `ov` (`object_id`,`version`),
                       KEY `object_id` (`object_id`)
                     ) TYPE=InnoDB

Обратите внимание на обязательные поля id, object_id, version, identifier, title для каждой таблицы контентного объекта.

Также вы можете переопределить таблицу для хранения some_catalog_folder. Предположим, вы дополнительно хотите хранить описание каждой категории каталога. Для этого вам необходимо модифицировать класс объекта сайта some_catalog_folder подобно some_catalog_object, и указать имя таблицы:

class some_catalog_folder ...
{
....
  function _define_class_properties() 
  {
    return array(
      [...]
      'db_table_name' => 'some_catalog_folder'
    );
  }
}

Далее, создаем класс таблицы, унаследовав от db_table.

class some_catalog_folder_db_table extends db_table
{
  function some_catalog_folder_db_table()
  {
    parent :: db_table();
 
    $this->_columns['id'] = array('type' => 'numeric');
    $this->_columns['object_id'] = array('type' => 'numeric');
    $this->_columns['identifier'] = array();
    $this->_columns['title'] = array();
    $this->_columns['description'] = array();//описание раздела
  }
}

Обязательными полями являются: id, object_id, identifier, title. Остальные операции проводятся аналогично действиям для some_catalog_object.

Создание контроллеров

Контроллер определяет функциональность объектов сайта. Начиная с Limb 2.3+ связь объекта с контроллером стала гибкой - теперь объекту сайта можно назначать любой контроллер.

Наш some_catalog_folder может отображать себя на двух списках - на фронтальной части и в центре администрирования (admin_display + display), также он может создавать дочерние элементы каталога и дочерние разделы каталога, плюс редактировать и удалять себя.

Рассмотрим код some_catalog_folder_controller (PROJECT_DIR/core/controllers/some_catalog_folder_controller.class.php). Ниже будет детальное описание каждого атрибута контроллера:

<?php
 
require_once(LIMB_DIR . 'core/controllers/site_object_controller.class.php');
 
class some_catalog_folder_controller extends site_object_controller
{
  function _define_default_action()
  {
    return 'display'; // display является действием по умолчанию в любом случае. 
                      // Показано для наглядности.
  }     
 
  function _define_actions()
  {
    return array(
      'display' => array(
        'template_path' => '/some_catalog_folder/display.html'
      ),
      'admin_display' => array(
        'template_path' => '/some_catalog_folder/admin_display.html'
      ),
      'create_some_catalog_folder' => array(
        'template_path' => '/some_catalog_folder/create.html',
        'action_path' => '/some_catalog_folder/create_some_catalog_folder_action',
        'JIP' => true,                    
        'popup' => true,                  
        'img_src' => '/shared/images/new.folder.gif',
        'action_name' => strings :: get('create_catalog_folder', 'some_catalog'),
        'can_have_access_template' => true,
      ),
      'edit' => array(
        'popup' => true,
        'JIP' => true,
        'action_name' => strings :: get('edit_catalog_folder', 'some_catalog'),
        'action_path' => '/site_object/edit_action',
        'template_path' => '/site_object/edit.html',
        'img_src' => '/shared/images/edit.gif' 
      ),                
      'create_some_catalog_object' => array(
        'template_path' => '/some_catalog_object/create.html',
        'action_path' => '/some_catalog_object/create_some_catalog_object_action',
        'JIP' => true,
        'popup' => true,
        'img_src' => '/shared/images/new.generic.gif',
        'action_name' => strings :: get('create_catalog_object', 'some_catalog'),
        'can_have_access_template' => true,
      ),
      'delete' => array(
        'JIP' => true,
        'popup' => true,
        'action_name' => strings :: get('delete_catalog_folde', 'some_catalog'),
        'action_path' => 'form_delete_site_object_action',
        'template_path' => '/site_object/delete.html',
        'img_src' => '/shared/images/rem.gif'
      )
    );
  }
}
?>

Итак, описание некоторых наиболее часто используемых аттрибутов в описаниях действий:

  • JIP - флаг, указывающий, показывать ли действие к списке JIP-действий.
  • action_name - указывает локализованное полное название действия.
  • action_path - указывает на относительный путь к классу действия. Для резолвинга полного имени применяется специальный принцип. Обратите внимание на то, что суффикс '.class.php' писать не нужно - это сделано для экономии времени.
  • template_path - указывает на относительный путь к файлу с шаблоном для отображения результата действия.
  • popup - флаг, указывающий на то, будет ли действие выполнено во всплывающем окне.
  • img_src - указывает путь к иконке, которая будет использоваться для обозначения действия в списке JIP.

Для тех, кто пользовался Limb 2.2. Обратите внимание, что аттрибут permissions_required был убран из описания действия, так как система прав претерпела некоторые изменения.

Теперь рассмотрим контроллер для нашего some_catalog_object (PROJECT_DIR/core/controllers/some_catalog_object_controller.class.php):

<?php
 
require_once(LIMB_DIR . 'core/controllers/site_object_controller.class.php');
 
class some_catalog_object_controller extends site_object_controller
{
  function _define_actions()
  {
    return array(
      'display' => array(
        'template_path' => '/some_catalog_object/display.html',
      ),
      'admin_display' => array(
        'template_path' => '/some_catalog_object/admin_display.html'
      ),
      'edit' => array(
        'popup' => true,
        'JIP' => true,
        'action_name' => strings :: get('edit_catalog_object', 'some_catalog'),
        'action_path' => '/some_catalog_object/edit_some_catalog_object_action',
        'template_path' => '/some_catalog_object/edit.html',
        'img_src' => '/shared/images/edit.gif'
      ),
      'delete' => array(
        'JIP' => true,
        'popup' => true,
        'action_name' => strings :: get('delete_catalog_object', 'some_catalog'),
        'action_path' => 'form_delete_site_object_action',
        'template_path' => '/site_object/delete.html',
        'img_src' => '/shared/images/rem.gif'
       )
    );
  }
}
?>

ini-файлы для поддержки мультиязычности

Как вы могли заметить в описании контроллера, мы пользуемся конструкциями вида strings :: get([…]) для получения локализованных строк. Для того, чтобы понимать, как мультиязычность работает в Limb, рекомендуется прочитать соответствующую страницу документации.

Наш some_catalog_ru.ini файл может иметь следующее содержание:

[constants]
create_catalog_folder = Создать раздел каталога
create_catalog_object = Создать элемент каталога
catalog_object = Элемент каталога
catalog_folder = Раздел каталога
catalog_object_creation  = Создание элемента каталога
catalog_object_edition  = Редактирование элемента каталога
catalog_folder_creation = Создание раздела каталога
catalog_folder_edition = Редактирование раздела каталога
image = Изображение
edit_catalog_object = Редактировать элемент каталога
edit_catalog_folder = Редактировать раздел каталога
delete_catalog_object = Удалить элемент каталога
delete_catalog_folder = Удалить раздел каталога
description = Описание
price = Цена

Для пользователей 2.2+. Раздел «extends» был удален из ini-файлов для упрощения начиная с версии Limb 2.3

[extends] // Больше не поддерживается!
filename = common

Создание классов для действий

Приступим к реализации некоторых действий, описанных в контроллере some_catalog_folder.

Начнем с действия 'create_some_catalog_folder' (PROJECT_DIR/core/actions/some_catalog_folder/create_some_catalog_folder_action.class.php). Это действие должно создать вложенную папку внутри текущей папки каталога. Вот код:

<?php
require_once(LIMB_DIR . '/core/actions/site_object/create_action.class.php');
 
class create_some_catalog_folder_action extends create_action
{
  function _define_controller_name()
  {
    return 'some_catalog_folder_controller';
  }
} 
?>

Просто, не так ли? :-) Мы просто указали имя контроллера, который должен незначаться новой папке каталога по умолчанию.

Нет необходимости создавать специальный класс действия для «редактирования», так как будет использоваться стандартный /site_object/edit_action.class.php. Смотрите выше класс контроллера some_catalog_folder.

Вот и все с some_catalog_folder. Вы можете спросить, где остальные действия? Они уже написаны за Вас в Limb, и в стандартной ситуации нет необходимости переопределять их.

Теперь перейдем к действию 'create_some_catalog_object' (PROJECT_DIR/core/actions/some_catalog_object/create_some_catalog_object_action.class.php):

<?php
 
class create_some_catalog_object_action extends form_create_site_object_action
{
  function _define_site_object_class_name()
  {
    return 'some_catalog_object';
  }  
 
  function _define_dataspace_name()
  {
    return 'some_catalog_object_form';
  }
 
  function _define_datamap()
  {
    return complex_array :: array_merge(
        parent :: _define_datamap(),
        array(
          'price' => 'price',
          'description' => ' description ',
          'image_id' => 'image_id'
        )
    );     
  }  
 
  function _init_validator()
  {
    parent :: _init_validator();
 
    $v = array();
    $this->validator->add_rule($v[] = array(LIMB_DIR . 'core/lib/validators/rules/required_rule', 'title'));
    $this->validator->add_rule($v[] = array(LIMB_DIR . 'core/lib/validators/rules/required_rule', 'description'));
    $this->validator->add_rule($v[] = array(LIMB_DIR . 'core/lib/validators/rules/required_rule', 'price'));
  }
}
 
?>
  • _define_site_object_class_name() - определяет класс объекта сайта.
  • _define_dataspace_name() - определяет источник данных, используемый этим действием. Возвращает атрибут 'name' компоненты формы в шаблоне WACT, привязанном к этому дейстию. Действие и шаблон будут совместно использовать этот источник данных.
  • Заметьте также, как мы проверяем значения, приходящие в запросе: мы определили правила в методе _init_validator(). Во избежание затрат на разбор PHP кода до выполнения, мы используем технику отложенной загрузки, похожую на эту.

Вы можете обнаружить набор различных правил в каталоге LIMB_DIR/core/lib/validators/rules. Код, представленный выше, должен быть понятным сам по себе, хотя, возможно, вы захотите поковыряться в базовом классе form_create_site_object_action :)

  • Пожалуйста, обратите внимание, что через метод _define_datamap() мы определяем как должны отображаться переменные запроса на атрибуты объекта сайта.

Теперь настало время для реализации действий some_catalog_object_controller. Единственное, что нужно здесь написать - это действие «редактировать» (PROJECT_DIR/core/actions/some_catalog_object/edit_some_catalog_object_action.class.php), так как остальные уже написаны в Limb.

<?php
 
class edit_some_catalog_object_action extends form_edit_site_object_action
{
  function _define_site_object_class_name()
  {
    return 'some_catalog_object';
  }  
 
  function _define_dataspace_name()
  {
    return 'some_catalog_object_form';
  }
 
  function _define_datamap()
  {
    return complex_array :: array_merge(
        parent :: _define_datamap(),
        array(
          'price' => 'price',
          'description' => ' description ',
          'image_id' => 'image_id'
        )
    );     
  }  
 
  function _init_validator()
  {
    parent :: _init_validator();
 
    $this->validator->add_rule($v1 = array(LIMB_DIR . 'core/lib/validators/rules/required_rule', 'title'));
    $this->validator->add_rule($v2 = array(LIMB_DIR . 'core/lib/validators/rules/required_rule', 'description'));
    $this->validator->add_rule($v3 = array(LIMB_DIR . 'core/lib/validators/rules/required_rule', 'price'));
  }
}
 
?>

Ну, вроде, с действиями покончено.

Некоторые действия могут быть очень похожими и отличаться лишь небольшими участками кода, нам это известно. Было бы прекрасно иметь некоторое средство генерации для действий на основе метаинформации. В настоящее время все, что мы можем сказать - это запланировано :-)

Создание файлов шаблонов

В этом разделе мы создадим парочку шаблонов для действий объектов сайта. Почему только пару? Ну, потому что некоторые действия повторно используют стандартные шаблоны, поставляемые с Limb, а некоторым действиям шаблон вообще не нужен. Скажем, действие 'удалить' объекта some_catalog_object использует стандартный шаблон LIMB_DIR/design/default/templates/site_object/delete.html. Посмотрите выше на объявление действия в some_catalog_object_controller. Иногда вообще нет шаблона, так как это не интерактивное действие.

Шаблоны Limb - активные. Обычно, все операции выборки из БД производятся источниками данных шаблонов (хотя это не обязательное поведение).

Вот шаблон для действия 'admin_display' объекта сайта some_catalog_folder. Мы помещаем его в PROJECT_DIR/design/main/templates/some_catalog_folder/admin_display.html:

<core:WRAP file="admin/admin_display_page.html" placeholder="content">
 
<span class=jip>
<fetch:MAPPED>
<core:INCLUDE file="jip_actions/extended.html">
</fetch:MAPPED>
</span>
 
<fetch:SUB_BRANCH target='folders'>
    <core:PARAMETER name='loader_class_name' value='site_object'>
    <core:PARAMETER name='order' value='priority=ASC'>
</fetch:SUB_BRANCH>
 
<fetch:SUB_BRANCH target='some_catalog_objects'>
    <core:PARAMETER name='loader_class_name' value='some_catalog_object'>
    <core:PARAMETER name='order' value='priority=ASC'>
</fetch:SUB_BRANCH>
 
<grid:LIST id='folders'>
<table width=100%>
<tr>
    <th><grid:SELECTORS_TOGGLER></th>
    <th><locale:STRING name='catalog_folder' file='catalog'></th>
    <th><locale:STRING name='modified_date'></th>
    <th><locale:STRING name='items_order'></th>
    <th><locale:STRING name='actions'></th>
</tr>
 
<grid:ITERATOR>
<tr>
<td><core:INCLUDE file="/admin/selector.html"></td>
<td><a href='{$path}?action=admin_display'>{$title}({$children})]]</td>
<td><locale:DATE_FORMAT hash_id='modified_date' type='stamp' locale_format='short_date_time'></td>
<td><core:INCLUDE file='/admin/priority_input.html'></td>
<td><core:INCLUDE file="jip_actions/dropdown.html"></td>
</tr>
</grid:ITERATOR>
 
<tr>
    <td colspan='4' align='left'><core:INCLUDE file='/admin/delete_button.html'></td>
    <td colspan='2'><core:INCLUDE file='/admin/priority_button.html'></td>
</tr>
</table>
</grid:LIST>
 
<core:INCLUDE file="/admin/pager.html">
 
<grid:LIST id='some_catalog_objects'>
<table width=100%>
<tr>
    <th><grid:SELECTORS_TOGGLER></th>
    <th><locale:STRING name='catalog_object' file='catalog'></th>
    <th><locale:STRING name='modified_date'></th>
    <th><locale:STRING name='items_order'></th>
    <th><locale:STRING name='actions'></th>
</tr>
 
<grid:ITERATOR>
<tr>
<td><core:INCLUDE file="/admin/selector.html"></td>
<td><a href='{$path}?action=admin_display'>{$title}]]</td>
<td><locale:DATE_FORMAT hash_id='modified_date' type='stamp' locale_format='short_date_time'></td>
<td><core:INCLUDE file='/admin/priority_input.html'></td>
<td><core:INCLUDE file="jip_actions/dropdown.html"></td>
</tr>
</grid:ITERATOR>
 
<tr>
    <td colspan='4' align='left'><core:INCLUDE file='/admin/delete_button.html'></td>
    <td><core:INCLUDE file='/admin/priority_button.html'></td>
</tr>
</table>
</grid:LIST>

Этот шаблон состоит из 2 таблиц для отображения вложенных папок и вложенных объектов каталога.

  • <fetch:SUB_BRANCH> получает набор детей some_catalog_folders для глубины(depth) = 1 по умолчанию и присваит их к целевому компоненту 'folders'.
  • <grid:LIST> используется для отображения табличных данных. <grid:LIST> и <grid:ITERATOR>

выводят данные только, если в наборе данных есть хоть одна запись. (Тэг <grid:DEFAULT> может быть использован для пустго набора данных).

Давайте реализуем шаблон для действия «создать» объекта сайта some_catalog_folder. Мы поместим его в PROJECT_DIR/design/main/templates/some_catalog_folder/create.html:

<core:WRAP file="popup.html" placeholder="content">
<h3>  <locale:STRING name='catalog_folder_creation' file='catalog'> </h3>
 
<form method="post" name="create_some_catalog_folder" id="create_some_catalog_folder">
  <table width="100%" border="0" cellspacing="2" cellpadding="3">
        <core:INCLUDE file='/admin/admin_form_items/folder_form_fields.html'>
    <tr>
      <td colspan=2 align=center height=30>
       <action_button action="create_some_catalog_folder" name="create"  type="submit" id="create" locale_value="create" class="button">
      &nbsp;
      <input name="cancel" type="button" id="cancel" locale_value="close" onclick='window.close();' class="button">
      </td>
    </tr>
  </table>
</form>

Поскольку поля форм для создания и редактирования совпадают, удобно обобщить их. Вот почему мы включаем их через тэг &ltcore:INCLUDE file=«/some_catalog_object/form_fields.html»>.

Вот содержимое PROJECT_DIR/design/main/templates/some_catalog_object/form_fields.html:

<table width=100% border=0 cellspacing=0 cellpadding=0 height=100%>
<tr>
  <td height=1%>
    <!--BEGIN: tab-->
    <table width=100% border=0 cellspacing=0 cellpadding=0 id=tabulator active=param_req class=tabulator>
    <col span=100 valign=bottom class=form>
 
    <tr>
        <td class=tab>&nbsp;</td>
        <td id=param_req_box class=tab-active>
            <table border=0 cellspacing=0 cellpadding=0 height=100%>
            <tr>
              <td nowrap class=label-active id=param_req>
                <a href='JavaScript:void(0);'><locale:STRING name='properties'></a>
              </td>
            </tr>
            </table>
        </td>
        <td class=tab id=param_text_box>
            <table border=0 cellspacing=0 cellpadding=0 height=100%>
            <tr>
 
                <td nowrap class=label id=param_text><a href='JavaScript:void(0);'><locale:STRING name='content'></a></td>
            </tr>
            </table>
        </td>
        <td class="tab" width="100%">&nbsp;</td>
 
    </tr>
    </table>
    <!--END: tab-->
  </td>
</tr>
<core:INCLUDE file='/admin/admin_form_items/errors.html'>
<tr>
 
  <td height=100% valign=top>
 
      <!--BEGIN: tab #1-->
      <table width="100%" border="0" cellspacing="0" cellpadding="0" style='padding:5px 10px 1px 5px;' id=param_req_content>
        <col align=right width=200 class=labels>
 
         <core:INCLUDE file='/admin/admin_form_items/parent_select.html'>
         <core:INCLUDE file='/admin/admin_form_items/title.html'>
 
         <core:INCLUDE file='/admin/admin_form_items/image_select.html'>
 
         <tr>
           <td><label for="price"><span class='req'>*</span><locale:STRING name=' price ' file='catalog'></label></td>
           <td><input type="text" name="price" id="price" label="price" class='input' size='10'>
          </td>
        </tr>
    </table>
    <!--END: tab #1-->
 
    <!--BEGIN: tab #2-->
    <table width="100%" border="0" cellspacing="3" cellpadding="0" height=100% id=param_text_content>
    <tr>
 
      <td colspan=2><richedit name="description" id="description" label="Description" rows="25" style='width:100%;'></richedit>
      </td>
    </tr>
    </table>
    <!--END: tab #2-->
 
  </td>
</tr>
</table>
<script>
    init_tab('param_req', 'tabulator', 'label', 'tab');
    init_tab('param_text', 'tabulator', 'label', 'tab', 'window.onresize()');
</script>

Регистрация объектов сайта

Пожалуйста, прочтите register new site objects documentation page для более подробной информации.

Единственный объект сайта, который нам надо зарегистрировать - some_catalog_folder. Нам не нужно регистрировать some_catalog_object, так как some_catalog_folder знает как и где расположть свои вложенные some_catalog_objectы.

Прежде всего необходимо войти в систему! Перейдите на страницу /root/admin и найдите там действие 'register new site object' (зарегистрировать новый объект сайта). Щелкните по нему и введите следующие значения для вашего нового some_catalog_folder:

  • class_name = some_catalog_folder
  • controller_name = some_catalog_folder_controller
  • identifier = catalog
  • title = My new catalog
  • path = /root

Однако Ваша папка каталога еще не доступна. Перейдите в /root/admin/classes, найдите Ваш недавно установленный some_catalog_folder класс и задайте доступ к нему для групп. За более подробной информацией обращайтесь к документации по Политике доступа.

Я думаю, это все, наконец! :-) Вы можете найти Ваш объект сайта в дереве /root/admin/site_structure. Попробуйте посмореть на него с фронтальной части, набрав /root/catalog или в административной зоне /root/catalog?action=admin_display

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
   __  ___   __ __  _____     __   ___ 
  /  |/  /  / // / / ___/ __ / /  / _ \
 / /|_/ /  / _  / / /__  / // /  / ___/
/_/  /_/  /_//_/  \___/  \___/  /_/
 
limb2/ru/howtos/create_new_site_object.txt · Последние изменения: 2010/11/10 10:02 (внешнее изменение)