Hi,
As most of Couch's users would know, tag <cms:field> (used from within <cms:config_form_view> tag block) offers a powerful way to customize the looks of fields as they appear in the admin-panel while editing a page (viewtopic.php?f=5&t=10241).
As mentioned in the documentation post linked above, the content enclosed within the <cms:field> tag-pair is dynamic i.e. although it is defined on the front-end, it executes in the context of the admin-panel.
An example of which is the following taken from the same documentation -
As seen above, the content indeed is dynamic and can be changed depending on the context of the admin-panel.
However, the definition of <cms:field>, per se, is set in stone to the front-end context and will not react to the dynamics of the admin-panel.
A little example will make this point clearer -
Suppose, for some reason, you wish to add a particular field in the edit screen of the admin-panel only when the page has been saved at least once (i.e. is not new).
Placing the required check as follows will not work as you might expect -
The reason being that <cms:if k_page_id ne '-1'> (a new page has an id of -1) was executed on the front-end (while the 'visit as super-admin' part of making changes to a template was done).
A page on the front-end will never be new so the check will succeed and the <cms:field> definition will be executed causing the field to be added.
In the edit screen of the admin-panel, the check will never be made again and the field will always be present in the form.
Now, one can argue that, since the contents of the field will nevertheless be executed every time the edit screen is accessed, we could place the check within the contents e.g. as follows
Yes, that would cause the contents to appear only for a saved page but the field itself (with its label etc.) will continue to appear in new pages (and you might have to fall back on CSS to hide it).
Anyway, if you happen to run into a use-case, as I did recently, where dynamically controlling the very presence of fields in the admin-panel is a requirement, following is a little addon that I coded to help with the situation.
Please copy the full code given at the end of this post to your 'couch/addons/kfunctions.php' file (if a file by this name does not exist, please rename the 'kfunctions.example.php' found there to 'kfunctions.php').
With this code incorporated, you can use a tag named <cms:jit_fields> (that is 'Just In Time' fields) within your <cms:config_form_view> block.
Now, instead of directly within your <cms:config_form_view> block, you should define the <cms:field> tags within the <cms:jit_fields> block e.g. as follows -
The <cms:jit_fields> tag block serves to provide a dynamic context to all enclosed <cms:field> tags and so the following amendment of the failed code we tried above will work as expected
Hope this helps.
CODE:
As most of Couch's users would know, tag <cms:field> (used from within <cms:config_form_view> tag block) offers a powerful way to customize the looks of fields as they appear in the admin-panel while editing a page (viewtopic.php?f=5&t=10241).
As mentioned in the documentation post linked above, the content enclosed within the <cms:field> tag-pair is dynamic i.e. although it is defined on the front-end, it executes in the context of the admin-panel.
An example of which is the following taken from the same documentation -
- Code: Select all
<cms:field 'my_message' >
<cms:repeat '3' startcount='1'>
<h<cms:show k_count />>Hello!</h<cms:show k_count />>
</cms:repeat>
</cms:field>
As seen above, the content indeed is dynamic and can be changed depending on the context of the admin-panel.
However, the definition of <cms:field>, per se, is set in stone to the front-end context and will not react to the dynamics of the admin-panel.
A little example will make this point clearer -
Suppose, for some reason, you wish to add a particular field in the edit screen of the admin-panel only when the page has been saved at least once (i.e. is not new).
Placing the required check as follows will not work as you might expect -
- Code: Select all
<cms:if k_page_id ne '-1'>
<cms:field 'my_message' >
<cms:repeat '3' startcount='1'>
<h<cms:show k_count />>Hello!</h<cms:show k_count />>
</cms:repeat>
</cms:field>
</cms:if>
The reason being that <cms:if k_page_id ne '-1'> (a new page has an id of -1) was executed on the front-end (while the 'visit as super-admin' part of making changes to a template was done).
A page on the front-end will never be new so the check will succeed and the <cms:field> definition will be executed causing the field to be added.
In the edit screen of the admin-panel, the check will never be made again and the field will always be present in the form.
Now, one can argue that, since the contents of the field will nevertheless be executed every time the edit screen is accessed, we could place the check within the contents e.g. as follows
- Code: Select all
<cms:field 'my_message' >
<cms:if k_page_id ne '-1'>
<cms:repeat '3' startcount='1'>
<h<cms:show k_count />>Hello!</h<cms:show k_count />>
</cms:repeat>
</cms:if>
</cms:field>
Yes, that would cause the contents to appear only for a saved page but the field itself (with its label etc.) will continue to appear in new pages (and you might have to fall back on CSS to hide it).
Anyway, if you happen to run into a use-case, as I did recently, where dynamically controlling the very presence of fields in the admin-panel is a requirement, following is a little addon that I coded to help with the situation.
Please copy the full code given at the end of this post to your 'couch/addons/kfunctions.php' file (if a file by this name does not exist, please rename the 'kfunctions.example.php' found there to 'kfunctions.php').
With this code incorporated, you can use a tag named <cms:jit_fields> (that is 'Just In Time' fields) within your <cms:config_form_view> block.
Now, instead of directly within your <cms:config_form_view> block, you should define the <cms:field> tags within the <cms:jit_fields> block e.g. as follows -
- Code: Select all
<cms:config_form_view>
<cms:jit_fields>
.. place <cms:field> tags here
</cms:jit_fields>
</cms:config_form_view>
The <cms:jit_fields> tag block serves to provide a dynamic context to all enclosed <cms:field> tags and so the following amendment of the failed code we tried above will work as expected
- Code: Select all
<cms:config_form_view>
<cms:jit_fields>
<cms:if k_page_id ne '-1'>
<cms:field 'my_message' >
<cms:repeat '3' startcount='1'>
<h<cms:show k_count />>Hello!</h<cms:show k_count />>
</cms:repeat>
</cms:field>
</cms:if>
</cms:jit_fields>
</cms:config_form_view>
Hope this helps.
CODE:
- Code: Select all
// JIT fields
{
// Tag <cms:jit_fields>
$FUNCS->register_tag( 'jit_fields', function($params, $node){
global $CTX, $FUNCS, $AUTH;
if( $AUTH->user->access_level < K_ACCESS_LEVEL_SUPER_ADMIN ){ return; }
// get the 'config' object supplied by 'cms:config_form_view' tag
$arr_config = &$CTX->get_object( '__config', 'config_form_view' );
if( !is_array($arr_config) ){ return; }
if( count($node->children) ){
$content = $node->children;
}
$arr_config['jit_fields'] = $content;
});
if( defined('K_ADMIN') ){
$FUNCS->add_event_listener( 'alter_pages_form_default_fields', function(&$arr_default_fields, &$obj){
global $PAGE, $FUNCS, $CTX, $DB;
if( !(is_array($obj->arr_config) && array_key_exists('jit_fields', $obj->arr_config) && is_array($obj->arr_config['jit_fields'])) ){ return; }
// replace cms:config_form_view tag
$arr_config = array( 'arr_fields'=>array(), 'js'=>'', 'css'=>'', 'html'=>'', 'params'=>'' );
$listener_config_form_view = function($tag_name, &$params, &$node, &$html) use(&$arr_config){
global $FUNCS, $CTX;
$CTX->set_object( '__config', $arr_config );
// invoke child tags
foreach( $node->children as $child ){
$child->get_HTML();
}
return 1; // skip original tag code
};
$FUNCS->add_event_listener( 'alter_tag_config_form_view_execute', $listener_config_form_view );
$html = '<cms:config_form_view></cms:config_form_view>';
$parser = new KParser( $html );
$dom = &$parser->get_DOM();
$dom->children[1]->children = $obj->arr_config['jit_fields'];
foreach( $dom->children as $child ){
$child->get_HTML();
}
$FUNCS->remove_event_listener( 'alter_tag_config_form_view_execute', $listener_config_form_view );
// set fields if any
if( is_array($arr_config['arr_fields']) && count($arr_config['arr_fields']) ){
if( !is_array($obj->arr_config) ){ $obj->arr_config = array(); }
if( !is_array($obj->arr_config['arr_fields']) ){ $obj->arr_config['arr_fields'] = array(); }
foreach( $arr_config['arr_fields'] as $k=>$v ){
$obj->arr_config['arr_fields'][$k] = $v;
}
}
});
}
}// end JIT fields