Last night there was a discussion in #drupal regarding the help system, and the need for an overhaul therein. Dries asked me to send a note to this list with what was discussed and the thoughts on where to go with it. This is a developer, documenter, and translator issue, so input from all three parties is welcome. Problems with the current help system, vis, hook_help() ----------------------------------------------------------------------- - Huge blocks o' text in the source code file. - Because the strings are large, translation of help files via PO is slooooow. - Synchronization with the online handbook is tedious and difficult, which means it sometimes doesn't get done. Proposed solution ----------------------- Replace hook_help() with a database-based help lookup system that incorporates translations directly in the database. The database table would look something like this: help ( hid, module, key, locale, helptext ); The key would be a short textual string that identifies the help text in question, serving the same function as $section in hook_help(). (Possibly with the same naming scheme, possibly not.) Then, hook_help() would be replaced with a function help_get(): /* Example function, missing lots of necessary error checks */ function help_get($module, $key, $locale='en') { $help = db_fetch_object(db_query("SELECT helptext FROM {help} WHERE module='%s' AND key='%s' AND locale='%s'", $module, $key, $locale)); return $help->helptext; } What gets returned, then, is an already-localized string, ready for printing/theming/whatevering. The help lookup is always a single database hit, no slow textual substr() matching needed. That also means that PO files are much smaller, and module source code doesn't have to have giant masses of text in it. Issues and solutions -------------------------- Links: I'd say the solution here is to have links flagged in the database for easy conversion by help_get() before they're returned. For example: ... Go to the <link url="admin/modules">modules page</link> to enable... help_get() would then, before returning the string, check for <link> tags, extract the data, and replace it with the output from an l() call. I'm not sure of the efficiency of the syntax above, but something along those lines should be easiest. (Good place for a regex?) Data loading: Of course, there needs to be some way to get helptext into the database in the first place. That would require an auxiliary file along with the .module file, say .help. See below for comments on the format of .help. When the module is enabled on admin/modules, the .help file is parsed into the help table once. When the module is disabled, the help table is cleared of any records for that module to avoid cruft. While this does make enabling and disabling a module a bit slower, that's not done often enough that it should make any practical difference. We would need to then make sure that the module's name and short description are available in the module itself, as those are needed on the admin/modules page. The simplest solution would be to have a hook_module_info() function, which returns an array of the form: array('name' => 'node', 'description' => 'Allows content to be submitted to the site and displayed on pages.'); Those text strings are small enough that they can be handled by the current translation system. admin/modules would then include every .module file (as now) and then call the _module_info() hooks to get the data to display. Data format, data entry, handbook sync -------------------------------------------------- These all dovetail together, so I'm going to discuss them all at once. - The Docs team wants to be able to write help text for core and contrib modules without futzing about with MySQL dumps or some other obscure format. A web-frontend is preferred. - Developers need to be able to enter their own help text without going through the drupal.org docs team. That's especially important for custom modules that need help text but don't end up on Drupal.org for whatever reason. (Custom for a client, commercial modules, etc.) - The Translation people don't want to have to deal with obscure file formats either. - Keeping the text in the online handbook in sync with the in-system text in the actual module should be sufficiently trivial that no one thinks to not do so. That's a tall order, and a problem that hasn't been solved yet. :-) My recommendation for the intermediary help files would be an XML format, one reasonably easy to import/export from the online handbook and reasonably easy to hand-edit. The Docs and Translations teams could then edit the text in the online handbook and export it to the necessary XML files, as can the translation team, while developers can write the XML file directly via their XML editing method of choice. The file needn't be complicated. For instance: <drupal:help module='node' locale='en'> <drupal:entry key="description">Some <b>HTML</b> here.</drupal:entry> <drupal:entry key="stuff">Some other text.</drupal:entry> </drupal:help> When the module is enabled, the XML file is parsed into the help table, as mentioned. It's a one-time event, so performance is a non-issue. There would be a separate file for each locale. So the node module, for instance, would have: node.module node.mysql node.help node.es.help node.de.help ... As now, English would be the default language. Besides being easier to edit, using XML files instead of an SQL dump keeps the help text database-independent. Otherwise, we'd need separate mysql and pgsql files for each locale. Other thoughts ------------------- I have not worked with the current help system that extensively, so I'm not sure how it handles context-sensitive help. By that I mean "What's this?" type help, or other "what do I do on this page" help text. One advantage to this method is that keys reserved for the main help system could be pre-defined, while a module author would be free to add additional help keys for his module. So on the foobar/4/edit page, the module author could write: $output .= theme('help_link', 'foobar', 'edit'); Which would return a formatted link to context-appropriate help, such as: <div class="help-link"><a href="help/foobar/edit">Help on this page</a></div> help/foobar/edit then would trigger the callback for 'help', which would dutifully display the theme('help') for module 'foobar', key 'edit'. Both of those could then be re-themed to allow pop-up help windows, javascript overLib (http://www.bosrup.com/web/overlib/) calls, or whatever else a theme-author felt like doing. Some more thought here is definitely needed, but I'd love to see more non-admin-user context sensitive help in Drupal. Conclusion -------------- I'm sure at least some of the above is insanely stupid, so please point out where gently. :-) Dries said he suspects this would be a 4.8-targeted improvement, which I think is likely given the amount of legacy code and how close we are to 4.7's release. Devs, Docs, and Trans, your input please! My thanks to Dries, Amazon, webcheck, killes, and everyone else who was in the channel last night for this discussion. *dons flame retardant suit* -- Larry Garfield AIM: LOLG42 larry@garfieldtech.com ICQ: 6817012 "If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it." -- Thomas Jefferson