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

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


limb2:en:principles

The basic Limb principles

What is site object?

The central architectural unit of Limb is a site object. Every single piece of Limb CMS data is a site object, be it a workflow document or just a guest book reply.

All site objects are hierarchicaly organized in the objects tree. You can find it at /root/admin/site_structure page.

The site object is defined with set of different attributes. The most important are:

  • node_id - integer, specifies the node in the object tree to which the site object is attached
  • id - integer, specifies unique id of the site object
  • identifier - string, allows to build a human-readable path to the object in the object tree
  • title - string, allows a name every object

Why having 'node_id' and 'id'? In future this feature will help aliasing site objects. Currently it's not implemented though and 'node_id' is mostly used.

Actually there're 2 ways of fetching the specific site object:

  • by the full tree path which comprises site objects identifiers delimetered with /, e.g. /root/catalog/TDD/refactoring
  • by the node id, e.g. /root?node_id=92

What is content object?

There're two types of site objects:

  • simple site object
  • content object.

The main difference of the latter is its being under very simple Limb version control, every modification results in a new version. This way we resolve concurrent editing. The basic implementation of the content object ties it with a database record. Most of the content objects never require any complex O-R mapping and if any the developer is required to resolve mapping manually.

Here goes the example of the article content object:

<?php
require_once(LIMB_DIR . 'core/model/site_objects/content_object.class.php');
class article extends content_object
{
 function _define_attributes_definition()
 {
  return complex_array :: array_merge(
    parent :: _define_attributes_definition(),
    array(
     'content' => array('search' => true, 'search_weight' => 1),
     'annotation' => array('search' => true, 'search_weight' => 5),
     'author' => array('search' => true, 'search_weight' => 10),
     'source' => array('search' => true, 'search_weight' => 10),
    )
  );
 }
 
 function _define_class_properties()
 {
  return array(
   'class_ordr' => 1,
   'can_be_parent' => 0,
   'icon' => '/shared/generic.gif',
  );
 }
}
?>

What is site object controller?

Every site object linked with some controller, it defines what kind of actions the site object has. Since Limb 2.3+ it's possible to assign different controllers to site objects of some class.

Here is the example of site object controller:

<?php
require_once(LIMB_DIR . 'core/controllers/site_object_controller.class.php');
require_once(LIMB_DIR . 'core/lib/locale/strings.class.php');
 
class article_controller extends site_object_controller
{
 function _define_actions()
 {
   return array(
    'display' => array(
      'template_path' => '/article/display.html',
    ),
    'admin_detail' => array(
      'template_path' => '/admin/object_detail_info.html',
      'popup' => true,
      'JIP' => true,
      'img_src' => '/shared/images/admin_detail.gif',
      'action_name' => strings :: get('detail_info'),
    ),
    'print_version' => array(
      'template_path' => '/article/print_version.html',
      'action_name' => strings :: get('print_version_action', 'document'),
      'display_in_breadcrumbs' => false,
    ),
    'edit' => array(
      'popup' => true,
      'JIP' => true,
      'action_name' => strings :: get('edit_article', 'article'),
      'action_path' => '/article/edit_article_action',
      'template_path' => '/article/edit.html',
      'img_src' => '/shared/images/edit.gif'
    ),
    'publish' => array(
      'popup' => true,
      'JIP' => true,
      'action_name' => strings :: get('publish'),
      'action_path' => '/doc_flow_object/set_publish_status_action',
      'img_src' => '/shared/images/publish.gif',
      'can_have_access_template' => true,
    ),
    'unpublish' => array(
      'popup' => true,
      'JIP' => true,
      'action_name' => strings :: get('unpublish'),
      'action_path' => '/doc_flow_object/set_publish_status_action',
      'img_src' => '/shared/images/unpublish.gif',
      'can_have_access_template' => true,
    ),
    'delete' => array(
      'JIP' => true,
      'popup' => true,
      'action_name' => strings :: get('delete_article', 'article'),
      'action_path' => '/article/delete_article_action',
      'template_path' => '/site_object/delete.html',
      'img_src' => '/shared/images/rem.gif'
    ),
  );
 }
}
?>

What is action?

