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

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


limb2:en:howtos:create_new_site_object

Creating new site objects from the scratch

We hope you've already read the basic LIMB 2.x principles and got the main idea. So it's time to implement your very first custom site objects, isn't it? :-)

Please note we're going to describe very simple custom site objects implementation, the main goal is to shed some light on LIMB 2.x internals. If you need to create something way more complex, you'd probably want to browse the LIMB source and consult developers about any problems you might face. You can also take a look at the demo site source if anything goes wrong or may seem to be unclear.

In order to create the new site object you're usually required to accomplish the following steps:

  1. Plan your new site object: whether it's a site object or a content object, probable attributes and required functionality
  2. Create a class for it(inherit from site_object or content_object base class)
  3. Create a db_table class if you are creating a content object
  4. Create a site object controller class for it.
  5. Create action classes to implement functionality
  6. Create template files for actions with GUI (good candidates are display, edit, create actions templates).
  7. Register the new site object in the object tree using admin_page's register_new_object action.
  8. Assign appropriate access permissions
  9. Create ini-files with localized strings (optional)

Planning

Let's imagine we need a sort of very specific catalog. Suppose our catalog has some form of hierarchically linked folders. Every folder contains catalog folders as well as catalog objects.

To implement this we need 2 types of new site objects: some_catalog_object and some_catalog_folder. Below we'll try to create all necessary classes and templates to implement our simple catalog functionality step by step.

some_catalog_folder will be a common site_object as far as it doesn't have any additional attributes other than 'identifier' and 'title'.

some_catalog_object is a content object since it would be nice for it to support versioning, it has the following attributes:

  • 'identifier' - VARCHAR
  • 'title' - VARCHAR
  • 'description' - VARCHAR
  • 'price' - FLOAT
  • 'image_id' - INTEGER, id of the image from the LIMB media repository

Creating site object classes

Site object classes are used to define the fetching and saving behaviour. Usually the only thing you need is to inherit your custom site object class from one of the 2 base classes: site_object or content_object. We won't go into advanced details in this tutorial. Let's just keep it simple for a while.

In fact you have ability not to create a class for catalog_folder since there is no need to specify controller class name in Limb 2.3+ for every site object. (in Limb 2.2+ it was neccessary to specify controller in site_object class). Any way we will continue since we want to specify special icon for our catalog folders.

Let's create a file for our some_catalog_folder class in site_objects folder of our project. The path to the file will look like this: PROJECT_DIR/core/model/site_objects/some_catalog_folder.class.php:

And the contents:

<?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' => 1,         //was used for sorting in the tree, e.g. folders usually have this one set to 0, 
                                 //it was used to for 'folders first' sorting functionality, currently not implemented
      'can_be_parent' => 1,                                         // since it's a catalog folder 
      'icon' => '/shared/images/folder.gif'                         // icon to display in tree structure
    );
  }
}
?>

Next step is a class for some_catalog_object. The file with the class will has a path like this: 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), 
       // tells to the LIMB search engine to index some_catalog_object by 'description' attribute 
       //and use 'search_weight' for relevant sorting
     ));
  }
 
  function _define_class_properties()
  {
    return array(
      'class_ordr' => 1,
       'can_be_parent' => 0, 
       'auto_identifier' => true   //there's no need to set identifier manually for this object
     );
  }
}
 
?>

Creating db_table classes

LIMB uses db_table mechanism to abstract db calls to tables. This mechanism allows to emulate nested deletes and simplify basic operations. At the moment you have to duplicate your db tables with corresponding db_table classes. There's no db schema auto generation, yet it's planned to appear some day in the future. So first you have to create tables in database and then describe them with db_tables.

You have only to create db_table for some_catalog_object, there's no need to create one for some_catalog_folder, since it doesn't have versions thus the default sys_site_object_db_table is used(this behaviour is defined in the base site_object class).

Since some_catalog_object is inherited from the content_object base class it keeps all attributes in one db table by default. Appropriate db_table class is used for carrying-out fetching/creating/deleting. some_catalog_object_db_table will be used by default(the base class tries to guess which db_table to use if not explicitly specified).

