====== how to add top-level menu items to the staff client ====== One day this may be scripted, or the framework might be able to handle this dynamically, but for now... ===== constants.js ===== Edit **ILS/Open-ILS/xul/staff_client/chrome/content/main/constants.js** and add the path for your interface to the urls object. If this is a remote interface, don't include the domain if you can help it. Use something like '/xul/server/admin/backdoor.xul' or '/opac/en-US/skin/default/xml/index.xml'. I plan to do text mangling with sed on release builds and change 'xul/server' to some variation of 'xul/BUILD_STAMP/server' outside of CVS to support versioning, so be aware of that. For this example, let's say you add **'XUL_LOCATION_EDITOR' : '/xul/server/admin/location.xul'** to urls. var urls = { 'opac' : '/opac/en-US/skin/default/xml/advanced.xml', 'XUL_DEBUG_CONSOLE' : 'chrome://global/content/console.xul', 'XUL_LOCATION_EDITOR' : '/xul/server/admin/location.xul', } ===== menu_frame_menus.xul ===== Now edit **ILS/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul** (note: this may move back to ILS/Open-ILS/xul/staff_client/server/main/menu_frame_menus.xul once I migrate from XUL interfaces that require chrome, such as wizards). Within the **** element, let's add something like ****. If you'd like to create a shortcut key, add an attribute like key="location_editor_key", and then in the element, add something like . Now, find the **** element you're interested in. It should have a **** element as it's child. Within the , add something like **** We'll let Adam, our intern, handle localization. :D ===== menu.js ===== Lastly, edit **ILS/Open-ILS/xul/staff_client/chrome/content/main/menu.js**. This is the controller for our menus. In main.menu.prototype, in 'init', in **cmd_map** add something like this: 'cmd_edit_location' : [ ['oncommand'], function() { obj.set_tab( obj.url_prefix(urls.XUL_LOCATION_EDITOR) + '?ses='+escape(session), { 'tab_name' : 'Location Editor' }, { 'extra' : too_big_for_url_param, 'on_edit' : function(loc){ alert('Location is now ' + loc); } } ); } ], This applies a command event listener to the corresponding element. Both and are observing and broadcasting to that . If you were to disable that element (say with obj.controller.view.cmd_edit_location.disabled = true), all the observers would disable as well--the shortcut key would cease to work and the menu option would be greyed out. "obj" refers to that instance of the 'main.menu' object. set_tab loads the specified interface in the current tab. You could use new_tab, or even something like window.open. The 3rd parameter for new_tab/set_tab is an alternate way to pass data. It will push the parameter into the loaded interface's window scope as xulG. Generally, it's better to use URL query params as that makes your interface more portable outside the staff client environment, but you'll need to use xulG if you want to push in functions for use as callbacks. That's it. :)