Netzke demo update: actions, menus and authentication
UPDATE (2009-09-07): This tutorial is outdated with the release of netzke-basepack v0.5.0. Please, refer to the project's wiki for updated articles. After releasing the next version of the Netzke gems, I also updated the live demo (http://netzke-demo.writelesscode.com/). Along with some minor fixes (like preventing the user to trigger sorting on virtual columns in the GridPanel), and providing a FormPanel-based widget in the “General” pane of a widget’s configuration window, the BasicApp demo has been updated in a way that it no longer requires the user to log in. However the access to the User management is only granted to an authenticated user. Further I describe those simple steps that were needed to achieve that.
First of all, we need to define the actions (where “action” is a reflection of Ext.Action) available in our BasicAppDemo widget:
def actions
{
:clerks => {:text => "Clerks", :fn => "loadWidgetByAction"},
:bosses => {:text => "Bosses", :fn => "loadWidgetByAction"},
# Only allow administrative actions when user is logged in
:users => {:text => "Users", :fn => "loadWidgetByAction",
:disabled => Netzke::Base.user.nil?}
}
end
The parameter “fn” specifying the action’s main event handler is optional. If it’s omitted, clicking on a menu item bound to a specific action will call a property function with the same name as the action’s. However, in this case we want all actions to refer to the same handler function which is found in BasicApp widget: loadWidgetByAction. This function receives the reference to the action in charge, and by default loads the widget with the same name as that of the action.
Notice that the action “users” has an additional option “disabled” set to true when there’s no user logged in. This “disabled” option is a direct map to Ext.Action’s “disabled” config option.
Now we only need to define the menus:
def menu
[{
:text => "Go to",
:menu => %w{ clerks bosses users }
}]
end
As of netzke-core v0.2.9, the menu is specified as an array of either action names, or hashes that represent a submenu. To make this more clear, here’s how we would put 3 menu items - Clerks, Bosses and Users - in the top-level menu:
def menu
%w{ clerks bosses users }
end
And here’s how to put Users in a separate sub-menu:
def menu
[{
:text => "Go to",
:menu => %w{ clerks bosses }
},{
:text => "Administration",
:menu => %w{ users }
}]
end
The same way as defining menus, you can define bottom-bar and top-bar of a widget.
So, now you can’t click the menu when you’re not logged in - it’s disabled. But if you’ve been attentive enough while playing with the demo, you’d have noticed the way how the browser history is managed: via modifying the URL. When you go to Clerks view, it gets #clerks appended to it, when you go to Bosses - you see #bosses. What would stop us to edit the URL by hand and to put #users instead and get the User view even without being authenticated? We need to prevent this, and we do that by overriding BasicApp’s interface_app_get_widget method, which gets AJAX-fully called when the user clicks from one widget to the other:
#
# Prevent unauthorized access to Users
#
def interface_app_get_widget(params)
widget = params[:widget].underscore
if Netzke::Base.user.nil? && widget == "users"
flash :error => "You do not have access to users"
{:success => false, :flash => @flash}.to_js
else
super
end
end
I hope, the code is self-explanatory, at least until that level of details that I mean to address in this post.