The action is….action can be whatever you want! There're a few base actions that ease the developers life though.

The action is transferred via 'action' attribute of the $_REQUEST, so

http://somedomain.com/root?&action=edit&node_id=83

will require the site object with node id 83 to perform 'edit' action.

If we had the object with node id 83 placed in /root/documents and it had 'article1' identifier, the request below would mean the same:

http://somedomain.com/root/documents/article1?action=edit

Let's examine the 'edit' section of the article controller. Well first of all we have 'action_path' set to '/article/edit_article_action', the controller is going to fire 'edit_article_action' (the path to the class is found with file path resolving technique]]):

<?php
require_once(LIMB_DIR . 'core/actions/form_edit_site_object_action.class.php');
class edit_article_action extends form_edit_site_object_action
{
 function _define_site_object_class_name()
 {
   return 'article';
 }
 
 function _define_dataspace_name()
 {
   return 'article_form';
 }
 
 function _define_datamap()
 {
   return complex_array :: array_merge(
    parent :: _define_datamap(),
     array(
      'article_content' => 'content',
      'annotation' => 'annotation',
      'author' => 'author',
      'source' => 'source',
      'uri' => 'uri',
     )
   );
 }
 
 function _init_validator()
 {
  parent :: _init_validator();
 
  $this->validator->add_rule(new required_rule('title'));
  $this->validator->add_rule(new required_rule('author'));
  $this->validator->add_rule(new required_rule('article_content'));
 }
}
?<

Simple, isn't it?

What about action template?

Also in the 'edit' section of the article controller we have optional attribute 'template_path' set to '/article/edit.html', the controller is going to initialize WACT template and pass it to action. This template might look as follows:

<core:WRAP file="popup.html" placeholder="content">
 
<form method="post" name="article_form" id="article_form">
  <table width=100% border=0 cellspacing=0 cellpadding=0 height=100%>
  <tr>
    <td colspan=2 class=table-title><locale:STRING name='article_edition' file='article'> 
  <h3> "<fetch:MAPPED>{$title}</fetch:MAPPED>" </h3></td>
 
  </tr>
  <tr>
    <td colspan=2 height=100% valign=top class=com4>
        <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>
        <tr>
 
          <td><label for="identifier"><span class='req'>*</span><locale:STRING name='identifier' ></label></td>
          <td><input type="text" name="identifier" id="identifier" label="Identifier" class='input'></td>
        </tr>
 
        <tr>
          <td><label for="title"><span class='req'>*</span><locale:STRING name='title' ></label></td>
          <td><input type="text" name="title" id="title" label="Title" class='input' size='40'></td>
 
        </tr>
        <tr>
          <td><label for="annotation"><locale:STRING name='annotation'></label></td>
          <td><textarea class='textarea' name="annotation" id="annotation" label="Annotation" cols='40' rows='5'></textarea></td>
 
        </tr>
        <tr>
          <td><label for="author"><span class=req>*</span><locale:STRING name='author' file='article'></label></td>
          <td><input type="text" name="author" id="author" label="Author" size="60" class='input'></td>
 
        </tr>
        <tr>
          <td><label for="source"><locale:STRING name='source' file='article'></label></td>
          <td><input type="text" name="source" id="source" label="Source" size="60" class='input'></td>
 
        </tr>
        <tr>
          <td><label for="uri"><locale:STRING name='uri' file='article'></label></td>
          <td><input type="text" name="uri" id="uri" label="URL" size="60" class='input'></td>
        </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td colspan=2 align=center height=30>
     <action_button action="edit" name="update" type="submit" id="update" value="update" reload_parent="true" class="button">
    &nbsp;
    <input name="cancel" type="button" id="cancel" value="close" onclick='window.close();' class="button">
    </td>
  </tr>
  </table>
</form>

Every action has its View in the $_view attribute (rarely used though, our templates have active behaviour).

Extra stuff

Site objects passed around as arrays in the Limb, turning into objects only when it's needed. This allows to decrease unnecessary overhead greatly. Furthermore, they're transfered to WACT templates as array datasets which allows to use all the nice features of WACT.

There's no code generation for site objects yet and this colud be a very nice feature

Обсуждение

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