Problem/Motivation

hook_help() has two purposes:
a) Modules can provide help for specific administrative pages, which goes into the Help block (typically displayed in Seven at the top of the page).
b) Modules can provide a top-level module overview topic (typically explaining what a module is for and how to use it), and these are listed on the admin/help page.

This issue only concerns the module-overview topics [b] not the page-specific help.

This help system has several problems, which have persisted throughout many versions of Drupal (it existed pretty much as it is now as early as version 4.6):

  • Only modules can provide these top-level topics, not themes, Core, profiles, etc. So we have no good place to provide help on our core themes, or help for fields that are in core and not in a module, or help topics like "what are entities", etc., because they are not associated with modules.
  • Each module can provide only one topic. For instance, the System module help is currently a mish-mash of "everything provided by the system module plus core systems".
  • The help cannot be edited to suit particular sites, and admins cannot add their own help topics without writing a custom module.
  • The list of help topics is flat, not hierarchical.
  • Editing topics is difficult for documentation writers, since they need to write/edit PHP functions.
  • Users new to Drupal have no idea which topic to look in to learn how to do a task or about a topic, because they do not know already what module provides that information.

It would instead be desirable to have a system where:

  • Modules, Core, Themes, etc. could each provide one or more help topics, each with a machine name, a human-readable title, and a somewhat structured body.
  • The topics would have relationships. The admin/help page would list topics that are marked as "top-level". In addition, each topic would be able to have "relationships" to other topics, such that when displaying a topic, there would be an automatic display of the related topics and any topics listing this one as related. [This is preferable to a strict parent-child hierarchy of topics, based on the experience of the drupal.org community documentation -- having a strict tree is problematic for help.
  • Administrators could manage (edit/add/delete) the help topics. This would allow them to build a set of help for their own site, and make top-level topics or outline pages for different roles within the site. Also, module developers and help topic writers could use this same UI to create/edit help topics, and export them into the config/optional directory of a module, theme, or distribution (contrib or core).

Note: We've had a proposal before for a help system that would solve some or all of these problems. See #1031972: Discussion: What would a better help system for D8 be? for a discussion, and https://www.drupal.org/node/1095012 for a proposal... but this system didn't get built, due to complexity and/or lack of interest and consensus.

Proposed resolution

The proposal in this issue is:

  • We would define a config entity for a help topic. This config entity would have fields for the related topics, as well as fields that would allow building the body of the topic. We would also need to have a way to make inline links to other help topics and to admin pages within the site.
  • Modules, themes, core, etc. could provide configuration for one or more help topics.
  • There would be an admin page that would allow for CRUD on the help entities. You could then use the Config Export UI to export shipped config or share with another site.
  • The admin/help listing page would display these help entities along with the hook_help() module-level topics. This issue is currently postponed on #2661200: Make admin/help page more flexible, and list tours on it, which makes that display possible.
  • hook_help() would continue in its present form. However, we might want to take out some information that is currently in hook_help() implementations, and make configurable topics instead. Good candidates might be:
    - the entity/field background information currently in the Field module help.
    - task-based "how to do xyz" information, which could be organized by task instead of by module
    Note that #2354539: [meta] Convert help to new config entities proposed converting everything, but we should revise that to only convert selected topics, and we still want to keep the module overviews.

Remaining tasks

Concerns still to be addressed:

  1. We need to figure out what happens if a module updates their default help config entity. CMI currently has no interest in updated default configuration so if a site doesn't edit the default config, it also won't get any updates either (unless the module author explicitly adds an update to change it, but that risks changing something that's been edited). See comment #119. This is a generic problem in Core with updating config.
  2. If/when #2358923: Config translation module cannot deal with different base path gets fixed, then we should change the help topic to have the View page be the canonical route for translation. See comment #84, #85, #86, and #94.
  3. If/when this help topic entity gets added to core, there are some follow-ups:
    - #2354539: [meta] Convert help to new config entities
    - #2355685: Make "view help topics" its own permission
    - Publish the draft change notice https://www.drupal.org/node/2354963

User interface changes

New topics displayed along with old hook_help() topics on Help page. New UI added for editing help. Site builders can make their own help topics.

API changes

Modules would have an additional way to provide help, but would not be required to use it.

CommentFileSizeAuthor
#145 2351991-145.patch125.84 KBjhodgdon
#110 2351991-help-entity-110.patch66.92 KBjhodgdon
#110 interdiff.txt4.4 KBjhodgdon
#101 interdiff.txt994 bytesjhodgdon
#101 2351991-help-entity-101.patch67.01 KBjhodgdon
#95 interdiff.txt9.86 KBjhodgdon
#95 2351991-help-entity-95.patch67.02 KBjhodgdon
#92 interdiff.txt1.89 KBjhodgdon
#92 2351991-help-entity-92.patch62.39 KBjhodgdon
#86 interdiff.txt1.82 KBjhodgdon
#86 2351991-help-entity-86.patch61.44 KBjhodgdon
#83 interdiff-changes.txt1.93 KBjhodgdon
#83 interdiff-newfiles.txt2.55 KBjhodgdon
#83 2351991-help-entity-83.patch61.45 KBjhodgdon
#75 2351991-help-entity-75.patch57.35 KBjhodgdon
#70 Add Hungarian translation for Help module help topic | s2f835baca6773f1.s3.simplytest.me 2014-10-14 16-13-21.png368.78 KBGábor Hojtsy
#53 interdiff.txt4.58 KBjhodgdon
#53 2351991-help-entity-53.patch57.33 KBjhodgdon
#52 Add help topic Drupal8.png71.26 KBjibran
#49 interdiff-changes.txt999 bytesjhodgdon
#48 interdiff-newfiles.txt3.97 KBjhodgdon
#48 2351991-help-entity-48.patch57.37 KBjhodgdon
#47 interdiff-changes.txt14.58 KBjhodgdon
#47 interdiff-newfiles.txt5.85 KBjhodgdon
#47 2351991-help-entity-47.patch53.19 KBjhodgdon
#43 2351991-help-entity-43.patch47.3 KBjhodgdon
#43 interdiff-newfiles.txt1.34 KBjhodgdon
#43 interdiff-changes.txt13.15 KBjhodgdon
#38 2351991-diff-37-38.txt6.12 KBvijaycs85
#38 2351991-hook_help-38.patch43.2 KBvijaycs85
#37 help-config.37.patch43.08 KBlarowlan
#37 interdiff.txt4.83 KBlarowlan
#36 help-config.36.patch40.05 KBlarowlan
#36 interdiff.txt1.24 KBlarowlan
#28 interdiff.txt4.75 KBjhodgdon
#27 route-tokens.27.patch39.07 KBlarowlan
#27 interdiff.txt1.56 KBlarowlan
#26 route-tokens.26.patch39.35 KBlarowlan
#26 interdiff.txt4.83 KBlarowlan
#25 interdiff.txt11.74 KBjhodgdon
#25 2351991-help-config-entity-25.patch34.68 KBjhodgdon
#23 interdiff-b.txt3.2 KBtim.plunkett
#23 interdiff-a.txt4.61 KBtim.plunkett
#23 2351991-help-22.patch35 KBtim.plunkett
#20 interdiff.txt10.54 KBjhodgdon
#20 2351991-help-config-entity-20.patch35.54 KBjhodgdon
#16 before-help-page.png93.01 KBvijaycs85
#16 after-help-topic-link.png51.23 KBvijaycs85
#16 after-help-topic-add.png67.73 KBvijaycs85
#16 after-help-page.png103.67 KBvijaycs85
#14 2351991-help-config-entity-14.patch27.49 KBjhodgdon
#12 2351991-help-config-entity-12.patch24 KBjhodgdon
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jhodgdon’s picture

Assigned: Unassigned » jhodgdon
Fabianx’s picture

+1 to this issue! This is a great proposal and would solve so much for admins customizing the system, which are usually not the developers building it.

andypost’s picture

Issue tags: +beta deadline

Great! Would be great to move SystemHelpBlock to help module once on it

tstoeckler’s picture

This is a very interesting proposal. Note that one feature that this would still not solve and that e.g. Advanced Help in D7 has is images in help. There's really no way to store image references in config, and much less in module-shipped config. Still +100 for this issue, just wanted to point that out.

jhodgdon’s picture

Image references -- no, but you could certainly have an image that is somewhere in a module directory or subdirectory, and make a direct IMG tag to it.

SystemHelpBlock to Help module -- nothing to do with this issue. Please file a separate issue if you want to do that. SystemHelpBlock is for the help that goes at the tops of individual pages. This issue is about the module-level help topics that appear on their home page. Totally separate.

tstoeckler’s picture

Image references -- no, but you could certainly have an image that is somewhere in a module directory or subdirectory, and make a direct IMG tag to it.

Hmm... interesting idea. That will get tricky because you can't hardcode the location of a module. That can be discussed in a follow-up, though.

larowlan’s picture

First up great idea. We already have tour config entities and plans to make them address topics. Perhaps we could align the two and have help subsume tour module? A single config entity that has general topic based help as well as route and element specific help. System help block would be replaced with tours.
Thoughts?

nick_schuch’s picture

I think this is a great idea. Consolidating the module, approaches and efforts would be a huge boost for both.

Referring back to the original tour ticket there is a big discussion about rethinking how we do help. Consolidating of approaches might is a great way to then start the discussion.

https://www.drupal.org/node/1809352#comment-7081012

jhodgdon’s picture

Tours are for pages. System help blocks are for pages. This config entity is not, and I don't think it serves the same purpose as a tour. I also don't think the Tour entity has the same structure as a Topic entity, and I don't think I want to make an entity complex enough to know what page it belongs on, or take over hook_help() completely. Please... don't try to make this any more complex than it is!

jhodgdon’s picture

Also this issue has been marked Beta Deadline, and we are past beta. We do not have time to make it Do Everything Possible That You Could Think Of.

jhodgdon’s picture

Issue summary: View changes

OK, I am updating the issue summary to describe the limitations of this idea.... Actually it already says this. Emphasizing it.

THIS IS ONLY for the help topics that you see on admin/help. It is not for the help at the top of pages that the System Help block shows.

jhodgdon’s picture

I have a preliminary version of this working! This is NOT DONE but I am going to upload this patch just in case my computer crashes or something... still some work to do! I'll be working on it more tomorrow.

Fabianx’s picture

We could run the help through twig templates in which case you could link to a module, etc. but that would be follow-up and as old syntax is supported, would not be a BC break.

jhodgdon’s picture

Status: Active » Needs review
Issue tags: -beta deadline +beta target, +Needs tests
FileSize
27.49 KB

Here's a more viable patch. I didn't make an interdiff; quite a lot has changed, and hopefully no one looked at the previous patch yet since it was just up there to prevent me losing everything in a computer crash.

There are a few things that still need work in this patch, but it's basically working and I would love it if people would try it out. The things that need work that I know about:

a) Breadcrumbs on topic pages -- need to make a breadcrumb handler class so the breadcrumbs are Admin> Help like on Module pages. Fairly easy to do; a couple of examples in Core (Book, Comment modules).

b) Internal links. I think this just needs to be done via a text filter, which would almost undoubtedly be useful in general for Drupal admins and content editors. I've tentatively made a Help module topic config. In this, I used things like <a href="[[help.main]]"... which I would propose this text filter would transform to a link to admin/help (which is at route help.main). I'll work on this next.

