Adding custom page and list it in the NavMenu

At first I want to say, that Xataface is a great framework. 4 lines of php-code and listing the tables in the conf.ini file and the back-end is finished. Also the configuring is nice, to rename the labels ect.
It would be nice, if it somehow could inherit the relationships of the database to the config, but this is a nice-to-have (but a very nice one ^^).
------- My approach and stuff I found out -------
I'm writing this in that form, so you can follow the thoughts of a newbie in Xataface. Maybe it helps to develop or enhance tutorials for Xataface users.
After playing a bit with Xataface and its instantly generated back-end I thought, "Ok, back-end: nice, but how to make the front-end for the user?"
It started with the small question how to add a new page, with no direct link to a table. That's because I need very customized composition of various data of the DB.
One short attempt was to create a table in the conf.ini file and somehow to override the functionality by a delegate class, to create a very own content. But it failed because of the Xataface structure, because somewhere deep within it wants to query the table which doesn't exist ...
One way is using actions. I added an action and it worked, but there was no button to this site/this action. And because it's an "stand-alone" action - unlike edit, list or delete - it must be at the level of the Navigation Menu. I found the solution using the Dataface_Application_Menu.html to create a custom menu. But I don't like it, because it's separated from the NavMenu and has by default no style. Furthermore I want to use my custom pages in combination with the NavMenu, so they have to be together.
So the search for adding elements to the NavMenu began. Somewhere I read to add a action to the NavMenu you have to override the Dataface_NavMenu.html template. But I thought "Smarty templates? Then I must find the place where the vars/context are assigned to the template and found NavMenu.php. I tried to add values to $_tables, but nothing changed. I added an echo to look if it is even called, but nothing was shown. I placed an exit on the beginning of each function and the NavMenu was still showed. I deleted the half of the file so it should produce an error, but it didn't happen.
I even called the Dataface_NavMenu.html template directly with df_display() in my action, with the array("asdf" => "asdf", "fdsa" => "fdsa") as context and still the normal NavMenu with all tables showed up.
Very strange ...
So I traced the df_display() over the dataface-public-api.php to the function display() in SkinTool.php. I wanted to know what there the $context really contains and printed it. But there wasn't the tables listed ... But I saw also the $ENV in the file which fits the {foreach from=$ENV.APPLICATION._tables item=label key=table} stuff. So I printed $this->ENV and there were the tables listed, along with tons of other stuff. ^^
I added a value to $this->ENV['APPLICATION']['_tables'] and jackpot! The NavMenu had one entry more.
But how to add my action now? In the SkinTool.php for sure not. Then a brilliant idea came up - write it in the config file! It will be sure read into the $ENV stuff, I thought.
After checking, I was right. So I can access it in the Template, only with a new entry in the config file.
I copied the foreach loop and modified it and it worked, but there was one little problem:
The first table was always marked as selected, because of the default table setting. So I had to change the if-part
{if $ENV.table==$table}class="selected"{/if}>
Oh, while writing this I found a better (and cleaner) method to solve this.
Hurray, it works!
Drawbacks:
-- The actions are always listed before the tables.
-- The automatism when the horizontal menu is shown is only affected by the count of the tables, but via [_prefs] horizontal_tables_menu = 0 or 1 this shouldn't be a too big problem.
What do you think about my solution? Is it clean enough? Could I improve some parts?
------- Installing Instructions -------
Put the modified Dataface_NavMenu.html Template into yourapplicationpath/templates (see the whole file at the end of this post)
That overrides the template of Xataface.
Add to conf.ini
------- Dataface_NavMenu.html - the whole file -------
PS: Please excuse me if there are grammar failures or strange expressions, but English isn't my mother tongue. ^^
It would be nice, if it somehow could inherit the relationships of the database to the config, but this is a nice-to-have (but a very nice one ^^).
------- My approach and stuff I found out -------
I'm writing this in that form, so you can follow the thoughts of a newbie in Xataface. Maybe it helps to develop or enhance tutorials for Xataface users.
After playing a bit with Xataface and its instantly generated back-end I thought, "Ok, back-end: nice, but how to make the front-end for the user?"
It started with the small question how to add a new page, with no direct link to a table. That's because I need very customized composition of various data of the DB.
One short attempt was to create a table in the conf.ini file and somehow to override the functionality by a delegate class, to create a very own content. But it failed because of the Xataface structure, because somewhere deep within it wants to query the table which doesn't exist ...
One way is using actions. I added an action and it worked, but there was no button to this site/this action. And because it's an "stand-alone" action - unlike edit, list or delete - it must be at the level of the Navigation Menu. I found the solution using the Dataface_Application_Menu.html to create a custom menu. But I don't like it, because it's separated from the NavMenu and has by default no style. Furthermore I want to use my custom pages in combination with the NavMenu, so they have to be together.
So the search for adding elements to the NavMenu began. Somewhere I read to add a action to the NavMenu you have to override the Dataface_NavMenu.html template. But I thought "Smarty templates? Then I must find the place where the vars/context are assigned to the template and found NavMenu.php. I tried to add values to $_tables, but nothing changed. I added an echo to look if it is even called, but nothing was shown. I placed an exit on the beginning of each function and the NavMenu was still showed. I deleted the half of the file so it should produce an error, but it didn't happen.
I even called the Dataface_NavMenu.html template directly with df_display() in my action, with the array("asdf" => "asdf", "fdsa" => "fdsa") as context and still the normal NavMenu with all tables showed up.
Very strange ...
So I traced the df_display() over the dataface-public-api.php to the function display() in SkinTool.php. I wanted to know what there the $context really contains and printed it. But there wasn't the tables listed ... But I saw also the $ENV in the file which fits the {foreach from=$ENV.APPLICATION._tables item=label key=table} stuff. So I printed $this->ENV and there were the tables listed, along with tons of other stuff. ^^
I added a value to $this->ENV['APPLICATION']['_tables'] and jackpot! The NavMenu had one entry more.
But how to add my action now? In the SkinTool.php for sure not. Then a brilliant idea came up - write it in the config file! It will be sure read into the $ENV stuff, I thought.
- Code: Select all
[_actions_add_to_navmenu]
actionname = "Shown Name in the NavMenu"
After checking, I was right. So I can access it in the Template, only with a new entry in the config file.
I copied the foreach loop and modified it and it worked, but there was one little problem:
The first table was always marked as selected, because of the default table setting. So I had to change the if-part
{if $ENV.table==$table}class="selected"{/if}>
Oh, while writing this I found a better (and cleaner) method to solve this.

