Commit 992f677a authored by Gábor Hojtsy's avatar Gábor Hojtsy

Issue #2920309 by jhodgdon, Amber Himes Matz, alexpott, larowlan, andypost,...

Issue #2920309 by jhodgdon, Amber Himes Matz, alexpott, larowlan, andypost, vadim.hirbu, effulgentsia, diqidoq, jibran, webchick, catch, xjm, jhedstrom, Gábor Hojtsy, dawehner, Berdir, tim.plunkett, benjifisher, markcarver, yoroy, ckrina, amateescu, gnuget, webflo, Greg Boggs, yo30, vijaycs85, SenthilMohith, andrewmacpherson, EclipseGc, sandboxpl, MariaDenysyuk, tstoeckler, miro_dietiker, Mixologic, RoloDMonkey, timmillwood, Fabianx: Add experimental module for Help Topics
parent 8f430db9
......@@ -231,6 +231,10 @@ Hypertext Application Language (HAL)
Help
- ?
Help Topics
- Amber Matz 'Amber Himes Matz' https://www.drupal.org/u/amber-himes-matz
- Andrey Postnikov 'andypost' https://www.drupal.org/u/andypost
Image
- Claudiu Cristea 'claudiu.cristea' https://www.drupal.org/u/claudiu.cristea
......
......@@ -128,6 +128,7 @@
"drupal/forum": "self.version",
"drupal/hal": "self.version",
"drupal/help": "self.version",
"drupal/help_topics": "self.version",
"drupal/history": "self.version",
"drupal/image": "self.version",
"drupal/inline_form_errors": "self.version",
......
<?php
/**
* @file
* Hooks provided by the Help Topics module.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Perform alterations on help topic definitions.
*
* @param array $info
* Array of help topic plugin definitions keyed by their plugin ID.
*/
function hook_help_topics_info_alter(array &$info) {
// Alter the help topic to be displayed on admin/help.
$info['example.help_topic']['top_level'] = TRUE;
}
/**
* @} End of "addtogroup hooks".
*/
name: Help Topics
type: module
description: 'Displays help topics provided by themes and modules.'
core: 8.x
package: Core (Experimental)
version: VERSION
dependencies:
- drupal:help
<?php
/**
* @file
* Displays help topics provided by modules and themes.
*/
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
/**
* Implements hook_help().
*/
function help_topics_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.help_topics':
$help_home = Url::fromRoute('help.main')->toString();
$locale_help = (\Drupal::moduleHandler()->moduleExists('locale')) ? Url::fromRoute('help.page', ['name' => 'locale'])->toString() : '#';
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Help Topics module adds module- and theme-provided help topics to the module overviews from the core Help module. For more information, see the <a href=":online">online documentation for the Help Topics module</a>.', [':online' => 'https://www.drupal.org/modules/help_topics']) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Viewing help topics') . '</dt>';
$output .= '<dd>' . t('The top-level help topics are listed on the main <a href=":help_page">Help page</a>. Links to other topics, including non-top-level help topics, can be found under the "Related" heading when viewing a topic page.', [':help_page' => $help_home]) . '</dd>';
$output .= '<dt>' . t('Providing help topics') . '</dt>';
$output .= '<dd>' . t("Modules and themes can provide help topics as Twig-file-based plugins in a project sub-directory called <em>help_topics</em>; plugin meta-data is provided in meta tags within each Twig file. Plugin-based help topics provided by modules and themes will automatically be updated when a module or theme is updated. Use the plugins in <em>core/modules/help_topics/help_topics</em> as a guide when writing and formatting a help topic plugin for your theme or module.") . '</dd>';
$output .= '<dt>' . t('Translating help topics') . '</dt>';
$output .= '<dd>' . t('The title and body text of help topics provided by contributed modules and themes are translatable using the <a href=":locale_help">Interface Translation module</a>. Topics provided by custom modules and themes are also translatable if they have been viewed at least once in a non-English language, which triggers putting their translatable text into the translation database.', [':locale_help' => $locale_help]) . '</dd>';
$output .= '</dl>';
return ['#markup' => $output];
case 'help_topics.help_topic':
$help_home = Url::fromRoute('help.main')->toString();
return '<p>' . t('See the <a href=":help_page">Help page</a> for more topics.', [
':help_page' => $help_home,
]) . '</p>';
}
}
/**
* Implements hook_theme().
*/
function help_topics_theme() {
return [
'help_topic' => [
'variables' => [
'body' => [],
'related' => [],
],
],
];
}
help_topics.help_topic:
path: '/admin/help/topic/{id}'
defaults:
_controller: '\Drupal\help_topics\Controller\HelpTopicPluginController::viewHelpTopic'
requirements:
_permission: 'access administration pages'
services:
help_topics.breadcrumb:
class: Drupal\help_topics\HelpBreadcrumbBuilder
arguments: ['@string_translation']
tags:
- { name: breadcrumb_builder, priority: 900 }
public: false
plugin.manager.help_topic:
class: Drupal\help_topics\HelpTopicPluginManager
arguments: ['@module_handler', '@theme_handler', '@cache.discovery']
help_topics.twig.loader:
class: Drupal\help_topics\HelpTopicTwigLoader
arguments: ['@app.root', '@module_handler', '@theme_handler']
# Lowest core priority because loading help topics is not the usual case.
tags:
- { name: twig.loader, priority: -200 }
public: false
<meta name="help_topic:label" content="Changing basic site settings"/>
<meta name="help_topic:top_level"/>
<meta name="help_topic:related" content="user.security_account_settings"/>
{% set regional_url = render_var(url('system.regional_settings')) %}
{% set information_url = render_var(url('system.site_information_settings')) %}
{% set datetime_url = render_var(url('entity.date_format.collection')) %}
<p>{% trans %}The settings for your site are configured on various administrative pages, as follows:{% endtrans %}</p>
<dl>
<dt>{% trans %}Site name, slogan, and email address{% endtrans %}</dt>
<dd>{% trans %}On the <a href="{{ information_url }}"><em>Basic site settings</em></a> page, which you can reach in the main <em>Manage</em> administrative menu, by navigating to <em>Configuration</em> &gt; <em>System</em> &gt; <em>Basic site settings</em>.{% endtrans %}</dd>
<dt>{% trans %}Time zone and country{% endtrans %}</dt>
<dd>{% trans %}On the <a href="{{ regional_url }}"><em>Regional settings</em></a> page, which you can reach in the main <em>Manage</em> administrative menu, by navigating to <em>Configuration</em> &gt; <em>Regional and language</em> &gt; <em>Regional settings</em>.{% endtrans %}</dd>
<dt>{% trans %}Date and time formats{% endtrans %}</dt>
<dd>{% trans %}On the <a href="{{ datetime_url }}"><em>Date and time formats</em></a> page, which you can reach in the main <em>Manage</em> administrative menu, by navigating to <em>Configuration</em> &gt; <em>Regional and language</em> &gt; <em>Date and time formats</em>.{% endtrans %}</dd>
</dl>
<meta name="help_topic:label" content="Configuring error responses, including 403/404 pages"/>
<meta name="help_topic:related" content="core.config_basic,core.maintenance"/>
{% set log_settings_url = render_var(url('system.logging_settings')) %}
{% set site_settings_url = render_var(url('system.site_information_settings')) %}
<h2>{% trans %}Configuring 403/404 pages{% endtrans %}</h2>
<p>{% trans %}The core software provides default responses for 403 response (Not Authorized: when someone tries to visit a page they do not have permission to see) and 404 response (Not Found: when someone tries to visit a page that does not exist). You can change what page is displayed for these responses on the <a href="{{ site_settings_url }}"><em>Basic site settings</em></a> page, which you can reach in the main <em>Manage</em> administrative menu, by navigating to <em>Configuration</em> &gt; <em>System</em> &gt; <em>Basic site settings</em>. Note that the pages you want to use must already exist as either system-provided pages or content that you have created.{% endtrans %}</p>
<h2>{% trans %}Responding to software errors{% endtrans %}</h2>
<p>{% trans %}Software errors on your site are logged, if you have a logging module installed (such as the core Database Logging module or the core Syslog module). You can configure whether or not error messages are also shown (to both administrators and other site visitors) on the <a href="{{ log_settings_url }}"><em>Logging and errors</em></a> configuration page, which you can reach in the main <em>Manage</em> administrative menu, by navigating to <em>Configuration</em> &gt; <em>Development</em> &gt; <em>Logging and errors</em>.{% endtrans %}</p>
<h2>{% trans %}Viewing the site log{% endtrans %}</h2>
<p>{% trans %}If you have the core Database Logging module installed, you can view recent error and informational messages by navigating in the main <em>Manage</em> administrative menu to <em>Reports</em> &gt; <em>Recent log messages</em>. If you are using the core Syslog module for logging, error messages will be logged in your web server''s log files.{% endtrans %}</p>
<meta name="help_topic:label" content="Maintaining and troubleshooting your site"/>
<meta name="help_topic:top_level"/>
<p>{% trans %}The related topics listed here will help you keep your site running and troubleshoot problems.{% endtrans %}</p>
<meta name="help_topic:label" content="Defining navigation and URLs"/>
<meta name="help_topic:top_level"/>
<p>{% trans %}The related topics listed here describe how to set up various aspects of site navigation and URLs.{% endtrans %}</p>
<meta name="help_topic:label" content="Making your site secure"/>
<meta name="help_topic:top_level"/>
<meta name="help_topic:related" content="menu_ui.menu_overview"/>
<p>{% trans %}The topics listed here will help you make and keep your site secure.{% endtrans %}</p>
<meta name="help_topic:label" content="Accessibility features"/>
<meta name="help_topic:related" content="core.ui_components"/>
<p>{% trans %}The following features of the administrative user interface may help administrative users with disabilities access your site:{% endtrans %}</p>
<dl>
<dt>{% trans %}Disabling drag-and-drop functionality{% endtrans %}</dt>
<dd>{% trans %}The default drag-and-drop user interface for ordering tables in the administrative interface presents a challenge for some users, including users of screen readers and other assistive technology. The drag-and-drop interface can be disabled in a table by clicking a link labeled <em>Show row weights</em> above the table. The replacement interface allows users to order the table by choosing numerical weights instead of dragging table rows.{% endtrans %}</dd>
</dl>
<meta name="help_topic:label" content="Using the administrative interface"/>
<meta name="help_topic:top_level"/>
<p>{% trans %}The related topics listed here describe various aspects of the administrative interface, and tell how to use them.{% endtrans %}</p>
<meta name="help_topic:label" content="Contextual links"/>
<meta name="help_topic:related" content="core.ui_components"/>
<h2>{% trans %}What are contextual links?{% endtrans %}</h2>
<p>{% trans %}<em>Contextual links</em> give users with the <em>Use contextual links</em> permission quick access to administrative tasks related to areas of non-administrative pages. For example, if a page on your site displays a block, the block would have a contextual link that would allow users with permission to configure the block. If the block contains a menu or a view, it would also have a contextual link for editing the menu links or the view. Clicking a contextual link takes you to the related administrative page directly, without needing to navigate through the administrative menu system.{% endtrans %}</p>
<h2>{% trans %}Displaying and using contextual links{% endtrans %}</h2>
<p>{% trans %}If you have the core Contextual Links module installed, the contextual links related to an area on a page can be displayed by clicking the contextual links button in that area of the page. In most themes, this button looks like a pencil and is placed in the upper right corner of the page area (upper left for right-to-left languages); however, contextual links buttons are normally hidden. Here are two ways to make contextual links buttons visible:{% endtrans %}</p>
<ul>
<li>{% trans %}Hovering your mouse over an area on the page will temporarily make the contextual links button visible, if there is one for that area of the page. Also, in most themes, the page area that the contextual links pertain to will be outlined while you are hovering.{% endtrans %}</li>
<li>{% trans %}If you have the core Toolbar module enabled, there will be a contextual links toggle button at the far right end of the toolbar (far left end for right-to-left languages; this button looks like a pencil in most themes). Clicking the toggle button will make all the individual contextual links buttons on the page visible; clicking the toggle button again will make them invisible.{% endtrans %}</li>
</ul>
<p>{% trans %}While the contextual links button for the area of interest is visible, click the button to display the list of links for that area. Click a link in the list to perform the task.{% endtrans %}</p>
<meta name="help_topic:label" content="Tours"/>
<meta name="help_topic:related" content="core.ui_components"/>
<h2>{% trans %}What are tours?{% endtrans %}</h2>
<p>{% trans %}The core Tour module provides users with <em>tours</em>, which are guided tours of the administrative interface. Each tour starts on a particular administrative page, and consists of one or more <em>tips</em> that highlight elements of the page, guide you through a workflow, or explain key concepts. Users need <em>Access tour</em> permission to view tours, and JavaScript must be enabled in their browsers.{% endtrans %}</p>
<h2>{% trans %}Viewing tours{% endtrans %}</h2>
<p>{% trans %}If a tour is available on a page, and you have the core Toolbar module installed, a <em>Tour</em> button will appear on the right end of the toolbar (left end for right-to-left languages). Click this button to view the first tip of the tour; click the <em>Next</em> button to advance to the next tip, and <em>End tour</em> at the end to close the tour.{% endtrans %}</p>
<meta name="help_topic:label" content="Writing good help"/>
<meta name="help_topic:top_level"/>
<p>{% trans %}Here are some suggestions for how to make your help topics as useful as possible for readers:{% endtrans %}</p>
<ul>
<li>{% trans %}Choose short titles. If the topic describes a task, start with a verb in -ing form, like "Writing good help".{% endtrans %}</li>
<li>{% trans %}Make your topics modular and short, using links to connect information together.{% endtrans %}</li>
<li>{% trans %}Use headings and lists to organize your topics.{% endtrans %}</li>
<li>{% trans %}Write in second person (you, your). When describing a task, use imperative mood (tell people directly what to do, such as "Enter information in the ABC field", rather than using words like "please" or more passive or declarative language like "the ABC field needs to be filled in").{% endtrans %}</li>
</ul>
<meta name="help_topic:label" content="Shortcuts"/>
<meta name="help_topic:related" content="core.ui_components"/>
<h2>{% trans %}What are shortcuts?{% endtrans %}</h2>
<p>{% trans %}<em>Shortcuts</em> are quick links to administrative pages; they are managed by the core Shortcut module. A site can have one or more <em>shortcut sets</em>, which can be shared by one or more users; each set contains one or more shortcuts. Users need <em>Use shortcuts</em> permission to view shortcuts; <em>Edit current shortcut set</em> permission to add, delete, or edit the shortcuts in the set assigned to them; and <em>Select any shortcut set</em> permission to select a different shortcut set when editing their user profile. There is also an <em>Administer shortcuts</em> permission, which allows an administrator to do any of these actions, and also permits assigning shortcut sets to other users.{% endtrans %}</p>
<h2>{% trans %}Creating and deleting shortcuts{% endtrans %}</h2>
<p>{% trans %}When viewing certain administrative pages, you will see a link that allows you to add the page to your current shortcut set. In the core Seven administrative theme, the link looks like a star, and is displayed next to the page title. If the page is already in your shortcut set, you will instead see a link that allows you to remove it.{% endtrans %}</p>
<h2>{% trans %}Viewing and using shortcuts{% endtrans %}</h2>
<p>{% trans %}If you have the core Toolbar module installed, click <em>Shortcuts</em> in the toolbar to display your shortcuts. Once they are displayed, click any link in the shortcut bar to go directly to the administrative page. If you are not using the Toolbar module, you can display shortcuts by placing the <em>Shortcuts</em> block in a region of your theme.{% endtrans %}</p>
<meta name="help_topic:label" content="Defining how user accounts are created"/>
<meta name="help_topic:related" content="core.security"/>
{% set account_settings_url = render_var(url('entity.user.admin_form')) %}
<p>{% trans %}On the <a href="{{ account_settings_url }}"><em>Account settings</em></a> page, which you can reach from the <em>Manage</em> administrative menu, by navigating to <em>Configuration</em> &gt; <em>People</em> &gt; <em>Account settings</em> (requires the <em>Administer account settings</em> permission), you can configure several settings related to how user accounts are created:{% endtrans %}</p>
<ul>
<li>{% trans %}You can make it possible for new users to register themselves, with or without administrator approval. Or, you can make it so only administrators with <em>Administer users</em> permission can register new users.{% endtrans %}</li>
<li>{% trans %}You can require email verification of new user accounts.{% endtrans %}</li>
<li>{% trans %}You can enable or disable a password strength indicator, which is shown whenever passwords are being set up or changed.{% endtrans %}</li>
<li>{% trans %}You can edit the email messages that are sent to users in conjunction with the user registration process.{% endtrans %}</li>
</ul>
<?php
namespace Drupal\help_topics\Controller;
use Drupal\Component\Utility\SortArray;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Drupal\help_topics\HelpTopicPluginManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Controller for help topic plugins.
*
* @internal
* Help Topic is currently experimental and should only be leveraged by
* experimental modules and development releases of contributed modules.
* See https://www.drupal.org/core/experimental for more information.
*/
class HelpTopicPluginController extends ControllerBase {
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* The Help Topic plugin manager.
*
* @var \Drupal\help_topics\HelpTopicPluginManagerInterface
*/
protected $helpTopicPluginManager;
/**
* Constructs a HelpTopicPluginController object.
*
* @param \Drupal\help_topics\HelpTopicPluginManagerInterface $help_topic_plugin_manager
* The help topic plugin manager service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
*/
public function __construct(HelpTopicPluginManagerInterface $help_topic_plugin_manager, RendererInterface $renderer) {
$this->helpTopicPluginManager = $help_topic_plugin_manager;
$this->renderer = $renderer;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('plugin.manager.help_topic'),
$container->get('renderer')
);
}
/**
* Displays a help topic page.
*
* @param string $id
* The plugin ID. Maps to the {id} placeholder in the
* help_topics.help_topic route.
*
* @return array
* A render array with the contents of a help topic page.
*/
public function viewHelpTopic($id) {
$build = [];
if (!$this->helpTopicPluginManager->hasDefinition($id)) {
throw new NotFoundHttpException();
}
/* @var \Drupal\help_topics\HelpTopicPluginInterface $help_topic */
$help_topic = $this->helpTopicPluginManager->createInstance($id);
$build['#body'] = $help_topic->getBody();
$this->renderer->addCacheableDependency($build, $help_topic);
// Build the related topics section, starting with the list this topic
// says are related.
$links = [];
$related = $help_topic->getRelated();
foreach ($related as $other_id) {
if ($other_id !== $id) {
/** @var \Drupal\help_topics\HelpTopicPluginInterface $topic */
$topic = $this->helpTopicPluginManager->createInstance($other_id);
$links[$other_id] = [
'title' => $topic->getLabel(),
'url' => Url::fromRoute('help_topics.help_topic', ['id' => $other_id]),
];
$this->renderer->addCacheableDependency($build, $topic);
}
}
if (count($links)) {
uasort($links, [SortArray::class, 'sortByTitleElement']);
$build['#related'] = [
'#theme' => 'links__related',
'#heading' => [
'text' => $this->t('Related topics'),
'level' => 'h2',
],
'#links' => $links,
];
}
$build['#theme'] = 'help_topic';
$build['#title'] = $help_topic->getLabel();
return $build;
}
}
<?php
namespace Drupal\help_topics;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
/**
* Provides a breadcrumb builder for help topic pages.
*
* @internal
* Help Topic is currently experimental and should only be leveraged by
* experimental modules and development releases of contributed modules.
* See https://www.drupal.org/core/experimental for more information.
*/
class HelpBreadcrumbBuilder implements BreadcrumbBuilderInterface {
use StringTranslationTrait;
/**
* Constructs the HelpBreadcrumbBuilder.
*
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The translation service.
*/
public function __construct(TranslationInterface $string_translation) {
$this->stringTranslation = $string_translation;
}
/**
* {@inheritdoc}
*/
public function applies(RouteMatchInterface $route_match) {
return $route_match->getRouteName() == 'help_topics.help_topic';
}
/**
* {@inheritdoc}
*/
public function build(RouteMatchInterface $route_match) {
$breadcrumb = new Breadcrumb();
$breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));
$breadcrumb->addLink(Link::createFromRoute($this->t('Administration'), 'system.admin'));
$breadcrumb->addLink(Link::createFromRoute($this->t('Help'), 'help.main'));
return $breadcrumb;
}
}
<?php
namespace Drupal\help_topics;
use Drupal\Component\Discovery\DiscoveryException;
use Drupal\Component\FileCache\FileCacheFactory;
use Drupal\Component\FileSystem\RegexDirectoryIterator;
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Discovers help topic plugins from Twig files in help_topics directories.
*
* @see \Drupal\help_topics\HelpTopicTwig
* @see \Drupal\help_topics\HelpTopicTwigLoader
*
* @internal
* Help Topic is currently experimental and should only be leveraged by
* experimental modules and development releases of contributed modules.
* See https://www.drupal.org/core/experimental for more information.
*/
class HelpTopicDiscovery implements DiscoveryInterface {
use DiscoveryTrait;
/**
* Defines the key in the discovered data where the file path is stored.
*/
const FILE_KEY = '_discovered_file_path';
/**
* An array of directories to scan, keyed by the provider.
*
* The value can either be a string or an array of strings. The string values
* should be the path of a directory to scan.
*
* @var array
*/
protected $directories = [];
/**
* Constructs a HelpTopicDiscovery object.
*
* @param array $directories
* An array of directories to scan, keyed by the provider. The value can
* either be a string or an array of strings. The string values should be
* the path of a directory to scan.
*/
public function __construct(array $directories) {
$this->directories = $directories;
}
/**
* {@inheritdoc}
*/
public function getDefinitions() {
$plugins = $this->findAll();
// Flatten definitions into what's expected from plugins.
$definitions = [];
foreach ($plugins as $list) {
foreach ($list as $id => $definition) {
$definitions[$id] = $definition;
}
}
return $definitions;
}
/**
* Returns an array of discoverable items.
*
* @return array
* An array of discovered data keyed by provider.
*
* @throws \Drupal\Component\Discovery\DiscoveryException
* Exception thrown if there is a problem during discovery.
*/
public function findAll() {
$all = [];
$files = $this->findFiles();
$file_cache = FileCacheFactory::get('help_topic_discovery:help_topics');
// Try to load from the file cache first.
foreach ($file_cache->getMultiple(array_keys($files)) as $file => $data) {
$all[$files[$file]][$data['id']] = $data;
unset($files[$file]);
}
// If there are files left that were not returned from the cache, load and
// parse them now. This list was flipped above and is keyed by filename.
if ($files) {
foreach ($files as $file => $provider) {
$plugin_id = substr(basename($file), 0, -10);
// The plugin ID begins with provider.
list($file_name_provider,) = explode('.', $plugin_id, 2);
// Only the Help Topics module can provider help for other extensions.
// @todo https://www.drupal.org/project/drupal/issues/3025577 Remove
// help_topics special case once Help Topics is stable and core
// modules can provide their own help topics.
if ($provider !== 'help_topics' && $provider !== $file_name_provider) {
throw new DiscoveryException("$file should begin with '$provider.'");
}
$data = [
// The plugin ID is derived from the filename. The extension
// '.html.twig' is removed
'id' => $plugin_id,
'provider' => $file_name_provider,
'class' => HelpTopicTwig::class,
static::FILE_KEY => $file,
];
// Get the rest of the plugin definition from meta tags contained in the
// help topic Twig file.
foreach (get_meta_tags($file) as $key => $value) {
$key = substr($key, 11);
switch ($key) {
case 'related':
$data[$key] = array_map('trim', explode(',', $value));
break;
case 'top_level':
$data[$key] = TRUE;
if ($value !== '') {
throw new DiscoveryException("$file contains invalid meta tag with name='help_topic:top_level', the 'content' property should not exist");
}
break;
case 'label':
$data[$key] = new TranslatableMarkup($value);
break;
default:
throw new DiscoveryException("$file contains invalid meta tag with name='$key'");
}
}
if (!isset($data['label'])) {
throw new DiscoveryException("$file does not contain the required meta tag with name='help_topic:label'");
}
$all[$provider][$data['id']] = $data;
$file_cache->set($file, $data);
}
}
return $all;
}
/**
* Returns an array of providers keyed by file path.
*
* @return array
* An array of providers keyed by file path.
*/
protected function findFiles() {
$file_list = [];
foreach ($this->directories as $provider => $directories) {
$directories = (array) $directories;
foreach ($directories as $directory) {
if (is_dir($directory)) {
/** @var \SplFileInfo $fileInfo */
$iterator = new RegexDirectoryIterator($directory, '/\.html\.twig$/i');
foreach ($iterator as $fileInfo) {
$file_list[$fileInfo->getPathname()] = $provider;
}
}
}
}
return $file_list;
}
}
<?php
namespace Drupal\help_topics;
use Drupal\Core\Link;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Url;
/**
* Base class for help topic plugins.
*
* @internal
* Help Topic is currently experimental and should only be leveraged by
* experimental modules and development releases of contributed modules.
* See https://www.drupal.org/core/experimental for more information.
*/
abstract class HelpTopicPluginBase extends PluginBase implements HelpTopicPluginInterface {
/**
* The name of the module or theme providing the help topic.
*/
public function getProvider() {
return $this->pluginDefinition['provider'];
}
/**
* {@inheritdoc}
*/
public function getLabel() {
return $this->pluginDefinition['label'];
}
/**
* {@inheritdoc}
*/
public function isTopLevel() {
return $this->pluginDefinition['top_level'];
}
/**
* {@inheritdoc}
*/
public function getRelated() {
return $this->pluginDefinition['related'];
}
/**
* {@inheritdoc}
*/
public function toUrl(array $options = []) {
return Url::fromRoute('help_topics.help_topic', ['id' => $this->getPluginId()], $options);
}
/**
* {@inheritdoc}
*/
public function toLink($text = NULL, array $options = []) {
if (!$text) {
$text = $this->getLabel();
}
return Link::createFromRoute($text, 'help_topics.help_topic', ['id' => $this->getPluginId()], $options);
}
}
<?php
namespace Drupal\help_topics;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Component\Plugin\DerivativeInspectionInterface;
use Drupal\Core\Cache\CacheableDependencyInterface;
/**
* Defines an interface for help topic plugin classes.
*
* @see \Drupal\help_topics\HelpTopicPluginManager
*
* @internal
* Help Topic is currently experimental and should only be leveraged by
* experimental modules and development releases of contributed modules.
* See https://www.drupal.org/core/experimental for more information.
*/
interface HelpTopicPluginInterface extends PluginInspectionInterface, DerivativeInspectionInterface, CacheableDependencyInterface {
/**
* Returns the label of the topic.
*
* @return string
* The label of the topic.
*/
public function getLabel();
/**
* Returns the body of the topic.