c) Tests. There aren't any, and this could break existing tests? not sure.

d) A few more topics should be converted. Once I have the text filter working, I'll work on this too.

Suggestions/notes if you want to test it (turn on the Help module obviously):

- Go to admin/config. You'll see an entry for "Help topics" that will take you to the config page, where you can add/edit topics.

- Go to admin/help. You'll see the previously-existing list of module help topics, and a new area listing the configured help topics. We can bikeshed about the wording/headings starting now. :)

- For the moment this patch only has one configured help topic, for "Help Module". This explains how to use the configured help stuff.

Thoughts?

Status: Needs review » Needs work

The last submitted patch, 14: 2351991-help-config-entity-14.patch, failed testing.

vijaycs85’s picture

Did a quick manual test. Overall, It looks amazing. Please find the screenshot attached. the 3 fails related to the change of URL i.e. admin/help/help become admin/help_topic/help_module.

vijaycs85’s picture

few minor nice to haves:

  1. URL of help topic page can be fixed so that it will be something like admin/help-topics/[plugin_id]
  2. Add a standard so that module's main topic is always in the form of help.help.modulename.yml and other additional pages can be help.help.modulename_section_title.yml. it would be cool, if we can have the subpage as admin/help-topics/modulename/section-name as well as admin/help-topics/modulename#section-name. But surely out of this issue's scope.
jhodgdon’s picture

I'll change it to admin/help-topic/* in the next patch. I don't think help-topics (with an S) is a good idea -- we don't have nodes/5, we have node/5. And taxonomy/term/3 not terms. Etc.

Your idea for the naming convention is fine. I'll get that into the Help class doc. I don't think I want to mess with complicated URLs like that though. admin/help-topic/ID should be it. Period. Too complicated ==> difficult.

jhodgdon’s picture

Oh wait though. We can have a module and a theme with the same machine name... so I think just using the machine name of the extension without a suffix is not a great idea. I suggest we adopt modulename_module and themename_theme as the convention.

jhodgdon’s picture

Status: Needs work » Needs review
FileSize
35.54 KB
10.54 KB

OK, here's the next bit: I've fixed the breadcrumbs, changed the route path as discussed above, and fixed the tests; also added tests for the new functionality. The interdiff may or may not be OK, it's a bit weird due to adding files.

As a note, the existing HelpTest was assuming that modules implementing hook_help() would have module overview pages. This is increasingly not going to be true with this patch. So I just tested with a new test module instead.

Remaining item to do is to get the links working, and that part will need tests.

Fabianx’s picture

This is great! The patch looks amazing already.

Just a question:

Is the plan to have a meta afterwards to convert all the hook_help() to configuration also? Just curious.

jhodgdon’s picture

Yes. I plan to put another few into this patch, and then have a meta afterwards to convert the rest. Glad you like it! :)

