@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 parentKFuncs::_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.