[drupal-devel] Help system redesign
Larry Garfield
larry at garfieldtech.com
Sun Sep 25 04:00:03 UTC 2005
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 at 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
More information about the drupal-devel
mailing list