[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