Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.869 diff -u -p -r1.869 common.inc --- includes/common.inc 18 Feb 2009 15:07:26 -0000 1.869 +++ includes/common.inc 21 Feb 2009 19:22:46 -0000 @@ -3512,6 +3512,21 @@ function element_children(&$elements, $s } /** + * Determine whether help topics for a given module exist. + * + * @param $module + * The module name. + * @return + * TRUE if the module is enabled and provides help topics, and the help module is enabled. + */ +function help_exists($module) { + if (drupal_function_exists('help_get_topics') && module_exists($module)) { + $topics = help_get_topics(); + return isset($topics[$module]); + } +} + +/** * Provide theme registration for themes across .inc files. */ function drupal_common_theme() { @@ -3583,8 +3598,8 @@ function drupal_common_theme() { 'list' => array( 'arguments' => array('elements' => NULL), ), - 'more_help_link' => array( - 'arguments' => array('url' => NULL), + 'help_link' => array( + 'arguments' => array('module' => NULL, 'topic' => NULL, 'title' => NULL, 'popup' => NULL, 'attributes' => NULL), ), 'xml_icon' => array( 'arguments' => array('url' => NULL), Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.312 diff -u -p -r1.312 menu.inc --- includes/menu.inc 9 Feb 2009 16:27:35 -0000 1.312 +++ includes/menu.inc 21 Feb 2009 19:22:46 -0000 @@ -1299,10 +1299,9 @@ function menu_get_active_help() { if ($help = $function($router_path, $arg)) { $output .= $help . "\n"; } - // Add "more help" link on admin pages if the module provides a - // standalone help page. - if ($arg[0] == "admin" && module_exists('help') && $function('admin/help#' . $arg[2], $empty_arg) && $help) { - $output .= theme("more_help_link", url('admin/help/' . $arg[2])); + // Add "more help" link on admin pages if the module provides help topics. + if ($arg[0] == "admin" && help_exists($arg[2]) && $help) { + $output .= theme("help_link", $arg[2]); } } return $output; Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.469 diff -u -p -r1.469 theme.inc --- includes/theme.inc 5 Feb 2009 03:42:56 -0000 1.469 +++ includes/theme.inc 21 Feb 2009 19:22:47 -0000 @@ -1590,13 +1590,6 @@ function theme_list($elements) { } /** - * Returns code that emits the 'more help'-link. - */ -function theme_more_help_link($url) { - return '
The Help system is a pluggable system that provides help facilities for Drupal and its modules. Although the help does not provide general help by itself, it provides a powerful and easy framework that modules may use to provide their own help. +
+ ++Modules utilizing Help should create a 'help' subdirectory inside their +module's directory. Place the file MODULENAME.help in this subdirectory, formatted +similar to the following example: +
++[buses] +title = "How buses are tied into the system" +file = buses + +[TOPIC_ID] +title = "Title of topic". +file = filename of topic, without the .html extension. +weight = How important the topic is on the index page. +parent = The optional topic parent to use in the breadcrumb, + either topic or module%topic. ++ +
+All topics are addressed by the module providing the topic, and by the topic +id. To embed links, use the following format: +
+
+$output .= theme('help_topic', $module, $topic);
+
+
+Inside your help file, link to other topics using the format <a href="[topic:module/topic]">. This +format will ensure the popup status remains consistent when switching between links.
+ +Use <img src="[path]example.jpg" /> to reference items +within the help directory, such as images you wish to embed within the help text.
+ +Use <a href="[base_url]admin/settings/site-configuration" target="_blank"> to reference any normal path in the site.
+ +If the search module is enabled, the contents of help system will be indexed on cron. If you enable new modules and wish to immediately index its help text, visit the "Administration -> Reports -> Status report" and click the "Run cron manually" link.
+ +Example: Don't click this!
+ +See: Help file format
Index: modules/help/help/help-file.html =================================================================== RCS file: modules/help/help/help-file.html diff -N modules/help/help/help-file.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/help/help/help-file.html 21 Feb 2009 19:22:47 -0000 @@ -0,0 +1,54 @@ + +The help configuration file is in simple .ini file format, divided into sections for each help file, plus an optional section for global settings that might be inherited for each help file. + +The first line of an help ini file should be ;$Id $ which will be a comment providing the CVS identifier for the file. The ; indicates a comment character. Anything after the ; will be ignored. + +Global settings may be put into a section named [help settings] -- this means that this name is reserved and it cannot be a help file in any module. The following settings may be set in this section: ++[using-help] +title = "Using help" +weight = -10 + +[translation] +title = Translating help + +[help-file] +title = Help file format +line break = TRUE +\ No newline at end of file Index: modules/help/help-popup.css =================================================================== RCS file: modules/help/help-popup.css diff -N modules/help/help-popup.css --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/help/help-popup.css 21 Feb 2009 19:22:47 -0000 @@ -0,0 +1,152 @@ +/* $Id$ */ + +body { + background: #edf5fa; + color: #494949; + font: 12px/170% Verdana, sans-serif; + margin: 0; + padding: 0; +} + +input { + color: #494949; + font: 12px/100% Verdana, sans-serif; +} + +textarea, select { + color: #494949; + font: 12px/160% Verdana, sans-serif; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: normal; + font-family: Helvetica, Arial, sans-serif; + margin: 0; + padding: 0; +} + +h1 { + font-size: 170%; +} + +h2 { + font-size: 160%; + line-height: 130%; +} + +h3 { + font-size: 140%; +} + +h4 { + font-size: 130%; +} + +h5 { + font-size: 120%; +} + +h6 { + font-size: 110%; +} + +ul, ol, .item-list ul, .item-list ol, quote, code, fieldset { + margin: .5em 0; +} + +p { + margin: 0.6em 0 1.2em; + padding: 0; +} + +a:link, a:visited { + color: #027AC6; + text-decoration: none; +} + +a:hover { + color: #0062A0; + text-decoration: underline; +} + +a:active, a.active { + color: #5895be; +} + +hr { + background: #5294c1; + border: none; + height: 1px; + margin: 0; + padding: 0; +} + +ol li, ul li { + margin: 0.4em 0 0.4em .5em; /* LTR */ +} + +code, pre { + background: #f1f1f1; + border: 1px solid #444; + display: block; + margin: 1em; + padding: .2em; +} + +div#breadcrumb { + background-color: white; + border-bottom: 1px solid #ccc; + height: 2em; + padding: .2em 0 0 1em; + position: fixed; + top: 0; + width: 100%; +} + +div#breadcrumb .breadcrumb { + padding: 0; + margin: 0; +} + +#content { + margin: 3em 1em 1em 1em; +} + +#content #page-title { + margin-bottom: .5em; +} + +#content .toc { + background: #fff; + border: 1px solid #D0EBFF; + display: table; + margin: 10px 0; + padding: 5px 10px 5px 5px; +} + +#content .toc-block { + background: #fff; + border: 1px solid #D0EBFF; + float: right; + margin: 0 10px 10px; + padding: 5px; +} + +div.admin-panel { + background: #fff; + border: 1px solid #D0EBFF; + margin: 5px 0; + padding: 1em 1em 1.5em; +} + +div.admin-panel .description { + color: #898989; + font-size: 0.92em; + line-height: 150%; + margin-bottom: 1em; +} + +div.admin-panel .body { + margin: 0; + padding: 0; +} Index: modules/help/help-popup.tpl.php =================================================================== RCS file: modules/help/help-popup.tpl.php diff -N modules/help/help-popup.tpl.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/help/help-popup.tpl.php 21 Feb 2009 19:22:47 -0000 @@ -0,0 +1,34 @@ + + + + + +
' . t('Help is available on the following items:') . '
' . help_links_as_list(); - return $output; +* Menu callback; returns a page displaying available help topics for modules. +*/ +function help_by_module() { + $items = array(); + $menu_items = array(); + + $topics = help_get_topics(); + $settings = help_get_settings(); + + help_get_topic_hierarchy($topics); + + $modules = module_rebuild_cache(); + foreach ($modules as $file) { + $module = $file->name; + if (empty($topics[$module]) || !empty($settings[$module]['hide'])) { + continue; + } + + // Fetch help links. + $items = help_get_tree($topics, $topics[$module]['']['children'], array(), 0); + + // Sort in ascending order of keys. + ksort($items); + + // Retrieve the name to use. + if (isset($settings[$module]['index name'])) { + $name = $settings[$module]['index name']; + } + elseif (isset($settings[$module]['name'])) { + $name = $settings[$module]['name']; + } + else { + $name = t($file->info['name']); + } + + $menu_items[$name] = array($file->info['description'], $items); + } + + // Render the page differently for popup display. + if (isset($_GET['popup'])) { + drupal_set_breadcrumb(array()); + print theme('help_popup', theme('system_admin_by_module', $menu_items)); + return; + } + + drupal_add_css(drupal_get_path('module', 'help') . '/help.css'); + return theme('system_admin_by_module', $menu_items); } /** - * Menu callback; prints a page listing general help for a module. + * Menu callback; returns a page with help topic for a module. */ -function help_page($name) { - $output = ''; - if (module_hook($name, 'help')) { - $module = drupal_parse_info_file(drupal_get_path('module', $name) . '/' . $name . '.info'); - drupal_set_title($module['name']); - - $temp = module_invoke($name, 'help', "admin/help#$name", drupal_help_arg()); - if (empty($temp)) { - $output .= t("No help is available for module %module.", array('%module' => $module['name'])); +function help_topic_page($module, $topic = NULL) { + $info = help_get_topic_info($module, $topic); + if (isset($topic) && !$info) { + // Return error 404 if the topic does not exist. + return drupal_not_found(); + } + + $popup = isset($_GET['popup']); + + drupal_set_title($info['title']); + + // Set up breadcrumb. + $breadcrumb = array(); + + $parent = $info; + $parent_module = $module; + + $checked = array(); + // Crawl up parent tree looking for the breadcrumb trail. + while (!empty($parent['parent'])) { + if (strpos($parent['parent'], '%')) { + list($parent_module, $parent_topic) = explode('%', $parent['parent']); } else { - $output .= $temp; + $parent_topic = $parent['parent']; + } + + // Mark the topic as checked to prevent processing again. + if (!empty($checked[$parent_module][$parent_topic])) { + break; } + $checked[$parent_module][$parent_topic] = TRUE; - // Only print list of administration pages if the module in question has - // any such pages associated to it. - $admin_tasks = system_get_module_admin_tasks($name); - if (!empty($admin_tasks)) { - ksort($admin_tasks); - $output .= theme('item_list', $admin_tasks, t('@module administration pages', array('@module' => $module['name']))); + $parent = help_get_topic_info($parent_module, $parent_topic); + if (!$parent) { + break; } + $breadcrumb[] = help_l($parent['title'], "admin/help/$parent_module/$parent_topic"); + } + + $output = help_view_topic($module, $topic, $popup); + if (empty($output)) { + $output = help_view_module($module, $popup); + drupal_set_title(t('@module', array('@module' => help_get_module_name($module)))); + } + else { + $breadcrumb[] = help_l(help_get_module_name($parent_module), "admin/help/$parent_module"); + } + + $breadcrumb[] = help_l(t('Help'), "admin/help"); + + if ($popup) { + drupal_set_breadcrumb(array_reverse($breadcrumb)); + print theme('help_popup', $output); + return; + } + + $breadcrumb[] = help_l(t('Administer'), 'admin'); + $breadcrumb[] = l(t('Home'), ''); + drupal_set_breadcrumb(array_reverse($breadcrumb)); + drupal_add_css(drupal_get_path('module', 'help') . '/help.css'); + + return $output; +} + + /** + * Load and render a help topics listing. + */ +function help_view_module($module, $popup = FALSE) { + $output = ''; + + $items = array(); + $topics = help_get_topics(); + + help_get_topic_hierarchy($topics); + + if (!empty($topics[$module])) { + $items = help_get_tree($topics, $topics[$module]['']['children'], array(), 0); + $output = theme('item_list', $items, NULL, 'ul', array('class' => 'toc')); + } + else { + $output = t('No help topic on this subject is available.'); } + return $output; } -function help_links_as_list() { - $empty_arg = drupal_help_arg(); - $module_info = module_rebuild_cache(); - - $modules = array(); - foreach (module_implements('help', TRUE) as $module) { - if (module_invoke($module, 'help', "admin/help#$module", $empty_arg)) { - $modules[$module] = $module_info[$module]->info['name']; - } - } - asort($modules); - - // Output pretty four-column list - $count = count($modules); - $break = ceil($count / 4); - $output = '' . t('This guide provides context sensitive help on the use and configuration of Drupal and its modules, and is a supplement to the more extensive online Drupal handbook. The online handbook may contain more up-to-date information, is annotated with helpful user-contributed comments, and serves as the definitive reference point for all Drupal documentation.', array('@drupal' => 'http://drupal.org', '@handbook' => 'http://drupal.org/handbook')) . '
'; - return $output; - case 'admin/help#help': - $output = '' . t('The help module provides context sensitive help on the use and configuration of Drupal and its modules, and is a supplement to the more extensive online Drupal handbook. The online handbook may contain more up-to-date information, is annotated with helpful user-contributed comments, and serves as the definitive reference point for all Drupal documentation.', array('@drupal' => 'http://drupal.org', '@handbook' => 'http://drupal.org/handbook')) . '
'; - $output .= '' . t('For more information, see the online handbook entry for Help module.', array('@help' => 'http://drupal.org/handbook/modules/help/')) . '
'; - return $output; + return '' . t('This guide provides context sensitive help on the use and configuration of Drupal and its modules, and is a supplement to the more extensive online Drupal handbook. The online handbook may contain more up-to-date information, is annotated with helpful user-contributed comments, and serves as the definitive reference point for all Drupal documentation.', array('@drupal' => 'http://drupal.org', '@handbook' => 'http://drupal.org/handbook')) . '
'; } } + +/** + * Return code that emits a link to view a topic in a popup. + * + * @param $module + * The module that owns this help topic. + * @param $topic + * Optional identifier for the topic. NULL value displays all available topics. + * @param $title + * Optional title or label for the link. Default is "More help". + * @param $popup + * Optional boolean value to open the link in a popup. + * @param $attributes + * An array of attributes to include in hyperlink. + */ +function theme_help_link($module, $topic = NULL, $title = NULL, $popup = TRUE, $attributes = array()) { + static $js_added = FALSE; + + if (!isset($title)) { + $title = t('More help'); + } + + if ($popup) { + // Set class for links to be opened in popup. + $popup_class = !empty($attributes['class']) ? $attributes['class'] . ' help-link-popup' : 'help-link-popup'; + $attributes += array('class' => $popup_class); + } + + // Check for the function existence and include help.admin.inc. + drupal_function_exists('help_get_topic_info'); + // Fetch the information on the module/topic. + $info = help_get_topic_info($module, $topic); + + if (isset($topic) && !$info) { + // Return if the explicitly specified topic doesn't exist. + return; + } + + // Set the topic title as the hyperlink's title attribute. + $attributes += array('title' => $info['title']); + + if (!$js_added) { + // Include JavaScript for opening topics in a popup for hyperlinks with the class 'help-link-popup'. + drupal_add_js('modules/help/help.js'); + $js_added = TRUE; + } + + // Trim the trailing slash if no topic is specified. + $output = l($title, trim("admin/help/$module/$topic", '/'), array('attributes' => $attributes)); + + return 'To translate help, first create a translations/help/$language directory +in the module directory. Then, copy the .ini file and all .html files from +the help directory.
+ +The .ini file only needs to keep the titles, and if there is a 'name' or 'index name' setting in the 'help settings' portion, that should be retained. Any retained settings should be translated. The rest of the data in the .ini file may be discarded or ignored.
+ +Each file should then be translated in place.
+ +When translating a .html file, you will find that the path keyword will lead to the original directory. If you must translate items that are linked, such as images, use trans_path instead, which will lead to the translated directory. This will allow you to pick and choose which linked items, if any, will be translated.
\ No newline at end of file Index: modules/system/system.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v retrieving revision 1.127 diff -u -p -r1.127 system.admin.inc --- modules/system/system.admin.inc 18 Feb 2009 15:19:56 -0000 1.127 +++ modules/system/system.admin.inc 21 Feb 2009 19:22:48 -0000 @@ -85,10 +85,8 @@ function system_admin_menu_block_page() * Menu callback; prints a listing of admin tasks for each installed module. */ function system_admin_by_module() { - $modules = module_rebuild_cache(); $menu_items = array(); - $help_arg = module_exists('help') ? drupal_help_arg() : FALSE; foreach ($modules as $file) { $module = $file->name; @@ -101,8 +99,8 @@ function system_admin_by_module() { // Only display a section if there are any available tasks. if (count($admin_tasks)) { - // Check for help links. - if ($help_arg && module_invoke($module, 'help', "admin/help#$module", $help_arg)) { + // Check for help topics. + if (help_exists($module)) { $admin_tasks[100] = l(t('Get help'), "admin/help/$module"); } @@ -598,9 +596,6 @@ function system_modules($form_state = ar $modules = array(); $form['modules'] = array('#tree' => TRUE); - // Used when checking if module implements a help page. - $help_arg = module_exists('help') ? drupal_help_arg() : FALSE; - // Iterate through each of the modules. foreach ($files as $filename => $module) { $extra = array(); @@ -618,12 +613,10 @@ function system_modules($form_state = ar $extra['requires'][$requires] = t('@module (enabled)', array('@module' => $files[$requires]->info['name'])); } } - // Generate link for module's help page, if there is one. - if ($help_arg && $module->status && in_array($filename, module_implements('help'))) { - if (module_invoke($filename, 'help', "admin/help#$filename", $help_arg)) { - // Module has a help page. - $extra['help'] = theme('more_help_link', url("admin/help/$filename")); - } + // Generate link for module's help topics, if there are any . + if (help_exists($filename)) { + // Module has help topics. + $extra['help'] = theme('help_link', $filename, NULL, t('Get help')); } // Mark dependents disabled so the user cannot remove required modules. $dependents = array(); @@ -744,7 +737,7 @@ function _system_modules_build_row($info $form['description']['#markup'] .= theme('system_modules_incompatible', $status_long); } - // Show a "more help" link for modules that have them. + // Show a help link for modules that have them. if ($extra['help']) { $form['help'] = array( '#markup' => $extra['help'],