You can override db_table class name for the object by db_table_name property (do not append '_db_table' postfix), e.g.

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

or like this

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

some_catalog_object_db_table has the following code (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' => '', //similar to array('type' => 'string') used for convenience of typing
      'price' => array('type' => 'numeric'),
    );
  }
}
?>

Columns definitions are useful in type casting and filtering. String type used if the definition for a column is empty. The list of supported types at the moment:

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

some_catalog_object - is a default name of data base table some_catalog_object_db_table class will work with. You can override name of the table, placing some_catalog_object_db_table :: _define_db_table_name() method:

function _define_db_table_name()
{
  return 'some_other_name';
}

DB schema for this table is as follows:

some_catalog_object  CREATE TABLE `some_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

Creating controllers

The controller defines some site object functionality. In Limb 2.3+ it's possible to assign any controller to a site object.

Our some_catalog_folder is able to display itself in 2 lists (admin_display + display), create child objects and folders, edit and delete itself.

Ok, here goes some_catalog_folder_controller source (PROJECT_DIR/core/controllers/some_catalog_folder_controller.class.php). There will be a detailed explanation for every attribute below:

<?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'; // 
  }     
 
  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'
      )
    );
  }
}
?>

Let's clarify some attributes:

  • JIP flag means whether the action is to be displayed in the template Just In Place controls.
  • action_name holds the localized full name of this action.
  • action_path option tells the relative path to the action object. It's important to know how LIMB resolves relative files paths to understand the principle. Note that we don't append '.class.php' - this done automatically just to save your typing time.
  • template_path points to the relative template file to display the action result. The same resolving technique]] is applied to it too.
  • popup flag means that action should be performed in the popup window.
  • img_src is used to display an icon for this action.

For Limb 2.2 users. Note: permissions_required option was removed from controller specification due to access policy changes. Limb 2.3+ access policy was greately simplified so there is no need for permissions_required attribute any more.

It's a turn for the some_catalog_object controller (PROJECT_DIR/core/controllers/some_catalog_object_controller.class.php):

<?php
 
require_once(LIMB_DIR . 'core/controllers/site_object_controller.class.php');
require_once(LIMB_DIR . 'core/lib/i18n/strings.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'
       )
    );
  }
}
?>

Localized *.ini files

As you may have noted from controllers definition we use strings :: get([…]) calls to get the localized values. You'll definitely want to read more on LIMB I18N and L10N conceptions.

Our some_catalog_en.ini file is as follows:

[constants]
create_catalog_folder = Create catalog folder
create_catalog_object = Create catalog object
catalog_object = Catalog object
catalog_folder=Folder
catalog_object_creation  = Catalog object creation
catalog_object_edition  = Catalog object edition
catalog_folder_creation = Catalog folder creation
catalog_folder_edition = Catalog folder edition
catalog_image_creation  = Image creation
catalog_image_edition  = Image edition
image = Image
edit_catalog_object = Edit catalog object
edit_catalog_folder = Edit catalog folder
edit_catalog_image = Edit catalog image
delete_catalog_object = Delete catalog object
delete_catalog_folder = Delete catalog folder
description = Description
price = Price

For Limb 2.2+ users. Extends section was removed in Limb 2.3 for simplification.

[extends]
filename = common

Creating action classes

Let's implement some actions defined in our some_catalog_folder controller.

First goes the 'create_some_catalog_folder' action (PROJECT_DIR/core/actions/some_catalog_folder/create_some_catalog_folder_action.class.php). This action should create a nested catalog folder under the current catalog folder. Here's the code:

<?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';
  }
} 
?>

Simple, isn't it? :-) We just specified controller name that should be assigned to new catalog folder by default.

There is no need to create a special action class for «edit» action since the standart /site_object/edit_action.class.php will be used. See some_catalog_folder controller class above.

That's it for the some_catalog_folder. You may ask where're the rest of actions? Well, they're already coded for you in LIMB and there's no need to override them in standart situations.

Then comes 'create_some_catalog_object' action (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() - defines the class of the site object.
  • _define_dataspace_name() - defines the dataspace to be used by this action. It returns the value of the 'name' attribute of the form component in the WACT template assigned to the action. There will be created a common dataspace shared by the action and the template.
  • Note also how we validate values coming from the request: we define rules in _init_validator() method. To avoid the overhead of parsing PHP code before real execution we use lazy load technique similiar to http://wact.sourceforge.net/index.php/ResolveHandle'>this one.

You can find a bunch of different rules in LIMB_DIR/core/lib/validators/rules directory. The code above should be self-explanatory yet you'll definitely want to dig the form_create_site_object_action base class :)

  • Please note that with _define_datamap() method we define how request variables should be mapped into site object's attributes.

Well, it's time for the some_catalog_object_controller actions implementaion. The only one we have to code here is 'edit'action (PROJECT_DIR/core/actions/some_catalog_object/edit_some_catalog_object_action.class.php), since the rest of them are already coded for you in 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'));
  }
}
 
?>

Well that should be it for actions!

Some actions may seem to be very similar with only several different pieces of code, yep, we know about it. It could be very nice to have some auto code generation for actions based on meta information. At the moment all we can say is that it's planned :-)

Creating template files

In this section we'll create a couple of templates for site objects actions. Why only a couple? Well, because some action re-use the default templates bundled with LIMB and some action don't need a template at all. Say, 'delete' action of the some_catalog_object - it makes use of the LIMB_DIR/design/default/templates/site_object/delete.html default template, take a look at action declaration in some_catalog_object_controller above. And sometimes there's no template at all, since its a non-interactive action(not covered in this tutorial though).

LIMB templates are active. Usually all db fetching operations are performed by templates datasources(not a mandatory behaviour though).

Here is the template for the 'admin_display' action of some_catalog_folder site object, we place it in 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>

This template contains 2 tables to display child folders and child catalog objects.

  • <fetch:SUB_BRANCH> gets a bunch of child some_catalog_folders at depth=1 by default and

assigns them to target 'folders' component.

  • <grid:LIST> is used to display tabular data. <grid:LIST> and <grid:ITERATOR>

make output only if the data set has at least one record (<grid:DEFAULT> tag can be in case of empty data set).

Let's implement template for the 'create' action of the some_catalog_folder site object, we place it in 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>

And the last is one is the template for the 'create' action of the some_catalog_object site object, we place it in PROJECT_DIR/design/main/templates/some_catalog_object/create.html:

<core:WRAP file="popup.html" placeholder="content">
 
<form method="post" name="catalog_object_form" id="catalog_object_form">
    <table width=100% border=0 cellspacing=0 cellpadding=0 height=100%>
    <tr>
      <td colspan=2 class=table-title>
        <locale:STRING name='catalog_object_creation' file='catalog'> 
        <h3> "<fetch:MAPPED>{$title}</fetch:MAPPED>" </h3>
      </td>
    </tr>
    <tr>
      <td colspan=2 height=100% valign=top class=com4>
        <core:INCLUDE file="/some_catalog_object/form_fields.html">
      </td>
    </tr>
 
    <core:INCLUDE file='/admin/admin_form_items/req_info.html'>
    <tr>
    <td colspan=2 align=center height=30>
    <action_button action="create_catalog_object" 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>

As long as the form fields are similar for creating and editing it's convenient to share them, that's why we include them with &ltcore:INCLUDE file=«/some_catalog_object/form_fields.html»> tag.

Here's the contents of 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>

Registering site objects

Please take a look at register new site objects documentation page for more details.

The only site object we have to register is some_catalog_folder, we don't need to register some_catalog_object since some_catalog_folder knows how and where to place its children some_catalog_objects.

First you have to be logged in! Go to the /root/admin page then and find there 'register new site object' action. Click it and enter the following values for your new some_catalog_folder:

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

However your catalog folder is not accessible yet. Go to the /root/admin/controllers (/root/admin/classes in LIMB 2.2.x), find your newly installed some_catalog_folder_controller class and set access for groups for it. For more information take a look at the access policy documentation page.

I guess that should be it, finally! :) You should be able to find your site object in the site tree /root/admin/site_structure. Try browsing it in the 'front' at /root/catalog and in the 'back' /root/catalog?action=admin_display(as you can see this separation is very thin and transparent)

Обсуждение

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