- Code: Select all
pseudo code:
{action_selected = false} -- in smarty assign new var
foreach(_actions_add_to_navmenu )
{if $ENV.action == run_action} class="selected" {action_selected = true} {/if} -- if action in the ENV (= current action) == current shown action -> show as selected and save it to the var
{if !$action_selected && $ENV.table == $table} -- when action is shown selected, don't show any table as selected
Hurray, it works!
Drawbacks:
-- The actions are always listed before the tables.
-- The automatism when the horizontal menu is shown is only affected by the count of the tables, but via [_prefs] horizontal_tables_menu = 0 or 1 this shouldn't be a too big problem.
- Code: Select all
see Application.php line 364:
if ( count($this->_tables) <= 10 ){
$this->prefs['horizontal_tables_menu'] = 1;
}
What do you think about my solution? Is it clean enough? Could I improve some parts?
------- Installing Instructions -------
Put the modified Dataface_NavMenu.html Template into yourapplicationpath/templates (see the whole file at the end of this post)
That overrides the template of Xataface.
Add to conf.ini
- Code: Select all
[_actions_add_to_navmenu]
actionname1 = "Shown Name1 in the NavMenu"
actionname2 = "Shown Name2 in the NavMenu"
------- Dataface_NavMenu.html - the whole file -------
- Code: Select all
{*-------------------------------------------------------------------------------
* Dataface Web Application Framework
* Copyright (C) 2005-2006 Steve Hannah (shannah@sfu.ca)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Modified by SilverCorvus 2011
* Description of the modification:
* You can add actions like the tables in the conf.ini to the
* new section [_actions_add_to_navmenu] and those actions will be listed in this
* NavMenu before the tables.
*-------------------------------------------------------------------------------
*}
{if $ENV.prefs.horizontal_tables_menu}
<ul id="table_selection_tabs">
{assign var=action_selected value=false}
{block name="tables_menu_head"}
{define_slot name="tables_menu_options"}
{foreach from=$ENV.APPLICATION._actions_add_to_navmenu item=label key=action}
<li {if $ENV.action==$action}{assign var=action_selected value=true}class="selected"{/if}><a href="{$ENV.DATAFACE_SITE_HREF}?-action={$action}"
accesskey="accesskeys-navigation"
class="action-selection-tab {if $ENV.action==$action}selected{/if}"
title="{$label}"
id="TableLink_{$action}">
{$label}
</a></li>
{/foreach}
{foreach from=$ENV.APPLICATION._tables item=label key=table}
<li {if !$action_selected && $ENV.table == $table}class="selected"{/if}><a href="{$ENV.DATAFACE_SITE_HREF}?-table={$table}"
accesskey="accesskeys-navigation"
class="table-selection-tab {if !$action_selected && $ENV.table == $table}selected{/if}"
title="{$label}"
id="TableLink_{$table}">
{$label}
</a></li>
{/foreach}
{/define_slot}
{block name="tables_menu_tail"}
</ul>
{else}
<div class="portlet" id="portlet-navigation-tree">
<div>
<h5>Navigation</h5>
<div class="portletBody">
{assign var=action_selected value=false}
{block name="tables_menu_head"}
{foreach from=$ENV.APPLICATION._actions_add_to_navmenu item=label key=action}
{define_slot name="tables_menu_options"}
<div class="portletContent">
<a href="{$ENV.DATAFACE_SITE_HREF}?-action={$action}"
accesskey="accesskeys-navigation"
class="navItem {if $ENV.action==$action}{assign var=action_selected value=true}currentNavItem{/if}"
title="{$label}"
id="ActionLink_{$action}">
<img
src="{$ENV.DATAFACE_URL}/images/folder_icon.gif" alt="" class="navIconRoot" title="Plone Site" />
<span class="navItemText">
{$label}
</span>
</a>
</div>
{/define_slot}
{/foreach}
{foreach from=$ENV.APPLICATION._tables item=label key=table}
{define_slot name="tables_menu_options"}
<div class="portletContent">
<a href="{$ENV.DATAFACE_SITE_HREF}?-table={$table}"
accesskey="accesskeys-navigation"
class="navItem {if !$action_selected && $ENV.table == $table}currentNavItem{/if}"
title="{$label}"
id="TableLink_{$table}">
<img
src="{$ENV.DATAFACE_URL}/images/folder_icon.gif" alt="" class="navIconRoot" title="Plone Site" />
<span class="navItemText">
{$label}
</span>
</a>
</div>
{/define_slot}
{/foreach}
{block name="tables_menu_tail"}
</div>
</div>
</div>
{/if}
PS: Please excuse me if there are grammar failures or strange expressions, but English isn't my mother tongue. ^^