Forum for discussing general topics related to Couch.
16 posts Page 2 of 2
Sure.

When the parser analyzes a given script, it breaks it up into 'code' and 'text' where 'text' is basically everything that is not a Couch tag.

Info about both are pushed onto the context stack ($CTX->push) but since the text block is basically anonymous, the 'name' part for it remains blank (as opposed to 'code' where the name identifies the tag in question).
Thank you, it helps.

Next, there is one more thing that bothers my mind every time I analyze my log: class KFuncs->_handle_extends. I understand it as that every time a snippet is embedded or rendered, Couch checks for <cms:extends /> tag. With a starter default theme, without any complications, I counted over 30 calls of _handle_extends. Is there any way to avoid this?
Is there any way to avoid this?
Well, if you are sure you don't want to use the <cms:extends> feature, you may try unregistering the following event listener that functions.php places by default in KFuncs constructor -
Code: Select all
$this->add_event_listener( 'alter_parsed_dom', array('KFuncs', '_handle_extends') );
Thank you, Kamran. Of course, unregistering would disable that feature, shaving off some cycles, however I wondered if it was possible to write the code so that it would be triggered only by the tag <cms:extends />. Perhaps, it was simply not possible.

My next question is about KNestable class and its derivatives. I am trying to approach this class (found in couch/folders.php) and study it. There are many auxiliary functions and callbacks spread around Couch (some went to tags.php), visitor functions, menuitem concept (most hard for me currently). It would help to have any comments about this class and maybe an insight about general patterns that were used.

P.S. Also, it is new to me that folders are not available for non-clonable templates. Folders are in database, but selector is not visible - so can not set a folder (perhaps, dynamically generated from a clonable template) to a single template. Superadmin is free to create any number of non-clonable templates, if she opts to do so, for example - item1.php, item2.php, item3.php setting a folder for each of one as if a tag. Maybe unpractical, yes, giving better options in Couch (nested pages and clonable templates), but possible. Anyway, tag cms:folder is not ignored and folders are placed into database. Why is it so?
@KK, your comments, please?
@trendoman, apologies for the delay in my reply.
I'll try to answer your query now -
..about KNestable class and its derivatives. I am trying to approach this class (found in couch/folders.php) and study it. There are many auxiliary functions and callbacks spread around Couch (some went to tags.php), visitor functions, menuitem concept (most hard for me currently)

The admin-panel comprises of several distinct components, e.g.
1. The sidebar with its menu,
2. Actions e.g.
- The toolbar buttons on the top,
- Widgets to filter the page listing (e.g. the 'folder' dropdown),
- Buttons at the bottom (e.g. save, view),
3. The actual fields in the form etc.

There is a general pattern to how these components are rendered in Couch v2.x -
Instead of directly rendering them in a hard-coded way (as was the case in Couch v1.x), Couch raises an event asking any participating code to 'register' these components with it.

In reply, the core code (and addons) provide meta-data about these components e.g. if an addon is requesting a particular button to be shown in the toolbar, it will provide all required data like the text, the link, the icon, the code to be called if access control is to be enforced etc.

Once all the data is gathered, Couch raises another event giving an opportunity to all participating code to make any changes to the gathered data.
It is only now that the components are finally rendered (It should be easy to see that this two-step process opens up the admin-panel to the kind of flexibility that was not hitherto available).

Internally, when the components are registered, Couch stores them as 'trees' of objects (i.e. in a hierarchical manner)
There are only two core functions (both present in functions.php) involved in the process -
Kfuncs:: _register_menuitem() - registers a component in a tree under a particular parent
KFuncs::_get_menu() - returns all components registered under a particular parent (this is used while rendering).

This terminology, I think, is the source of your confusion.
Please note that '_register_menuitem', despite its name, is not used *only* for registering menuitems shown in the sidebar - it is used for registering the toolbar buttons, the fields and many other items.
Similarly, on the converse site, '_get_menu' is used internally to retrieve many different components e.g. the fields to be rendered in a form.
Keep that in mind and things will become easier to follow.

Moving on - the structure used internally to store the definitions of the various components, as mentioned earlier, is a 'tree'.
Couch from v1.0 already had something that used a comparable structure - these were the 'folders'. You'll remember from <cms:folders> tag how we can retrieve only a particular branch of the folder tree (or just the folders under a particular sub-folder) using the 'childof' and 'root' parameters.

You'll also recall how the tag makes it easy for us to iterate through the different levels of a folder tree by reporting back as the levels change. This is done internally by providing a custom function to the tag that it calls back as it hops from one level to another visiting the nodes it encounters. This custom function is the 'visitor' function that you mentioned - it is nothing more than a normal function provided by us which is called back by the core folder code as it navigates through a folder tree providing info about its current location.

Now exactly the same functionality was later required when 'Nested pages' were introduced. It was natural that we made both the 'KFolder' class and the new 'KNestedPage' class derive from a common parent - the 'KNestable' class that provided the common code including the visit() function (please see folder.php).

In Couch v2.0, the same functionality was needed for registering the renderable components and so the new class 'KAdminMenuItem' was derived from 'KNestedPage' (and hence from 'KNestable'). Additonally, the form fields required some special consideration so they were given a sub-class of 'KAdminMenuItem' - you can persuse the code in folders.php.

With that info, you can use your debugger and expect to see the hierarchical structures containing the definition for the said components.
E.g, take a look at 'base.php' to see how it registers all the 'actions' for the 'list-view'
Code: Select all
// register actions for each category
$arr_action_types = array(
    'toolbar'  => 'add_toolbar_button',
    'filter'   => 'add_filter_action',
    'batch'    => 'add_batch_action',
    'page'     => 'add_page_action',
    'extended' => 'add_extended_action',
    'row'      => 'add_row_action'
);

Follow the functions mentioned above and you'll find that finally they all end up using the aforementioned '_register_menuitem()' function.

Similarly, the 'page-view' registers (after its own 'actions') 'fields' by eventually calling 'add_form_field()' which in turn again ends up calling the '_register_menuitem()' function.

On the converse side (i.e. fetching the sub-trees), it is usually the templates (couch\theme\_system) that call the core 'KFuncs::_get_menu()' through the tags (in tags.php) used by them e.g.
Code: Select all
<cms:admin_menuitems depth='1'> (in sidebar.html)
<cms:admin_form_fields depth='1'> (in content_form.html)
<cms:admin_form_fields childof=k_field_name depth='1'> (in form_row_group.html)

Point is, you'll find many auxiliary functions depending upon whether an actual menu-item, an action or a field is being registered (or fetched) but eventually all will end up using Kfuncs:: _register_menuitem() (or KFuncs::_get_menu()).

And these two do nothing more than maintaining a tree structure and retrieving data from it.

Hope this explanation helps.
16 posts Page 2 of 2