Creating admin menu items dynamically in joomla
Another day playing around with joomla, and another shortcoming to fix :)
This time it comes in the form of the administration(backend) menu. To add items/subitems to this menu, people have to write the menu items in an xml file accompanying their components/extension/plugin/whatever. When the extension is installed, joomla "generates" the menu items and "stores" them in the DB. Effectively, the real/tangible menu is rendered by reading the DB.
This has several implications:
- The menu is not scriptable
- The menu is not dynamic; changing the XML file after installation, won't update the menu
- Removal of items is not scriptable; joomla takes care of removing any items when you uninstall the extension.
I've got this system which relies on the ability to modify menu items on the fly, but through code. Simply put, I need to have functionality where I can create a volatile menu item (ie, it gets removed at the end of session).
To do so, I've got a couple of prospective hacks:
- Override the joomla global database instance so that I can make it return fake menu items. Th开发者_运维问答is is possible since the database object is stored in a public property of JFactory class:
JFactory::$database=new MyFakeJDatabase(JFactory::$database);
- Intercept the menu code (html) before being output and mess it up according to my needs. This is not template-friendly in that the end result would be injecting html, which might not be what the template was designed for.
- Create menu items through javascript. This suffers issues with the template AND the javascript that toggles submenus.
- Create menu items in the DB whenever I need them and somehow "tag" my items so that I remove them the next time (or end of session). This sounds like it would work like a charm. Since I can buffer menu items, I could possibly create my menu items in one whole SQL statement. Than I could use another SQL to remove the tagged menu items. 2 SQL statements might not be much of a load on the server.
What do you think?
Edit: I've checked joomla/administrator/modules/mod_menu/helper.php
to see if I could find a way to inject my stuff, wishing that maybe joomla used a global variable or something, but to no use - the menu items are creating directly by reading the db and rendering as well.
FYI I've searched a while on Google, to no use.
Interesting. I have worked with Joomla for many years, writing all kinds of extensions for various purposes, including integrating external systems. It has been my experience to approach these types of situations by looking at the basic needs of code execution. And I always seem to start off asking: is it UI driven or system-driven?
First, consider if the code will execute according to user-generated system events. There are a whole bunch of 'em and you can even trigger your own. If this is a requirement, then the solution will need to incorporate a plugin, attached to events.
However, for any kind of dynamic UI content, you will need a module. Modules are all about displaying content. These guys are designed for the user experience. So, consider how access to the UI content will be managed. Which users will comprise the "audience" of this content? This is controlled by user groups and access levels. At some point in your code, preferably early, you will have to check the user's rights and then modify your code execution in response. Thankfully, I find that someone has already done a lot of the work for me. How?
Find an extension that performs the things that your code needs to do, or as close as one might match up. The entire CMS is built with extensions running atop the Joomla! Framework and there are thousands of extensions available for download. Once you've found it, clone the thing. Then edit it so that it does what you need it to do, plus what it did before (if that is a requirement). Install your updated clone, unpublish the original and publish yours. Saves a lot of time.
Looking at your requirements, the code only executes as long as there is a session. I would start with with a 'user' type plugin. When the user triggers a login event the plugin can add the dynamic menu records to a session variable as an array of db records. When the user triggers a logout or the session times-out, the records will go away by themselves. Then I would simply clone "mod_menu" and have read in any records that it finds in the users session. I use this session variable technique all the time, especially when implementing analytic data gathering stuff.
Anyway, I don't post often; but I sure hope this helps. I would love to see this type pf functionality myself. Just haven't the time to code it.
Good luck!
chozyn
The "correct" way would be to write a module which overrides the core menu module to achieve the old functionality with the added feature of dynamic menus from whatever source you have. Not particularly a nice way to go, but that is Joomla's way. Thanks to @ircmaxell to point this method out.
No hack seems satifactory, safe or maintainable enough to achieve this.
I've aborted the project and instead am putting buttons in the main dashboard through JS.
It's highly inconvenient to end users (they still miss sub-items). But what the hell...it's Joomla's fault.
Oh and for the record, I needed to add my own custom "pages" similar to admin components. Guess what? That failed as well, so it's another hack.
Hope that by version 1.7, they[joomla] trash the initial codebase altogether.
精彩评论