tim.plunkett’s picture

  1. --- /dev/null
    +++ b/core/modules/help/config/install/help.help.help_module.yml
    
    @@ -0,0 +1,97 @@
    +class Help extends ConfigEntityBase implements HelpInterface {
    

    I think this should probably be called HelpTopic, just in case there is every something else provided by help.module. Then the file would be help.topic.*.yml

    Also, the _module suffix is overkill, themes and modules need to be differently named for hooks and such anyway.

  2. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -145,4 +212,66 @@ public function helpPage($name) {
    +  public function helpEntityView($id) {
    

    This should eventually be a ViewBuilder, but I know those are rather cumbersome for ConfigEntities

  3. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -145,4 +212,66 @@ public function helpPage($name) {
    +    $body = $config->get('body');
    

    In my patch I switch these to entities instead of config objects (which ->get() will still work for) but there should be public methods added to the entity interface for these.

I've attached two interdiffs, one for each logical change.

The first is that you shouldn't use the config object directly, and by switching {id}/$id to {help}/HelpInterface in the routing/controller, it auto-loads the help for you. This will also handle config translation!

The second is that the help.topic_view route correlates to what a canonical route would show for it, so I've switched that. And by adding a link template for that, the Url generation becomes a lot easier.

Status: Needs review » Needs work

The last submitted patch, 23: 2351991-help-22.patch, failed testing.

jhodgdon’s picture

Status: Needs work » Needs review
FileSize
34.68 KB
11.74 KB

Here is a new patch that fixes a few problems with Tim's patch (thanks Tim!) and also implements the change he suggested of making the entity class HelpTopic, with ID help_topic and config prefix topic. And also the suggestion of making the convention for module Foo help to just have machine name foo not foo_module (if Tim and Vijay agree this is better, I will bow to their wisdom).

The interdiff shows changes in the files, after renaming two files:
Help.php -> HelpTopic.php
help.help.help_module.yml -> help.topic.help.yml

Still need to do something about the links. larowlan is working on a token solution (brilliant!).

larowlan’s picture

FileSize
4.83 KB
39.35 KB

This adds support for route tokens.


   $text = 'This should <a href="[route:system.admin]">Link to admin</a>';
   $replaced = \Drupal::token()->replace($text);
   print $replaced;
   // outputs This should <a href="/admin">Link to admin</a>

larowlan’s picture

FileSize
1.56 KB
39.07 KB

Minor cleanup, self-reviews++

jhodgdon’s picture

FileSize
39.33 KB
4.75 KB

Great! With larowlan's tokens, here is a new patch. Added a token::replace call to the Controller and changed the help topic config so it has [route:] in it.

The only other thing I think we'll need right now for the 90% use case is a token like
[help_topic:machine_name]
that would turn into a link to the help topic. Or something like that. The current patch, which just converts the Help module topic, does not need this.

alexpott’s picture

+++ b/core/modules/system/src/Tests/Token/RouteTokensTest.php
@@ -0,0 +1,51 @@
+  public static $modules = array('system', 'user', 'core');
...
+    $this->installConfig(array('core'));

There is no core module to enable. And I'm not sure why this is needed.

vijaycs85’s picture

help.help.help_module.yml -> help.topic.help.yml

awesome! @tim.plunkett++

  1. +++ b/core/modules/help/config/schema/help.schema.yml
    @@ -0,0 +1,28 @@
    +      label: 'Topic title'
    

    Just 'Title'

  2. +++ b/core/modules/help/config/schema/help.schema.yml
    @@ -0,0 +1,28 @@
    +          label: 'Body text'
    

    Body

  3. +++ b/core/modules/help/config/schema/help.schema.yml
    @@ -0,0 +1,28 @@
    +          label: 'Body format'
    

    Text format

  4. +++ b/core/modules/help/config/schema/help.schema.yml
    @@ -0,0 +1,28 @@
    +      label: 'Display on help topic list'
    

    This should be the label of the checkbox. which is 'Top-level topic' to keep the translation sync.

  5. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -8,11 +8,14 @@
    +use Drupal\help\HelpInterface;
    

    may be renamed to HelpTopicInterface.

  6. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -27,13 +30,23 @@ class HelpController extends ControllerBase {
    +  protected $helpStorage;
    

    Minor: can be just $storage

  7. +++ b/core/modules/help/src/Entity/HelpTopic.php
    @@ -0,0 +1,97 @@
    + * Defines a configuration entity for help topics.
    

    Great documentation!

  8. +++ b/core/modules/help/src/Entity/HelpTopic.php
    @@ -0,0 +1,97 @@
    + * etc. by creating help topics from admin/config/development/help (with the
    

    etc? do we have anything other than module and themes that can provide help topics?

  9. +++ b/core/modules/help/src/Form/HelpForm.php
    @@ -0,0 +1,153 @@
    +class HelpForm extends EntityForm {
    

    HelpTopicForm

  10. +++ b/core/modules/help/src/Form/HelpForm.php
    @@ -0,0 +1,153 @@
    +      '#description' => $this->t('Check box if this topic should be displayed on the Topics list'),
    

    is it intentional capitalisation for 'Topics' in the middle?

  11. +++ b/core/modules/help/src/Form/HelpForm.php
    @@ -0,0 +1,153 @@
    +      drupal_set_message(t('Help topic updated.'));
    ...
    +      drupal_set_message(t('Help topic added.'));
    

    $this->t()

  12. +++ b/core/modules/help/src/HelpBreadcrumbBuilder.php
    @@ -0,0 +1,51 @@
    +  use StringTranslationTrait;
    

    there should be an empty line between class and use statement.

  13. +++ b/core/modules/help/src/HelpBreadcrumbBuilder.php
    @@ -0,0 +1,51 @@
    +  }
    

    empty like before class close.

  14. +++ b/core/modules/help/test/modules/help_test/help_test.module
    @@ -0,0 +1,18 @@
    +function help_test_help($route_name, RouteMatchInterface $route_match) {
    

    why are we checking hook_help? can we add a helptopic entity and check?

jhodgdon’s picture

FileSize
39.33 KB

Oh, one other thing I thought of.

There's a @todo in the Controller that says something about "maybe list the other topics that list this one as Related".

I am thinking now that we shouldn't do that. But what we should do is have another field on the config entity for "show_on" that would say "Also list this topic as Related on these other topic pages".

In this way, for instance, contrib module A could say "List me on this other module's topic" and it would only show up if that other module was turned on, and the other module wouldn't have to know about module A.

So I'll add that tomorrow, and if larowlan doesn't beat me to it, also do something about topic-to-topic link tokens, because we need those (the route tokens do not support placeholders, because how could you do that?).

jhodgdon’s picture

uh. Something weird happened with the files there... :(((((( ok hopefully they are all there...

alexpott’s picture

+++ b/core/modules/help/config/install/help.topic.help.yml
@@ -0,0 +1,10 @@
+  value: "<h3>About</h3>\r\n\r\n<p>The Help module provides <a href=\"[route:help.main]\">Help reference pages</a> to guide you through the use and configuration of modules. It is a starting point for <a href=\"https://www.drupal.org/documentation\">Drupal.org online documentation</a> pages that contain more extensive and up-to-date information, are annotated with user-contributed comments, and serve as the definitive reference point for all Drupal documentation. For more information, see the <a href=\"https://www.drupal.org/documentation/modules/help/\">online documentation for the Help module</a>.</p>\r\n\r\n<h3>Uses</h3>\r\n\r\n<dl>\r\n\t<dt>Providing a help reference</dt>\r\n\t<dd>The Help module displays both static module-provided help and configured help topics on the main <a href=\"[route:help.main]\">Help page</a>.</dd>\r\n\t<dt>Configuring help topics</dt>\r\n\t<dd>You can add, edit, delete, and translate configured help topics on the <a href=\"[route:help.topic_admin]\">Help topics</a> administration page. The help topics that are listed in the Module help section of the main Help page cannot be edited or deleted.</dd>\r\n</dl>\r\n"

Let's use the multiline yaml format - see http://symfony.com/doc/current/components/yaml/yaml_format.html#strings

larowlan’s picture

There is no core module to enable. And I'm not sure why this is needed.

The date time tokens don't work without the core config that provides the formats.
Calling this->installConfig for a module that isn't installed also fails, so we have to pretend that we enable the 'core' module - then it works.
Alternative is to make it a web-test but that'd be much slower.

Berdir’s picture

Can't we just special case 'core' in there? We do that in a few places already...

larowlan’s picture

FileSize
1.24 KB
40.05 KB

sure

larowlan’s picture

FileSize
4.83 KB
43.08 KB

This adds help_topic tokens and renames HelpInterface to HelpTopicInterface

   $text = 'This should <a href="[help_topic:help]">Link to topic with ID help</a>';
   $replaced = \Drupal::token()->replace($text);
   print $replaced;
   // outputs This should <a href="/admin/help-topic/help">Link to topic with ID help</a>
vijaycs85’s picture

Addressing few review comments:

#30.1 - Fixed
#30.2 - Fixed
#30.3 - Fixed
#30.4 - Fixed
#30.5 - Already done in #37
#30.6 - NOT FIXED: Not sure it is with changing.
#30.7 - @jhodgdon++
#30.8 - NOT FIXED: Not use if it is OK to change. Wait for @jhodgdon
#30.9 - Fixed.
#30.10 - Fixed.
#30.11 - Fixed
#30.12 - Fixed
#30.13 - Fixed
#30.14 - NOT FIXED: Not use if it is OK to change. Wait for @jhodgdon

#33.1 - FIXED

jibran’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/help/help.tokens.inc
    @@ -0,0 +1,53 @@
    +  $types['help_topic'] = array(
    ...
    +  $topics = array();
    ...
    +    $topics[$help_topic_id] = array(
    ...
    +      'description' => t('URL to the @label help topic', ['@label' => $help_topic->label()]),
    ...
    +  return array(
    ...
    +    'tokens' => array(
    ...
    +  $replacements = array();
    

    Either use `array()` or `[]` everywhere.

  2. +++ b/core/modules/help/help.tokens.inc
    @@ -0,0 +1,53 @@
    +  /* @var \Drupal\help\HelpTopicInterface */
    

    var name missing.

  3. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -27,13 +31,31 @@ class HelpController extends ControllerBase {
    +   * @var \Drupal\Core\UtilityToken
    

    it should be `\Drupal\Core\Utility\Token`

  4. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -27,13 +31,31 @@ class HelpController extends ControllerBase {
    +  public function __construct(RouteMatchInterface $route_match, EntityStorageInterface $help_storage, Token $token) {
    

    doc missing for `$token` in function def

  5. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -96,13 +139,36 @@ protected function helpLinksAsList() {
    +    $entities = $this->helpStorage->loadMultiple();
    

    It would be nice if we could add inline var definition :)

  6. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -145,4 +211,55 @@ public function helpPage($name) {
    +            'title' => $title,
    

    Undefined variable 'title'

  7. +++ b/core/modules/help/src/HelpListBuilder.php
    @@ -0,0 +1,58 @@
    +      ) + $entity->urlInfo('canonical')->toArray();
    

    `toArray` is deprecated now.

  8. +++ b/core/modules/help/src/HelpTopicInterface.php
    @@ -0,0 +1,16 @@
    +interface HelpTopicInterface extends ConfigEntityInterface {
    

    Maybe we should add getter and setter here i.e `$entity->get('top_level')`, `$entity->get('body')`, `$entity->get('related')` and $entity->set('related', $tosave)

  9. +++ b/core/modules/system/system.tokens.inc
    @@ -75,11 +79,25 @@ function system_token_info() {
    +    $routes[$route_name] = array(
    +      'name' => t('URL to !route_name', ['!route_name' => $route_name]),
    +      'description' => t('The URL to the !route_name route.', ['!route_name' => $route_name]),
    

    Either use `array()` or `[]` everywhere.

batigolix’s picture

This proposal would be a huge improvement for help topic writers because both editing in yml and via the UI is much easier than writing the topics in the hook_help() function within the .module file (that was so Drupal 6)

andypost’s picture

  1. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -41,50 +63,71 @@ public function __construct(RouteMatchInterface $route_match) {
       public function helpMain() {
         $output = array(
           '#attached' => array(
             'css' => array(drupal_get_path('module', 'help') . '/css/help.module.css'),
           ),
    -      '#markup' => '<h2>' . $this->t('Help topics') . '</h2><p>' . $this->t('Help is available on the following items:') . '</p>' . $this->helpLinksAsList(),
    +      '#markup' => '<h2>' . $this->t('Module help') . '</h2><p>' . $this->t('Help pages are available for the following modules:') . '</p>' . $this->moduleHelpLinksAsList() .
    

    Let's fix it to inline template

  2. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -145,4 +211,55 @@ public function helpPage($name) {
    +  public function helpEntityView(HelpTopicInterface $help_topic) {
    

    I still sure that we should use entity view builder here like TourViewBuilder does

  3. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -145,4 +211,55 @@ public function helpPage($name) {
    +    $build['#title'] = String::checkPlain($help_topic->get('label'));
    
    +++ b/core/modules/help/src/Entity/HelpTopic.php
    @@ -0,0 +1,97 @@
    + *   entity_keys = {
    ...
    + *     "label" = "label"
    

    $help_topic->label()

  4. +++ b/core/modules/help/src/Form/HelpTopicForm.php
    @@ -0,0 +1,153 @@
    +  public function exists($entity_id) {
    ...
    +        'exists' => array($this, 'exists'),
    

    No need in helper
    array('HelpTopic', 'load')

  5. +++ b/core/modules/help/src/HelpListBuilder.php
    @@ -0,0 +1,58 @@
    +    $row['label'] = $this->getLabel($entity);
    ...
    +  public function getDefaultOperations(EntityInterface $entity) {
    ...
    +    if ($entity->access('view')) {
    +      $operations['view'] = array(
    

    Suppose better to provide a link as label so no need in operation and default operation becomes "Edit"

  6. +++ b/core/modules/system/system.tokens.inc
    @@ -22,7 +23,10 @@ function system_token_info() {
    +  $types['route'] = array(
    +    'name' => t("Route information"),
    +    'description' => t("Tokens for route names."),
    
    @@ -75,11 +79,25 @@ function system_token_info() {
    +  foreach (\Drupal::service('router.route_provider')->getAllRoutes() as $route_name => $route) {
    ...
    +      'route' => $routes,
    

    Let's remove that to separate issue
    this also needs profiling...

  7. +++ b/core/modules/system/system.tokens.inc
    @@ -116,7 +134,8 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a
    -          $replacements[$original] = \Drupal::config('system.site')->get('mail');
    +          $replacements[$original] = \Drupal::config('system.site')
    +            ->get('mail');
    

    unnecessary change

  8. +++ b/core/modules/system/system.tokens.inc
    @@ -124,7 +143,10 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a
    +          $replacements[$original] = preg_replace(array(
    +              '!^https?://!',
    

    indent looks wrong

jhodgdon’s picture

This is most excellent! I go away for about 18 hours and there are new patches and new reviews!

I'm going to make a patch now to address hopefully the remaining concerns... thanks vijay especially for summarizing the status on #28 to that point!

Just adding this comment now; if someone else is working on the next patch please ping me in IRC now so we don't cross-post! Thanks everyone!!!!

jhodgdon’s picture

Status: Needs work » Needs review
FileSize
13.15 KB
1.34 KB
47.3 KB

Here's another patch, which addresses some mostly minor things from the previous reviews. I will make another patch or patches for some of the larger issues, on a separate comment or comments.

Note: two interdiffs -- one for the changes to existing files, and one for the new files (see below).

Replies and notes about the above reviews:

Comment #30

#8 - Anything that can provide configuration can provide topics. This would be: modules, themes, profiles, and Core. So... "modules, themes, etc." is probably OK.

#14 - We are maintaining the possibility that module developers (only modules!) can also use hook_help() to provide module overview topics (there are actually reasons you might want to use a function, because for instance it can be dynamic, and for backwards compatibility at this point in the Beta cycle). Because the Core modules are expected to mostly or entirely be converted from using hook_help() to using config entities, the test module uses hook_help() for testing purpose. So that needs to stay.

But I did also add two topic entity configs to the test module, and some additional tests.

Comment #33

The fix in #28 for this was not really complete: if you edited a Help topic and then export it, you would be back to having it all in one line with \r\n in there. So this still needs work.

Comment #39

Addressed all in this new patch.

Comment #41

#1 - This predated this issue, but good idea. Fixed.

#2 - Ah, great example! Agreed this is a good idea. TO DO

#3 - fixed

#4 - When I took out that line, I got and exception when submitting the form:
Notice: Undefined index: exists in Drupal\Core\Render\Element\MachineName::validateMachineName() (line 220 of core/lib/Drupal/Core/Render/Element/MachineName.php).
So I think it is necessary.

#5 - Excellent, duh! Fixed.

#6 - I can't convert topics from hook_help() to config entities without the added token types, so I'd like to keep this here (I think this comment is saying "do the routes token stuff in a separate patch", right?). Topics need to have links to routes and to other topics.

#7 - reverted this change, agreed not related to this patch.

#8 - indentation fixed, I guess. It's a two-level-deep array.

Other To Dos

- Create a test for the admin pages.
- Add the ability for help topics to say "List me on this other topic page".
- Convert a few more Core topics

jhodgdon’s picture

Issue summary: View changes

Added notes pertaining to batigolix's comments in #40 to the issue summary.

I'm still working on the remaining To Dos listed in #43.

andypost’s picture

Add the ability for help topics to say "List me on this other topic page".

Interesting idea, that's why #3 said about block, if help topics could appear more then one we need a kind of sorting for them

+++ b/core/modules/help/src/Entity/HelpTopic.php
@@ -94,4 +94,49 @@ class HelpTopic extends ConfigEntityBase implements HelpTopicInterface {
+  public function setRelated($topics) {
...
+      $item = trim($item);

+++ b/core/modules/help/src/Form/HelpTopicForm.php
@@ -124,16 +124,7 @@ public function form(array $form, FormStateInterface $form_state) {
   protected function copyRelatedFieldToEntity($type, EntityInterface $entity, array &$form, FormStateInterface &$form_state) {
...
-      $item = trim($item);

any reason for? suppose forms should care about that but that's optional

vijaycs85’s picture

Reg #43:

But I did also add two topic entity configs to the test module, and some additional tests.

ok.

jhodgdon’s picture

FileSize
53.19 KB
5.85 KB
14.58 KB

RE #45, the main reason for the trim is that in the next line, where it only adds items to the array if they are non-empty, I also wanted to weed out empty items that are only whitespace. I suppose it's not really necessary but seems cleaner.

Anyway. Latest patch and notes:

a) Convert to using a proper entity view builder instead of the controller method [comment #41 - item #2].

b) Add ability for topic A to say "List me on topic B page", and adds tests for this.

c) I did some further investigation on the \r\n problem. It seems that those \r\n are actually necessary... So if I go into the Add Help or Edit Help form, with CKEditor turned off, and I format the HTML source so that I can actually read it (i.e., put in newlines and maybe indents), when I go to config export it puts it all into one line and with the \r\n in there. And if I import a version of the help module topic page config without the \r\n in it, when I go into the Edit page, it's all scrunched up together into one line and hardly readable by an editor.

So while the config now accepts multiline, it's not really all that great if the source is HTML and you actually want the newlines kept in there where you put them.

d) I realized the "Full HTML" text format is probably not a good idea for shipped help topics, because that's part of standard profile. So I made a text format for help and added that to the help module.

e) Added a local task group so that View and Edit are local tasks (tabs) for help topic pages.

The only other To Dos, as far as I know, are:
1. Convert more topics. vijaycs85 is apparently working on this.
2. Add some tests for the admin CRUD functionality. I'll do this next but wanted to get this patch up for vijaycs85.

Two interdiffs again... one for existing file changes, one for new files.

jhodgdon’s picture

Issue tags: -Needs tests
FileSize
57.37 KB
3.97 KB

I added a child issue for the additional conversions.

And here is a patch with the admin CRUD test. Again, two interdiffs, one for two minor changes uncovered by the test and while writing it; the other for the new file.

Phew. I think this might be ready to go, of course pending the reviews!

jhodgdon’s picture

FileSize
999 bytes

forgot one

jibran’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/help/src/Entity/HelpTopic.php
    @@ -0,0 +1,180 @@
    +    $tosave = array();
    

    should be $to_save

  2. +++ b/core/modules/help/src/HelpViewBuilder.php
    @@ -0,0 +1,129 @@
    +use Drupal\Core\Entity\EntityInterface;
    ...
    +use Drupal\Core\Entity\EntityStorageInterface;
    

    unused.

  3. +++ b/core/modules/help/src/HelpViewBuilder.php
    @@ -0,0 +1,129 @@
    +   * @param \Drupal\Entity\EntityTypeInterface $entity_type
    ...
    +   * @param \Drupal\Entity\EntityManagerInterface $entity_manager
    ...
    +   * @param \Drupal\Language\LanguageManagerInterface $language_manager
    

    Wrong namespaces.

  4. +++ b/core/modules/help/src/Tests/HelpTopicAdminTest.php
    @@ -0,0 +1,132 @@
    +    foreach(array('admin/config', 'admin/config/development', 'admin/index') as $page) {
    

    phpcs: Expected "foreach (...) {\n"; found "foreach(...) {\n"

  5. +++ b/core/modules/system/system.tokens.inc
    @@ -75,11 +79,25 @@ function system_token_info() {
    +      'name' => t('URL to !route_name', ['!route_name' => $route_name]),
    +      'description' => t('The URL to the !route_name route.', array('!route_name' => $route_name)),
    

    Again [] and array() :(

jibran’s picture

Thank you @jhodgdon for fixing my previous review. Here are some more minor issues.

  1. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -96,13 +148,37 @@ protected function helpLinksAsList() {
    +    /* @var \Drupal\help\HelpTopicInterface $entity */
    

    It should be /* @var \Drupal\help\HelpTopicInterface[] $entities */ and should be added before line 158.

  2. +++ b/core/modules/help/src/HelpViewBuilder.php
    @@ -0,0 +1,129 @@
    +    return new static($entity_type, $container->get('entity.manager'), $container->get('language_manager'), $container->get('token'), $container->get('entity.query'));
    

    We are adding \n after every param for these calls.

jibran’s picture

FileSize
71.26 KB

Just some suggestion. We can ignore them :)

jhodgdon’s picture

Status: Needs work » Needs review
FileSize
57.33 KB
4.58 KB

Regarding #52 -

The text format defaults to using the "Help" format, actually, which is supplied by the Help module in this patch (if you had previously had the Help module installed and you just updated this patch, you will need to uninstall/reinstall Help module to get the new config imported for the text format, and you'll see this default). I do not think we should default to Basic or Full HTML, as those are part of Standard install profile, so they are not necessarily present on any given site. We also should not save any Core module help topics with anything but the Help text format, because that is the only one guaranteed to be present. So... I think defaulting to the Help format is actually the right thing to do. Thoughts?

Agreed the Related fields would be better as something more like either an entity reference or like tags... It would be easy to change the UI later, though, and I think it's good enough as it is now, and the storage is what we want. So... I filed a follow-up so we can discuss a nicer UI for this. OK? #2354955: Improve the UI for filling in help topic references

Regarding #51 & #52 - good cleanups, fixed in new patch.

jhodgdon’s picture

I guess we are going to need a change notice for this, although hook_help() still is quite usable in its old form and isn't changing: https://www.drupal.org/node/2354963 is the draft.

larowlan’s picture

+1 to new text format, great idea.
If there's a new ui pattern for the related topics we should post screenshots and tag as needs usability review, that's a gate too

jhodgdon’s picture

@larowlan: Are you saying we should get a usability review on the current UI, or for the proposed new UI? The UI that is there is just "enter a comma-separated list of topic machine names in the box".

larowlan’s picture

I think it would be courteous to confirm they were happy with a follow up

andypost’s picture

Priority: Normal » Major
Status: Needs review » Reviewed & tested by the community
Parent issue: » #2332687: Lost help for field types from Core/Field

I think the issue is ready, follow-ups filed, change record is great and #2202925: Move simple field types into Core/Field depends on it so raising priority

#55-#57 - Added this issue to #2346973: Improve usability, accessibility, and scalability of long select lists

Fabianx’s picture

RTBC + 1 from me

Just a little note:

+++ b/core/modules/help/src/Controller/HelpController.php
@@ -41,50 +52,91 @@ public function __construct(RouteMatchInterface $route_match) {
+    $output['modules'] = array(
+      '#type' => 'inline_template',
+      '#template' => $template,
+      '#context' => array(

This is usually not supported as the twig parser can't find the strings for translation if it can't see the template, but it does not matter in _this_ case, because all strings are translated separately.

So this is okay.

Gábor Hojtsy’s picture

As for translation, this solution merges help text for one topic from separate pieces into one bigger text piece. That may sound like better for translation and it may indeed improve context a little bit for some strings (although most strings are long enough to have enough context in themselves). However, having all the text for a topic in one string means that if a typo is fixed in the English original, translations will become outdated for the whole topic instead of just that small part of the topic like before. This is the exact reason we avoided putting the whole topic in one big t() and this solution is practically putting the whole text in one big t().

If we now believe this is a better approach for some reasons, then so be it. Ideally localize.drupal.org would be able to do some fuzzy matching to match strings even if they have small changes. We have #740494: Find translation memory to integrate with and implement integration open for that for 4.5 years with nobody doing work on it. Then Drupal core also needs a similar issue to do local fuzzy matching to apply translations until better ones become available. The hard part is "Use this setting to ...(5 more sentences)" is very similar to "Never use this setting to ... (5 more sentences)" and fuzzy matching will mark them as the same thing because there is only one word of difference. So again the main reason we chose to not merge help topics to one string instead of multiple strings is human review is most useful and relying on algorithms *only* may be dangerous.

Sorry for the sidetrack just wanted to illuminate a key question for this issue.

jhodgdon’s picture

Filed one more follow-up. #2355685: Make "view help topics" its own permission Not sure if it's a good idea or not but thought it should be discussed.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

We need to either use the fixed dependency key being introduced by #2224581: Delete forum data on uninstall or something similar to tour's module key to ensure that help topics are removed when a module is uninstalled - this also needs testing.

Gábor Hojtsy’s picture

In #24, @tim.plunkett noted changing the routes would support config translation better. Did someone test this with config translations? Basically a "Translate" tab should appear on the edit page which has a list of languages and allows adding translations if the integration works well. (The view/edit tabs and help and the schema makes me think it would/should work but I did not try).

jhodgdon’s picture

RE #63 - There is a translation tab if you install this module.

RE #62 - OK, I'll look into this... or if someone else has time to figure it out, go for it. I have to catch up on some client work this week and I'm heading to the PNW Drupal Summit in Portland for the later part of the week. So I'm not sure when/if I'll have time. :(

jhodgdon’s picture

Added one more follow-up issue, which also depends on a different issue being fixed and so can't be done right now (but it will be about a 5-line patch I think): #2356015: Convert Body field on Help entity to use new text-with-format

jhodgdon’s picture

I looked at how the Tour module does this... As far as I can tell:
a) Tour config schema has a "module" element.
b) Tour entity class has a corresponding $module member variable.
c) Tour entity class in calculateDependencies() does

$this->addDependency('module', $this->module)

I guess we could do this, but ... Tours do not have an editing UI, and the help entities do. What are we supposed to do about the module element in the edit/add topic form?

Alternatively, is there a way, when the config system is importing a Topic from a config/install directory, to have the config system set the module to the module that provided the Topic automatically, and then I guess just make it so that anything you create from scratch in the UI sets the module to 'help'? Then we'd have to tell module developers who create help entities using the UI and then exporting, would need to edit the file and change the 'module' element to their module name?

And... what about topics provided (hypothetically) by themes?

I really don't know about this... Any thoughts? And really, the config system doesn't automatically remember where config came from and uninstall it when the module that provides it is uninstalled? It seems like since config can be provided by modules, themes, and install profiles, as well as Core, that asking the config entity to figure out where it came from and deal with this is too much to ask... really do we need to do this?

larowlan’s picture

Yes adding a module property and the calculate dependencies is a good idea.
You could make the UI expose a select field listing active modules if needed, or alternatively make UI added ones default to help.

Fabianx’s picture

I overall think this needs to be figured out in the config system.

Generally deleting user supplied data when a module is uninstalled is a bad idea.

It is okay for automatically generated content though.

But the question remains: What about themes and profiles?

--

How do we deal currently with e.g. an image style provided by a module when the module was uninstalled? How do we deal with it when the image style was changed?

Replace image style with views and ask the question again.

andypost’s picture

I think that key should be "extension" default to "help"
And cmi issue with removal could be unified in #2224581: Delete forum data on uninstall

Gábor Hojtsy’s picture

+++ b/core/modules/help/test/modules/help_test/help_test.info.yml
+name: 'Help Test'
+type: module
+description: 'Support module for help testing.'
+package: Testing
+version: VERSION
+core: 8.x

In testing this patch I found that the help test module is not hidden. See above.

BTW the config translation UI works well with this module indeed:

However another issue I found while testing it is although /admin/help displays the help topic title translated, the actual page at /admin/help-topic/help did not. The reason for this is that entities are upcast in their original creation language on admin routes, with the expectation that admin routes will edit/delete/manage them and not merely display them. Config entities are upcast in the negotiated language on non-admin paths. So although one can translate help topics, it is not possible to view any of the translations, even if you switch languages on the admin screen. It will always display the original language. This is unfortunately a no-go. Not sure how to fix it. You can of course load it again in the negotiated language in your page controller, which would be the simplest or override the upcast logic to apply the negotiated language for this config entity for this route. (Or generalize that and make a route option for language upcasting to specify whether to upcast in negotiated or default and keep applying the current behavior unless explicitly specified otherwise). While this problem sounds far fetched from what this issue tries to accomplish, help topics shipped with this system are a step back in terms of translatability if they can never be displayed in their translated form.

jhodgdon’s picture

OK, this is great, thanks everyone for looking/testing/reviewing!

Things that need to be done:

a) Make sure the help test module is hidden. Oops. Thought I had done that.

b) Make sure help topic entities are displayed in the right language. The problem is that entities as route parameters are not translated, because it's assumed you are editing them (and that needs to be in English).

Berdir's suggestion for how to fix this is:

1. Add some information to the topic display route:

entity.help_topic.canonical:
  path: '/admin/help-topic/{help_topic}'
  defaults:
    _entity_view: 'help_topic.full'
    _title: 'Help'
  requirements:
    _entity_access: 'help_topic.view'
    options:
      parameters:
        help_topic:
          type: entity:help_topic
          # Force that help topics are loaded in the current
          # interface language
          use_current_language: true

2. Modify AdminPathConfigEntityConverter::applies() so that if it detects that use_current_language: true, it will return FALSE and so the default entity loader will be used and not the "if it's admin load in current language" loader.

c) Figure out dependencies. I think we actually should allow each topic to have multiple module and/or theme dependencies. So the schema would have something like:

dependencies:
   type: sequence

and within that each dependency would look like "module: foo" or "theme: bar".

The question is whether we should allow this to be specified in the UI. I think since these are editable by admin users, we can just (for now) make it a big text box comma separated. So if a help topic writer wanted to say "This topic depends on modules foo and bar, they would enter:

module: foo, module: bar

in the box. That would at least be clear and editable and would work. We could refine the UI later if necessary.

Thoughts?

jhodgdon’s picture

doh! berdir to the rescue -- in (a) I apparently put the test module in directory "test" not "tests". That will fix it!

jhodgdon’s picture

in (c) I will need to call this something other than dependencies in the config schema, because dependencies are dynamically, automatically calculated.

jhodgdon’s picture

OK, one more try on (c)...

On #2224581: Delete forum data on uninstall the patch introduces fixed config dependencies. That isn't done yet. That is what we would need.

So what we would need to do is have this editing field where you could enter module: foo, module: bar, theme: baz, but when saving, put it into

'dependencies' => array(
      'fixed' => array(
        'module' => array('foo', 'bar'),
        'theme' => array('baz'),
)

in the entity.

I'm not sure what to do in the meantime...

jhodgdon’s picture

Status: Needs work » Needs review
FileSize
57.35 KB

To start with, here's a patch that moves the core/module/help/test directory to be core/module/help/tests -- no other changes from the patch in #53. Should take care of the "test module is not hidden" problem. I didn't make an interdiff file.

Gábor Hojtsy’s picture

@jhodgdon: re 71 the solution suggested by Berdir for the route upcasting aligns with what I wrote for a more general solution in 70, specifically this part: Or generalize that and make a route option for language upcasting to specify whether to upcast in negotiated or default and keep applying the current behavior unless explicitly specified otherwise. So sounds good :)

jhodgdon’s picture

Good. So my plan for the "translation not working" issue is:

a) Write a test that installs help_test, help, and config_translation or whatever they're called. Adds a language. Clicks on Translate for one of the help_test topics, and supplies a "translation". Views the topic in the other language and verifies that it's displayed correctly. This would verify that the translation screen is there in the UI as well as that the topic is displayed correctly.

b) To fix it so it actually works: do as outlined in #71 item 1. Sounds like we all think this is a good idea, and it's also fairly easy to do.

So that is the next piece to work on.

I'm still not sure about the dependencies problem, but if I'm lucky, while I'm working on this that forum issue will land and we can use that method. :)

larowlan’s picture

The forum issue just needs doco, I'll pick it up again ASAP

larowlan’s picture

Oh actually Alex has done the doco so all it needs is reviews

alexpott’s picture

I the case of help topics created through the UI the module property would be "help" and yes help topic should be removed if the help module is uninstalled. The only time module property would be different is if a help topic is provided as a default configuration by another module - and then you want it to be removed when that module is uninstalled. The module author will have to change this manually.

jhodgdon’s picture

Yeah, but I think we want to allow for both modules and themes to have topics, so rather than a "module" field, we'd want to have a more generic dependencies field -- like the fixed dependencies added in that Forum issue.

jhodgdon’s picture

Issue summary: View changes

Updating the issue summary with the two remaining To Dos. I'm going to work on the plan in #77/#71 for fixing the translation problems.

jhodgdon’s picture

Issue summary: View changes
FileSize
61.45 KB
2.55 KB
1.93 KB

Here's a fix for the translation piece. It works for me, and has a test.

Question: There was already a Translate operation link on the Help topics management page (and this tests verifies its existence). But how can I make it so that if you are on the Help Topic edit or view page, you get a Translate tab (local task)? Shouldn't the config translation module put that in there? It isn't... Anyway, you can get to the Translate page from the help topics admin page, so maybe this is OK.

Anyway, two interdiff files (one for the changes and one for the new test file), and a new patch.

Gábor Hojtsy’s picture

Status: Needs review » Needs work

I think the translate tab is missing due to assumptions in config translation which again your module does not conform to :) The base route for config translation is the edit route. The translate tab is added as a children of that base route. In your admin screen there is a **view** of the help page, which is unlike how any of the other config settings work. So your edit screen gets the Translate tab as a sub-tab (note the path is also set up as /admin/config/development/help/help/edit/translate (ie. translate is under edit not alongside it). Other config entities have edit routes on a base path (not /edit). So the translate tab would show up as a second level tab under your edit tab now (which is where it is added now), but there is no other tab, so it is not displayed.

A solution to this would be to do away with the view page on the configuration screen (you already have a view page elsewhere) and just do what all other screens do and have an edit base path for the config entity. Another solution is to somehow make config translation module more intelligent about this, but not sure how...

jhodgdon’s picture

Ugh ugh ugh.

So I tried to do the simple thing:

function help_config_translation_info_alter(&$info) {
  $info['help_topic']['base_route_name'] = 'entity.help_topic.canonical';
}

This doesn't work at all, because there are other assumptions all over the config translation module that assume that the base route is really the Edit form. So for instance, with this change you cannot go to the help topics admin page at all because of this code in config_translation_entity_info_alter():

      elseif ($entity_type->hasLinkTemplate('edit-form')) {
        $entity_type->setLinkTemplate('drupal:config-translation-overview', 'config_translation.item.overview.' . $entity_type->getLinkTemplate('edit-form'));
      }

which is just blindly assuming that the base route is the edit form, which if you've altered it, is not true. And even if you comment out a bunch of code to get past that, and go to the Translate overview page, the Edit links on the Translation overview page always go back to whatever the base route is, so you have an Edit button that takes you to the View page if you've made this alter...

So... The assumption that Edit is the base route for translating config is deeply built into this module and is WAY beyond the scope of this issue to fix, IMO.

:((((((((((((((((((((((((

I realy don't know what to do. This isn't going to work without a lot of tearing apart the config translation module and making it actually obey and use its own hooks and not having assumptions.

jhodgdon’s picture

Status: Needs work » Needs review
FileSize
61.44 KB
1.82 KB

OK. For the moment, the way to get around this is to make Edit be the default tab and the base path. This patch does that. The UI is now OK -- you get edit, view, and translate tabs in the local task group. View is 2nd, which is slightly odd, but not horrible I think? The path admin/development/help/ID now goes to the edit page (used to be .../ID/edit), and admin/development/help/ID/translate is the translate path.

I think this works... tests pass locally... tabs are there... links work.... Thoughts?

Also I filed a separate issue about the inability to use the canonical route as the base route for translation:
#2358923: Config translation module cannot deal with different base path

Gábor Hojtsy’s picture

The key question is why do you do two view pages for help topics?

jhodgdon’s picture

Not sure what you're asking in #88?

andypost’s picture

#88 the BC path for module's help is there, the new path is for help entity (configurable help)

+++ b/core/modules/help/help.routing.yml
@@ -13,3 +13,49 @@ help.page:
+entity.help_topic.canonical:
...
+entity.help_topic.edit_form:

+++ b/core/modules/help/src/Entity/HelpTopic.php
@@ -0,0 +1,180 @@
+ *     "canonical" = "entity.help_topic.canonical",
...
+ *     "edit-form" = "entity.help_topic.edit_form",

+++ b/core/modules/help/src/HelpListBuilder.php
@@ -0,0 +1,46 @@
+  public function buildRow(EntityInterface $entity) {
...
+    $row['label']['data'] = array(
...
+      '#url' => $entity->urlInfo('canonical'),

Everything is fine here!

jhodgdon’s picture

Status: Needs review » Needs work

I thought of one more thing that this patch should have: validation for the two "related" fields in the Form classes. They should only contain commas and machine names of topics. I don't think we should validate that the machine names exist, but I think we should validate with a regexp that the fields only contain commas and whatever characters are allowed in standard machine names (we're just using the standard machine name regexp for the machine names).

I'll take care of this later today (after I actually wake up) or tomorrow...

jhodgdon’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
62.39 KB
1.89 KB

OK, here's a new patch with validation.

Gábor Hojtsy’s picture

@jhogdon: elaborating on my question in #88, that you asked about in #89, I believed you have two view paths for each help topic on the help.page and entity.help_topic.canonical routes. On a more careful review now it is evident you do not have access through the help.page route only through the canonical route. So then it is truly down to config translation not expecting that any config entity would display itself on the same admin area that it is configured (it is totally fine with an admin content view edited because they are used and edited at very different places). This use case of displaying a config entity where it is edited was not yet on our minds. Good that we may have one in core that we'll hopefully iron this out then :)

I agree a workaround here is sufficient for now and the actual problem should be fixed in config translation.

jhodgdon’s picture

Right, help.page is the route for static topics defined through hook_help(), and entity.help_topic.canonical is the route for editable topics defined through these new config entities.

The "workaround" for config translation in this patch is only that I made Edit be the first tab in the local task group instead of having View be the first tab. This is backwards from what you see on Node, Taxonomy term, etc., but at least all the tabs are there and work, and the URLs are what we will eventually want them to be. We can easily adjust this if the underlying bug is fixed in config translation, but right now I do not think it is possible to make this work with the tab order being View, Edit, Translate... as outlined on #2358923: Config translation module cannot deal with different base path.

So the only other remaining thing to take care of is the config dependencies. We're waiting on #2224581: Delete forum data on uninstall; it is currently RTBC so... maybe soon?

jhodgdon’s picture

FileSize
67.02 KB
9.86 KB

#2224581: Delete forum data on uninstall got in, so here is a new patch with dependencies, with tests for the new dependencies stuff, and a UI for adding them in the editor for help topics.

This should be the final iteration, pending reviews. Yippee! Tests pass locally...

jhodgdon’s picture

Issue summary: View changes

Summary update.

jibran’s picture

  1. +++ b/core/modules/help/help.tokens.inc
    @@ -0,0 +1,53 @@
    +  $types['help_topic'] = array(
    

    Please define $types var.

  2. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -41,50 +52,91 @@ public function __construct(RouteMatchInterface $route_match) {
    +  protected function fourColumnList($links) {
    

    Can we convert this to theme template? And use render array in moduleHelpLinksAslist

  3. +++ b/core/modules/help/src/Entity/HelpTopic.php
    @@ -0,0 +1,228 @@
    +      // 'entity: entity1; module: module1, module2; theme: theme1, theme2'.
    

    Awesome.

  4. +++ b/core/modules/help/src/Form/HelpTopicForm.php
    @@ -0,0 +1,184 @@
    +  public function exists($entity_id) {
    

    Where are we using this function?

jhodgdon’s picture

RE #97 -

item 1 - seriously? We have no standard about putting @var on every single local variable. In this case it's the return value of hook_token_info(), and we certainly have a standard saying that "Implements hook_whatever()" is acceptable documentation in this case. This is a 10-line function that returns an info value for this hook, and this local variable is clearly an associative array... nothing much to document? If you think it needs docs, please make your suggestion in the form of a patch? I don't think it's necessary.

item 2 - This is a separate issue and out of scope for this issue: #2337317: Replace help page layout CSS with reuseable layout classes

item 3 - Doesn't sound like you want a change.

item 4 - This is used as the "exists" callback in the machine name form element:

+    $form['id'] = array(
+      '#type' => 'machine_name',
+      '#default_value' => $this->entity->id(),
+      '#machine_name' => array(
+        'exists' => array($this, 'exists'),
+        'error' => $this->t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores.'),
+      ),
+    );
jibran’s picture

Thanks for clearing 2 and 4 . I was just praising the docs in 3. For 1 I only requested to add $types = array();. Sorry if I was not clear before. And thank you for your great work on the patch I really appreciate it.

alexpott’s picture

+++ b/core/modules/help/src/Form/HelpTopicForm.php
@@ -0,0 +1,184 @@
+    $form['enforced'] = array(
+      '#title' => $this->t('Dependencies'),
+      '#description' => $this->t('List of machine names of modules and themes this help topic depends on. The topic will be removed if any of these modules and themes are uninstalled. Format: module: module1, module2; theme: theme1, theme2'),
+      '#type' => 'textarea',
+      '#default_value' => $this->entity->getEnforcedDependenciesString(),
+    );
...
+    // semicolons, spaces, and characters that can be in machine names.
+    if (!preg_match('|^[a-z0-9_,;: ]*$|', $form_state->getValue('enforced'))) {
+      $form_state->setErrorByName('enforced', $this->t('Must be a list of dependencies in the right format'));
+    }

Why is not two multi-select lists of installed modules and themes. It should not be possible to create help that depends on modules and themes that are not installed. At the very least we should validate the input.

I guess there is also the question of whether we should even have this in the UI since in the action of creating a help topic and copying it to a module or theme you are going to have to edit the config file to remove the UUID - and that is the point where the dependency is real - when the help topic is being provided by an extension.

jhodgdon’s picture

FileSize
67.01 KB
994 bytes

Regarding #99, we have code like this all over core... Add it if you want. :)

Regarding #100... The main (only?) use case for this field is "Contrib module or theme developer making help topic(s) for distribution with their module/theme". So, the users of this field are likely developers, and I don't really think multi-selects are necessary, or careful validation. It's really there just for the convenience of developers (of the core help topics we need to convert now, and contrib down the line).

Given that, what if we just change the Description so it says something like "For use when creating topics for distribution with a module or theme", and leave it at that? [see attached patch]

And by the way, there is some minimal validation (allowed characters), just not the full validation of making sure the listed modules/themes actually exist.

So... I'm out of town the rest of today through next Monday. If something else comes up and someone wants to make a new patch, please do!

jhodgdon’s picture

Was this approach OK or not?

jhodgdon’s picture

Issue summary: View changes

We need to evaluate whether this should be:

a) Added to Core now.

b) Postponed to 8.1.x or a later release

c) If (b) published as a contrib module now

I am adding some information to the issue summary about the technical debt and options for this.

Fabianx’s picture

That will take some work. Each conversion is easy, but there are a lot of core modules and subsystems that need topics written. See #2354539: [meta] Convert help to new config entities

Wouldn't that make the process of writing that help topics simpler and not more difficult in the end and such save time?

jhodgdon’s picture

RE #104 - yes, it should save time in the long run and make it possible for actual writers who are not coders to write module help. Nonetheless, I was asked to list the technical debt that would be incurred if this patch were accepted post-beta, and therefore listed the need to convert existing help as one aspect of that. The 8.x branch maintainers have to evaluate technical debt/risks vs. rewards when deciding whether this belongs in 8.0.0, a later release, or contrib.

Meanwhile... any further issues here? I am not sure that the decision will be made until this patch reaches RTBC (again).

jhodgdon’s picture

The patch in #101 has been at Needs Review for 10 days... It would be really nice if someone could either mark it as Needs Work, RTBC, or "This needs to be postponed to 8.1.x". Thanks!

Fabianx’s picture

Status: Needs review » Reviewed & tested by the community

This looks ready for me, re-reviewed the patch and it is RTBC again IMHO.

Also setting to RTBC to get core committer feedback per 'changes' policy as there is nothing that can be done in the mean time here.

tstoeckler’s picture

Status: Reviewed & tested by the community » Needs review
  1. +++ b/core/modules/help/src/Controller/HelpController.php
    @@ -144,5 +220,4 @@ public function helpPage($name) {
    -
    

    This should not be removed.

  2. +++ b/core/modules/help/src/Tests/HelpTest.php
    @@ -16,15 +16,16 @@
    +  // Install with the standard profile, because it has the help block
    +  // enabled and admin theme, etc.
    +  protected $profile = 'standard';
    ...
    -  protected $profile = 'standard';
    

    It also has ~20 or so other modules, which are not at all needed for this test and are a drain for performance. How hard is it really to make this work without standard profile? There is WebTestBase::drupalPlaceBlock() and setting the admin theme should be as easy as setting the correct configuration value.

  3. Setting back to "needs review" for that to get some feedback.

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
4.4 KB
66.92 KB

RE #109...

First comment, OK, sorry, wasn't aware of that standard.

Second comment: Using the standard profile in this test was introduced by this issue's patch. All this patch does is add a better comment explaining why exactly it is being used, and move the line that was already there up a few lines.... So yes, I agree that it should not really be using standard profile, but filing this as a separate issue rather than killing even more kittens by trying to fix every problem in the Help module in this one patch: #2368277: HelpTest should not use standard profile (postponed until this one is resolved one way or another; this issue is marked as "related" on that other one so we don't need to add it as "related" here).

So here's an interdiff to take care of the blank line issues for all the classes in Help module. Setting back to RTBC since this is a trivial all-whitespace change.

tstoeckler’s picture

Oops, I totally missed that. Yes, of course, in that case that's not to be fixed here.

alexpott’s picture

Category: Task » Feature request
Status: Reviewed & tested by the community » Needs work

The key thing to resolve on this issue is are we going to do it. I'm ambivalent - I don't think the help system is super critical API so having a bit of flux here at this point does not seem that risky but it is risky. Also I think this issue should be classified as what it is - which is feature - editable and deployable help is totally new functionality. I like most of the patch - I'm not super convinced about the manual entry of dependencies in a form field with 0 validation though.

+++ b/core/modules/help/src/Entity/HelpTopic.php
@@ -0,0 +1,230 @@
+  /**
+   * {@inheritdoc}
+   */
...
+    $array = $this->getEnforcedDependencies();
+    foreach ($array as $type => $values) {
+      $array[$type] = $type . ': ' . implode(', ', $values);
+    }
+    return implode('; ', $array);

+++ b/core/modules/help/src/HelpTopicInterface.php
@@ -0,0 +1,108 @@
+  /**
+   * Returns the list of enforced dependencies as a string.
+   *
+   * @return string
+   *   List of enforced entity, module, and theme dependencies; see
+   *   \Drupal\Core\Config\Entity\ConfigDependencyManager for more information.
+   *   Format of string:
+   *   'entity: entity1; module: module1, module2; theme: theme1, theme2'.
+   */
...
+
+  /**
...
+   *
+   * @param array|string $dependencies
+   *   List of enforced entity, module, and theme dependencies to set; see
+   *   \Drupal\Core\Config\Entity\ConfigDependencyManager for more information.
+   *   Can be provided in a string in a format like:
+   *   'entity: entity1; module: module1, module2; theme: theme1, theme2'.
+   *
+   * @return $this
+   */
+  public function setEnforcedDependencies($dependencies);

The mangling part of this functionality really belongs on the form. It is not part of the business logic of a HelpTopic. getEnforcedDependenciesString() should move there and it would be nice if it was called convertEnforcedDependenciesToString(). The setter should be broken into two - the text mangling bit should be on the form and a new setter that accepts an array of dependencies should be on the ConfigEntity.

+++ b/core/modules/help/src/Tests/HelpTopicTokensTest.php
@@ -0,0 +1,53 @@
+    $text = 'This should <a href="[help_topic:nonexistant]">Not link to help topic</a>';
...
+    $this->assertTrue(strpos($replaced, '[help_topic:nonexistant]') !== FALSE);

+++ b/core/modules/system/src/Tests/Token/RouteTokensTest.php
@@ -0,0 +1,51 @@
+    $text = 'This should <a href="[route:system.nonexistant]">Not link to admin</a>';
...
+    $this->assertTrue(strpos($replaced, '[route:system.nonexistant]') !== FALSE);

Minor nit - it's nonexistent

jhodgdon’s picture

Version: 8.0.x-dev » 8.1.x-dev

Well if we classify this as a feature request then we must postpone it to 8.1.x or later. Which is disappointing, since I really do think this is a good system and also fills a need, but fair... it just simply came too late.

So, I'm not going to bother working on a new patch right now. Good comments in #112 though, thanks!

If we did want to have this as a contrib module in the meantime, there are some parts we would need to break out of this patch since they are not in the Help entity itself, but a contrib module would not work without these changes:

a) core/lib/Drupal/Core/ParamConverter/AdminPathConfigEntityConverter.php -- a change to allow admin routes to have use_current_language parameter that makes the config entity get translated on output

b) core/modules/system/src/Tests/Token/RouteTokensTest.php and core/modules/system/system.tokens.inc -- token "route" that outputs the correct URL for a route.

I have no idea whether either of these changes would be considered to be less feature-like... (b) could be added in the contrib module but not (a), and that would block any possibility of this working as a contrib module.

Any thoughts on that?

But... I'm not really all that inclined to go the contrib module route on this one. I don't think it's worth making another contrib module alternate help system. If it is not in Core then contrib modules would need to do their help twice to support both the existing core hook_help() and this new system, and that's extra work they're unlikely to want to do. There is no guarantee we'd even get this into 8.1.x either, and who knows when we'll actually get 8.0.x out the door, much less 8.1.x.

So... Let's just leave this as 8.1.x. and see what happens a few months/years down the road. Thanks for all the help from everyone who worked on this! Sorry it didn't work out yet. :((((((((

jhodgdon’s picture

I also just want to say that I really really really really wish that when I originally discussed this in IRC with alexpott in early October, or in an early comment, I would have known then that it was too late rather than spending a month trying to get this done. I feel like I was told then that it might be possible when it was really not ever going to be, and that led to me wasting a very large amount of time that I could have spent fixing issues that could have gone somewhere. I don't entirely disagree with the decision but I wish it had been made much sooner instead of being made today.

yukare’s picture

I think since it will only change how help works and will not break anything else it could be done now. Just a question, as i see it will support both ways, no? hook_help still works after this ? If so i really think we can make it for 8.0.

jhodgdon’s picture

No, it wouldn't break anything. But this issue has been classified by the core committers as a feature request, and that decision is reasonable. Therefore it is not allowed to proceed at this point. The policy is here: #2350615: [policy, no patch] What changes can be accepted during the Drupal 8 beta phase?.

So... Unless it is no longer classified as a feature request, that is the end of the discussion, because the policy is very clear that feature requests are not allowed at this point. My only annoyance is that it would have been nice to know that this would happen a month ago when I discussed this in IRC and specifically asked if it was too late. But these things happen.

Fabianx’s picture

Assigned: jhodgdon » alexpott

#112: Why did you change your opinion on what we originally discussed in IRC?

It seemed to be feasible for 8.0.x at that time as a task that removes brittleness and increases consistency? (which would be fine to go in per policy)

This could be seen as follow-up to CMI (critical task), FWIW.

alexpott’s picture

I have changed my opinion because looking at the scope of the patch - a new config entity and a new UI for editing help - this can only be called a feature. I should have said this immediately and that is my mistake. I can not honestly say that this is a followup to CMI since help was not config in D7. And as for brittleness - why? Consistency - yeah maybe.

If we don't label this a feature then we are asking for trouble because people will point to this patch and say "Hey why can't Feature X go in now? That was a feature but you jimmied it under the cloak of being a task".

As I said I like the patch but being honest with our issue categories is important.

catch’s picture

Main question I have with this issue is what happens if a module updates their default help config entity? CMI currently has no interest in updated default configuration so if a site doesn't edit the default config, it also won't get any updates either (unless the module author explicitly adds an update to change it, but that risks changing something that's been edited).

jhodgdon’s picture

Issue summary: View changes

@alexpott: You are completely right. This is a feature, and it's too late. No worries! We all should have thought of that a month ago, and we didn't. Oh well, these things happen.

@catch: Good question in #119. I will add that to the issue summary, since even if this becomes a contrib module the aspect of modules updating their config will need to be addressed.

Anyway... I've just updated the issue summary with a list of the outstanding concerns and the present status. I'll think seriously again about making this into a contrib module in the next few weeks... It would sure be helpful for site builders and certain contrib modules, and the Docs Working Group may also be thinking about using this to build a translatable basic User Manual for Drupal 8, which we've been needing forever.

alexpott’s picture

re #113

(a) This feels like a bug (and it is giving me deja-vu) and should be able to go in
(b) Can't the contrib module provide the token using the token hooks?

The issue catch raises in #119 is a very good point - off the top of my head I'm not sure how to tackle this.

jhodgdon’s picture

Yes, the contrib module could provide this token. It's not really related directly to the help topic entities but as I tried to say in #113 (b), there is no technical reason it cannot go there. I forgot to add that to the issue summary, so doing that now.

I also filed a separate issue for #113 (a), which I forgot about again (thanks for the reminder): #2369035: Config entities should not always be untranslated in admin routes

And I don't know how to resolve the config changes issue either. It's already in the issue summary... but yeah, good question.

andypost’s picture

I'm sure that his issue should get split info token and help entity to properly land to 8.1
@jhodgdon, please create a sandbox for the code (current patch)

I think the proper module name is help_content
PS: willing to help maintain it

jhodgdon’s picture

@andypost - great! A co-maintainer would be lovely.

Making a sandbox will take some work, because the current patch is for the core Help module and other Core files. But it won't take too long... I don't have time today but will set it up later this week if possible. I don't think it really needs to be split up into the tokens and entity separately, though -- the token part is small and the entity has a token too (for links to the help entities), so ... I think it's best just to put both into the same module as the entity. You really will need those tokens for most help topics.

So right now the main blocker to even having a viable contrib module is #2369035: Config entities should not always be untranslated in admin routes. If someone wants to make a viable patch there (take the bits out of the patch here), that would be great! It will most likely need a test though, which will take some work... this help entity made a good test of that behavior but... probably something simpler can be devised? I hope.

jhodgdon’s picture

Assigned: alexpott » jhodgdon

Assigning this back to me, as next steps are mine.

Fabianx’s picture

#119: But that is a _general_ problem with CMI and module updates (and also in Linux distributions e.g.). Is there an issue for that I can follow?

My own feeling was that when config is saved, the config key changes and the module that provides it is custom. In that case the worst that happens on a CMI "revert" is an additional help page, but I feel this is a larger CMI problem as stated already.

alexpott’s picture

re #126 I'm not sure I agree at all. For example, help text is different to a view. A help topic is intimately coupled with the code and functionality that the module provides than other configuration. In fact I would argue that it is an important feature of CMI that all configuration is owned by the site and not the module. In Drupal 7, if a module provided a default view and this was used by site without any customisations and provided what the site needed, then, what right does a module author have to add new functionality automatically to that view due to a module update? It did because the default view was defined in code. If the site owner customised just one thing on the view then it was moved to the database and the module update would do nothing. This type of behaviour is very inconsistent and confusing - let alone the fact now that the revert button on the views UI would now not revert the view to previous state as it was before the site owner customised it but a completely new never-seen-on-that-site before state.

Fabianx’s picture

Oh, I am not opposed to that in any way. If it came across that way, I am sorry. In fact I try to support both modes of operation active / passive in my sandbox contrib project.

However I think there is valid use cases both the help tops and views for a legitimate update:

After all if the code uses an views_embed_view() with a new argument that is not available in the old view, then the view is also tightly coupled to the code.

So both for help topics and that view, there needs to be some way to decide whether to:

- revert to the maintainers version
- keep their own changes
- view a diff

( same as in Ubuntu / Debian for example )

And also appropriate API functions in hook_update_N() for a site owner to decide to revert some configuration, etc.

I don't know enough about CMI at this point to know if anything like that is implemented already (and I assume there is), but something like that is needed to re-sync data from a module.

jhodgdon’s picture

I can think of a couple of approaches to the problem of "Module updates its help topic":

a) We could define a standard functions they could call from a hook_update_N() like help_topic_updated($id) and help_topic_added($id). These functions would somehow check to see if the user had ever edited the help topic for updated (possibly we'd add something to the config entity to detect this?), and see if a topic with that ID exists for additions, and then do something like this:
- Updates - If no edits had taken place, update by reading the new config from (module)/config/install
- Updates - If edits had taken place, tell the user a new version is available and let them act.
- Updates - if the topic doesn't exist, the user must have deleted it and leave it alone
- Additions - if there is a topic with the same ID, warn the user and let them act.

That would require a module maintainer to define a hook_update_N() and call these functions, but that probably isn't too much of a burden. We'd also have to add some stuff to the UI like "Show differences between this currently configured help topic and the shipped version" and "Reset this topic to the version that came shipped". And we'd have to have one or more flags on help topics to indicate whether they were shipped config and/or had been edited since then.

b) The help topic module could have a hook_modules_updated() or whatever it's called, which would compare the (module)/config/install topics to ones that are currently in the config system and warn the user if there are differences (updates, deletions, additions), whenever updates were being performed.

c) We could also implement hook_modules_updated() and just generically put out a message that warns the user when any updates are done that help topics are not updated or imported and let them figure it out with this hypothetical UI.

d) We could do nothing, on the assumption that help topics are site configuration and you don't need the updates.

I'm not sure which of these is the most feasible or which is best... or is there another idea that would be better? Or do you think it was stupid to consider making help topics be configuration at all? I think having them editable is a really good feature; on the other hand, it does definitely complicate the "acting as a manual for an extension" feature. Probably not in an insurmountable way though.

jhodgdon’s picture

I've made a preliminary commit to making this a contrib module in a new sandbox project at:
https://www.drupal.org/sandbox/jhodgdon/2369943

I haven't tested it yet... it will not work right without the patch for #2369035: Config entities should not always be untranslated in admin routes at a minimum. It is also quite likely that I messed some things up when I tried to make everything have the module shortname "config_help" instead of "help", so I expect it won't work yet. I'll work on it more tomorrow.

ALSO you need to uninstall the core Help module before installing the sandbox/contrib module! It defines some routes for the same paths. Anyway... don't try it yet I'm sure it's broken!

Tomorrow I'll also make the To Dos into issues on the new sandbox project and also probably move some of the child issues over there.

jhodgdon’s picture

OK. I got the sandbox module working! At least the tests pass. See #2371443: [Meta] To Do list for Configurable Help for the To Do list, or just look at the issue list for this module:
https://www.drupal.org/project/issues/2369943
I moved several of the "related" issues over to that project so we can work on them there.

The module is at https://www.drupal.org/sandbox/jhodgdon/2369943

You'll need the Core patch to #2369035: Config entities should not always be untranslated in admin routes installed, and at least right now, this is a drop-in replacement for the core Help module so you cannot run the core Help module at the same time.

jhodgdon’s picture

Update on the contrib module for this:

I've been working on this module for a while. It's now a separate module that depends on Core Help instead of a drop-in replacement, and I've fixed most of the issues that were identified here, as well as a few more that I came up with. I'm pretty happy with it now, and will probably turn it into a Real Project sometime soon.

The only missing piece that I know of is around what to do when a module updates a topic -- now issue #2371439: Figure out what to do when module updates configurable topic -- which was brought up by @catch above around comment #119 and discussed a bit in later comments. I think I've identified an approach for resolving this issue, and I'll be working on it. Incidentally the core Tour module needs this same functionality; see #1924202: Tour tips are provided as configuration, so never get updated... at least, I think that is what that issue is about, and if not they probably need a new issue for this problem.

Anyway... If anyone wants to try out the module, it's now named "Configurable Help", it's at https://www.drupal.org/sandbox/jhodgdon/2369943 , and your module directory should be called "config_help". It seems to be working well and all of its tests pass. The issue queue for the module is currently a nice sea of green aside from two postponed issues and the "what to do about updates" issue mentioned here. I'd love it if people tested the module and filed more issues. Well. I'd at least feel more confident. :)

Thanks!

cilefen’s picture

Issue tags: -beta target

I removed the "beta target" tag because this is pushed to 8.1.x.

jhodgdon’s picture

I've filed a new meta issue to collect all the problems with the current help system and discuss the best route to fixing them; this issue is being added as Related there:
#2592487: [meta] Help system overhaul

jhodgdon’s picture

I'm thinking about reviving this for 8.1.x, and I guess now would be the time...

I think now that we should leave the About sections of the existing hook_help() as they are, and make the Uses sections into a configurable topic outline that would be organized by topic (how to do things) rather than by module as it is now.

So if you go to the Help page, you'd have 3 sections: the module overview pages from hook_help(), the topics outline (which users could add more pages to, rearrange, edit, etc.), and a list of Tours as well.

Speaking of which, I don't think we ended up ever figuring out what we needed Tours for in core and making those tours... we should do that too.

jhodgdon’s picture

I've spun off part of this to #2661200: Make admin/help page more flexible, and list tours on it and will work on that first.

jhodgdon’s picture

Title: Replace hook_help() topic pages with config entities » Add a config entity for a configurable, topic-based help system
Issue summary: View changes
Status: Needs work » Postponed

Updating the issue summary and title, as my current plan is not to get rid of the module-level help in hook_help(), after discussion this with @alexpott a few days ago. I also discussed this with @webchick in IRC today... Anyway, I'm planning to go forward with making a patch for this sometime soon. However, it will depend on #2661200: Make admin/help page more flexible, and list tours on it getting done (which allows for modules to place sections on the admin/help page). And I think I will make the configurable help be a separate module.

I also cleaned out a bunch of obsolete stuff that was already fixed from the issue summary.

So while I work on getting the patch for #2661200: Make admin/help page more flexible, and list tours on it refined, I'll be working on the configurable help system, and some topics for it, in the sandbox project https://www.drupal.org/sandbox/jhodgdon/2369943 and its issue queue. I should have a patch here shortly after that one converges towards RTBC.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Wim Leers’s picture

jhodgdon’s picture

OK, I'll get back on this!

Right now my sandbox module mostly needs (a) some unit tests and (b) some topics to ship with... If anyone wants to help, the issue queue for the sandbox is:
https://www.drupal.org/project/issues/2369943?categories=All

I haven't tested it lately against 8.2.x, but that would be another good step. It should be OK, as it was assuming the patch for that other issue got in, in the latest iteration. There are existing tests so if they all pass then that would be a good sign that the module is working.

alexpott’s picture

BTW I'm still not convinced that help supplied by modules should be configurable. I think there is very with being able to add additional help and have that displayed through the help system. It is one thing being able to add and remove help but being able to change the help supplied by modules feels like a step too far.

jhodgdon’s picture

I know what you're saying, but as someone who used to build sites for clients, I also know that it would have been very helpful to be able to pick and choose topics from those provided by Core, and add my own, to build a help system for my clients. At least being able to edit the "outline" would be necessary for that, and ideally, you'd want to also be able to edit the core topics (for instance, you might be using a contrib module that modifies some workflow).

andypost’s picture

When help was a string... it was overridable with string overrides.
Now we need to keep ability to override core's shipped help
So ++

jhodgdon’s picture

One thing that we could do is to have a field in these config objects that indicates "This was provided by a module/theme". If this flag was set, we could do one or more of the following:
- Require a more restrictive permission to edit the topic [I think this is a bad idea]
- Display a message about the dangers of editing the topic [I think this is a reasonable idea].

To me, this is not much different from allowing people to delete/edit the default views that come with a module, even though if they screw them up somehow or delete a display that the module is expecting will exist, possibly the admin or user-facing functionality of the module may not work.

Anyway, I've filed an issue in my sandbox to discuss this:
#2687787: Provide a method for locking topics against editing

jhodgdon’s picture

Status: Active » Needs review
FileSize
125.84 KB

Well, I think my sandbox is in pretty good shape, so I redid it as a Core patch. It's kind of large... and it's quite different from the patch in #110, so I didn't think an interdiff would be helpful...

Short roadmap:

a) There's a new plugin type called TextSection, which I put into core/lib/Drupal/Core/Render (also it has an annotation class, and a plugin manager/service, and a render element in the TextSections class). This allows you to take a large piece of HTML-formatted text, and abstract it slightly to "sections", where a section could be a paragraph, header, sub-header, bullet list item, etc.

b) There's a new module called config_help, which defines a config_help config entity for help topics, provides a UI for editing them, and lists them in a new section on the admin/help page.

c) To avoid having very large pieces of HTML-formatted text in the body of the help topic config entities, which is bad for translation, they're made up of TextSection items instead. However, the config entity and its schema don't really need to know about TextSection plugins -- the help topic YML body looks something like this:

body:
  -
    type: paragraph
    text:
      value: 'Follow these steps to build a help system for different types/roles of users on your system to use:'
      format: help_plain
  -
    type: numbered
    text:
      value: 'Plan your help system: make a list of the topics each type/role of user would benefit from.'
      format: help_plain

(etc)

d) To start with, I only defined help topics for the config_help module itself, although I've started writing some additional topics in my sandbox project. I think that the initial patch should just do this much for topics, and then we can do more topics on a child issue.

e) There are tests! One Kernel test for the TextSection stuff, and 4 web tests for the help topic stuff.

Status: Needs review » Needs work

The last submitted patch, 145: 2351991-145.patch, failed testing.

jhodgdon’s picture

Status: Needs work » Active

Looks like I need a Composer entry for the new module, and the other test failure seems to be a bot problem.

Anyway... I'm actually thinking I should split the new render stuff off into a child issue and get that done separately first, and then once again come back here with the rest. I think that will make it all more understandable and reviewable. So... here is:
#2697791: Add Plugin system for abstracted HTML-formatted text
and I'll split that part of the patch off there, and postpone this one again...

jhodgdon’s picture

Status: Active » Postponed

I'm postponing this issue again. On #2697791: Add Plugin system for abstracted HTML-formatted text, a suggestion was made that instead of the plugin system for the body of the help topics, it might be better to use a markdown system instead. This is being discussed on #2698035: Add markdown system for HTML-formatted text. Until one or the other is decided on, this issue cannot proceed.

miro_dietiker’s picture

What confuses me here is that i would immediately say a user provided help should be much more content than config.
And it feels like we are abusing the config system for help, because it supports export / import.
(I would have expected that people complain this is not a valid architectural argument to use config for it.)

I don't know about the transport of config help you had in mind.
If the goal is to use our issue queue to provide / update help in modules, we need diffs against the previous dev.
If we would use a content entity to build help, and enable revisioning, we could build/export a diff against the originally imported revision with limited complexity.
@jhodgdon How did you plan to trade those things?

jhodgdon’s picture

Well, the idea here is for modules, themes, and install profiles to provide help, too. I see what you are saying about it being content -- and it's been brought up before. But if extensions are providing it, making it configuration means that we don't have to:
- Think up a new way to provide things in extensions (config entities already do that)
- Think up a new way for the POTX packages to find translatable strings (config entities are already picked up by POTX so they are translatable on localize.drupal.org)
- Think up a new way to combine the things that are provided by extensions and things that are provided by users (config entities already do that)

This is why I built it as config entities.

Regarding diffs, see this contrib module:
https://www.drupal.org/project/config_update
This is also a problem with views that are provided by core modules vs. views created by users.

jhodgdon’s picture

Status: Postponed » Closed (won't fix)

After more than two years of trying to get this system into Core, I am giving up now. I will continue working on it in Contrib, possibly, but I think this is too controversial to ever make it into Core, and I am tired of begging people to get patches reviewed.

Thanks to everyone who did offer constructive suggestions, though! Much appreciated. The contrib module (if I release it as contrib) will be much better due to your help.

jhodgdon’s picture

Oh, and if anyone is interested in co-maintaining the Configurable Help contrib module, contact me in the issue queue there (links to the current sandbox are in the issue summary).

jhodgdon’s picture

For anyone still following this closed issue...

I have restarted this initiative. There are two main issues:
#2592487: [meta] Help system overhaul is in the Ideas queue. Currently it is a Proposed Plan. We are waiting for sign-off from Product and Release managers to make it an official Community Initiative.

Meanwhile, #2920309: Add experimental module for Help Topics is working on a Core patch (probably premature but oh well). We're doing this by filing individual issues in the Sandbox module, so that we have a way to discuss individual changes to the Core patch. Here's the issue queue:
https://www.drupal.org/project/issues/2369943

If you'd like to officially be part of the team for this initiative, please go comment on the Ideas queue issue, and/or jump in and review patches on Sandbox issues. Meanwhile, I've gone through this issue and compiled a list of people who helped here with patches/reviews/tests and hopefully everyone will get credited if we actually get this into Core. Thanks!!