Commit 2a0254f9 authored by catch's avatar catch

Issue #2232605 by alexpott, dawehner, martin107, Cottser, sun: Fixed Themes cannot be uninstalled.

parent f27fd1f5
module: {} module: {}
theme: {} theme: {}
disabled:
theme: {}
...@@ -10,17 +10,7 @@ core.extension: ...@@ -10,17 +10,7 @@ core.extension:
label: 'Weight' label: 'Weight'
theme: theme:
type: sequence type: sequence
label: 'Enabled themes' label: 'Installed themes'
sequence: sequence:
- type: integer - type: integer
label: 'Weight' label: 'Weight'
disabled:
type: mapping
label: 'Disabled extensions'
mapping:
theme:
type: sequence
label: 'Disabled themes'
sequence:
- type: integer
label: 'Weight'
...@@ -283,7 +283,7 @@ services: ...@@ -283,7 +283,7 @@ services:
arguments: ['%container.modules%', '@cache.bootstrap'] arguments: ['%container.modules%', '@cache.bootstrap']
theme_handler: theme_handler:
class: Drupal\Core\Extension\ThemeHandler class: Drupal\Core\Extension\ThemeHandler
arguments: ['@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@router.builder'] arguments: ['@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder']
entity.manager: entity.manager:
class: Drupal\Core\Entity\EntityManager class: Drupal\Core\Entity\EntityManager
arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@language_manager', '@string_translation', '@class_resolver', '@typed_data_manager', '@entity.definitions.installed'] arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@language_manager', '@string_translation', '@class_resolver', '@typed_data_manager', '@entity.definitions.installed']
......
...@@ -1512,7 +1512,7 @@ function install_profile_modules(&$install_state) { ...@@ -1512,7 +1512,7 @@ function install_profile_modules(&$install_state) {
* Installs themes. * Installs themes.
* *
* This does not use a batch, since installing themes is faster than modules and * This does not use a batch, since installing themes is faster than modules and
* because an installation profile typically enables 1-3 themes only (default * because an installation profile typically installs 1-3 themes only (default
* theme, base theme, admin theme). * theme, base theme, admin theme).
* *
* @param $install_state * @param $install_state
...@@ -1521,15 +1521,15 @@ function install_profile_modules(&$install_state) { ...@@ -1521,15 +1521,15 @@ function install_profile_modules(&$install_state) {
function install_profile_themes(&$install_state) { function install_profile_themes(&$install_state) {
$theme_handler = \Drupal::service('theme_handler'); $theme_handler = \Drupal::service('theme_handler');
// ThemeHandler::enable() resets the current list of themes. The theme used in // ThemeHandler::install() resets the current list of themes. The theme used
// the installer is not necessarily in the list of themes to install, so // in the installer is not necessarily in the list of themes to install, so
// retain the current list. // retain the current list.
// @see _drupal_maintenance_theme() // @see _drupal_maintenance_theme()
$current_themes = $theme_handler->listInfo(); $current_themes = $theme_handler->listInfo();
// Install the themes specified by the installation profile. // Install the themes specified by the installation profile.
$themes = $install_state['profile_info']['themes']; $themes = $install_state['profile_info']['themes'];
$theme_handler->enable($themes); $theme_handler->install($themes);
foreach ($current_themes as $theme) { foreach ($current_themes as $theme) {
$theme_handler->addTheme($theme); $theme_handler->addTheme($theme);
......
...@@ -9,11 +9,11 @@ ...@@ -9,11 +9,11 @@
use Drupal\Core\Extension\ExtensionDiscovery; use Drupal\Core\Extension\ExtensionDiscovery;
/** /**
* Builds a list of enabled themes. * Builds a list of installed themes.
* *
* @param $type * @param $type
* The type of list to return: * The type of list to return:
* - theme: All enabled themes. * - theme: All installed themes.
* *
* @return * @return
* An associative array of themes, keyed by name. * An associative array of themes, keyed by name.
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
* Either the name of a theme or a full theme object. * Either the name of a theme or a full theme object.
* *
* @return bool * @return bool
* Boolean TRUE if the theme is enabled or is the site administration theme; * Boolean TRUE if the theme is installed or is the site administration theme;
* FALSE otherwise. * FALSE otherwise.
* *
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
...@@ -765,42 +765,6 @@ function theme_settings_convert_to_config(array $theme_settings, Config $config) ...@@ -765,42 +765,6 @@ function theme_settings_convert_to_config(array $theme_settings, Config $config)
return $config; return $config;
} }
/**
* Enables a given list of themes.
*
* @param $theme_list
* An array of theme names.
*
* @return bool
* Whether any of the given themes have been enabled.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
* Use \Drupal::service('theme_handler')->enable().
*
* @see \Drupal\Core\Extension\ThemeHandler::enable().
*/
function theme_enable($theme_list) {
return \Drupal::service('theme_handler')->enable($theme_list);
}
/**
* Disables a given list of themes.
*
* @param $theme_list
* An array of theme names.
*
* @return bool
* Whether any of the given themes have been disabled.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
* Use \Drupal::service('theme_handler')->disable().
*
* @see \Drupal\Core\Extension\ThemeHandler::disable().
*/
function theme_disable($theme_list) {
return \Drupal::service('theme_handler')->disable($theme_list);
}
/** /**
* @addtogroup themeable * @addtogroup themeable
* @{ * @{
......
...@@ -23,9 +23,6 @@ function update_fix_compatibility() { ...@@ -23,9 +23,6 @@ function update_fix_compatibility() {
foreach ($extension_config->get($type) as $name => $weight) { foreach ($extension_config->get($type) as $name => $weight) {
if (update_check_incompatibility($name, $type)) { if (update_check_incompatibility($name, $type)) {
$extension_config->clear("$type.$name"); $extension_config->clear("$type.$name");
if ($type === 'theme') {
$extension_config->set("disabled.theme.$name", 0);
}
$save = TRUE; $save = TRUE;
} }
} }
......
...@@ -124,7 +124,7 @@ class ConfigImporter { ...@@ -124,7 +124,7 @@ class ConfigImporter {
protected $themeHandler; protected $themeHandler;
/** /**
* Flag set to import system.theme during processing theme enable and disables. * Flag set to import system.theme during processing theme install and uninstalls.
* *
* @var bool * @var bool
*/ */
...@@ -252,8 +252,8 @@ protected function getEmptyExtensionsProcessedList() { ...@@ -252,8 +252,8 @@ protected function getEmptyExtensionsProcessedList() {
'uninstall' => array(), 'uninstall' => array(),
), ),
'theme' => array( 'theme' => array(
'enable' => array(), 'install' => array(),
'disable' => array(), 'uninstall' => array(),
), ),
); );
} }
...@@ -395,9 +395,9 @@ protected function createExtensionChangelist() { ...@@ -395,9 +395,9 @@ protected function createExtensionChangelist() {
$module_list = array_reverse($module_list); $module_list = array_reverse($module_list);
$install = array_intersect(array_keys($module_list), $install); $install = array_intersect(array_keys($module_list), $install);
// Work out what themes to enable and to disable. // Work out what themes to install and to uninstall.
$enable = array_diff(array_keys($new_extensions['theme']), array_keys($current_extensions['theme'])); $theme_install = array_diff(array_keys($new_extensions['theme']), array_keys($current_extensions['theme']));
$disable = array_diff(array_keys($current_extensions['theme']), array_keys($new_extensions['theme'])); $theme_uninstall = array_diff(array_keys($current_extensions['theme']), array_keys($new_extensions['theme']));
$this->extensionChangelist = array( $this->extensionChangelist = array(
'module' => array( 'module' => array(
...@@ -405,8 +405,8 @@ protected function createExtensionChangelist() { ...@@ -405,8 +405,8 @@ protected function createExtensionChangelist() {
'install' => $install, 'install' => $install,
), ),
'theme' => array( 'theme' => array(
'enable' => $enable, 'install' => $theme_install,
'disable' => $disable, 'uninstall' => $theme_uninstall,
), ),
); );
} }
...@@ -441,20 +441,10 @@ protected function getExtensionChangelist($type, $op = NULL) { ...@@ -441,20 +441,10 @@ protected function getExtensionChangelist($type, $op = NULL) {
*/ */
protected function getUnprocessedExtensions($type) { protected function getUnprocessedExtensions($type) {
$changelist = $this->getExtensionChangelist($type); $changelist = $this->getExtensionChangelist($type);
return array(
if ($type == 'theme') { 'install' => array_diff($changelist['install'], $this->processedExtensions[$type]['install']),
$unprocessed = array( 'uninstall' => array_diff($changelist['uninstall'], $this->processedExtensions[$type]['uninstall']),
'enable' => array_diff($changelist['enable'], $this->processedExtensions[$type]['enable']), );
'disable' => array_diff($changelist['disable'], $this->processedExtensions[$type]['disable']),
);
}
else {
$unprocessed = array(
'install' => array_diff($changelist['install'], $this->processedExtensions[$type]['install']),
'uninstall' => array_diff($changelist['uninstall'], $this->processedExtensions[$type]['uninstall']),
);
}
return $unprocessed;
} }
/** /**
...@@ -533,7 +523,7 @@ public function initialize() { ...@@ -533,7 +523,7 @@ public function initialize() {
$this->totalExtensionsToProcess += count($modules[$op]); $this->totalExtensionsToProcess += count($modules[$op]);
} }
$themes = $this->getUnprocessedExtensions('theme'); $themes = $this->getUnprocessedExtensions('theme');
foreach (array('enable', 'disable') as $op) { foreach (array('install', 'uninstall') as $op) {
$this->totalExtensionsToProcess += count($themes[$op]); $this->totalExtensionsToProcess += count($themes[$op]);
} }
...@@ -576,7 +566,7 @@ protected function processExtensions(array &$context) { ...@@ -576,7 +566,7 @@ protected function processExtensions(array &$context) {
$this->processExtension($operation['type'], $operation['op'], $operation['name']); $this->processExtension($operation['type'], $operation['op'], $operation['name']);
$context['message'] = t('Synchronising extensions: @op @name.', array('@op' => $operation['op'], '@name' => $operation['name'])); $context['message'] = t('Synchronising extensions: @op @name.', array('@op' => $operation['op'], '@name' => $operation['name']));
$processed_count = count($this->processedExtensions['module']['install']) + count($this->processedExtensions['module']['uninstall']); $processed_count = count($this->processedExtensions['module']['install']) + count($this->processedExtensions['module']['uninstall']);
$processed_count += count($this->processedExtensions['theme']['disable']) + count($this->processedExtensions['theme']['enable']); $processed_count += count($this->processedExtensions['theme']['uninstall']) + count($this->processedExtensions['theme']['install']);
$context['finished'] = $processed_count / $this->totalExtensionsToProcess; $context['finished'] = $processed_count / $this->totalExtensionsToProcess;
} }
else { else {
...@@ -650,24 +640,16 @@ protected function finish(array &$context) { ...@@ -650,24 +640,16 @@ protected function finish(array &$context) {
* on. If there is nothing left to do returns FALSE; * on. If there is nothing left to do returns FALSE;
*/ */
protected function getNextExtensionOperation() { protected function getNextExtensionOperation() {
foreach (array('install', 'uninstall') as $op) { foreach (array('module', 'theme') as $type) {
$modules = $this->getUnprocessedExtensions('module'); foreach (array('install', 'uninstall') as $op) {
if (!empty($modules[$op])) { $unprocessed = $this->getUnprocessedExtensions($type);
return array( if (!empty($unprocessed[$op])) {
'op' => $op, return array(
'type' => 'module', 'op' => $op,
'name' => array_shift($modules[$op]), 'type' => $type,
); 'name' => array_shift($unprocessed[$op]),
} );
} }
foreach (array('enable', 'disable') as $op) {
$themes = $this->getUnprocessedExtensions('theme');
if (!empty($themes[$op])) {
return array(
'op' => $op,
'type' => 'theme',
'name' => array_shift($themes[$op]),
);
} }
} }
return FALSE; return FALSE;
...@@ -794,11 +776,11 @@ protected function processExtension($type, $op, $name) { ...@@ -794,11 +776,11 @@ protected function processExtension($type, $op, $name) {
$this->moduleHandler->loadAll(); $this->moduleHandler->loadAll();
} }
if ($type == 'theme') { if ($type == 'theme') {
// Theme disables possible remove default or admin themes therefore we // Theme uninstalls possible remove default or admin themes therefore we
// need to import this before doing any. If there are no disables and // need to import this before doing any. If there are no uninstalls and
// the default or admin theme is change this will be picked up whilst // the default or admin theme is changing this will be picked up whilst
// processing configuration. // processing configuration.
if ($op == 'disable' && $this->processedSystemTheme === FALSE) { if ($op == 'uninstall' && $this->processedSystemTheme === FALSE) {
$this->importConfig(StorageInterface::DEFAULT_COLLECTION, 'update', 'system.theme'); $this->importConfig(StorageInterface::DEFAULT_COLLECTION, 'update', 'system.theme');
$this->configManager->getConfigFactory()->reset('system.theme'); $this->configManager->getConfigFactory()->reset('system.theme');
$this->processedSystemTheme = TRUE; $this->processedSystemTheme = TRUE;
......
...@@ -8,49 +8,54 @@ ...@@ -8,49 +8,54 @@
namespace Drupal\Core\Extension; namespace Drupal\Core\Extension;
/** /**
* Manages the list of available themes as well as enable/disable them. * Manages the list of available themes as well as install/uninstall them.
*/ */
interface ThemeHandlerInterface { interface ThemeHandlerInterface {
/** /**
* Enables a given list of themes. * Installs a given list of themes.
* *
* @param array $theme_list * @param array $theme_list
* An array of theme names. * An array of theme names.
* @param bool $enable_dependencies * @param bool $install_dependencies
* (optional) If TRUE, dependencies will automatically be installed in the * (optional) If TRUE, dependencies will automatically be installed in the
* correct order. This incurs a significant performance cost, so use FALSE * correct order. This incurs a significant performance cost, so use FALSE
* if you know $theme_list is already complete and in the correct order. * if you know $theme_list is already complete and in the correct order.
* *
* @return bool * @return bool
* Whether any of the given themes have been enabled. * Whether any of the given themes have been installed.
* *
* @throws \Drupal\Core\Extension\ExtensionNameLengthException * @throws \Drupal\Core\Extension\ExtensionNameLengthException
* Thrown when the theme name is to long * Thrown when the theme name is to long
*/ */
public function enable(array $theme_list, $enable_dependencies = TRUE); public function install(array $theme_list, $install_dependencies = TRUE);
/** /**
* Disables a given list of themes. * Uninstalls a given list of themes.
*
* Uninstalling a theme removes all related configuration (like blocks) and
* invokes the 'themes_uninstalled' hook.
* *
* @param array $theme_list * @param array $theme_list
* An array of theme names. * The themes to uninstall.
* *
* @return bool * @throws \InvalidArgumentException
* Whether any of the given themes have been disabled. * Thrown when you uninstall an not installed theme.
*
* @see hook_themes_uninstalled()
*/ */
public function disable(array $theme_list); public function uninstall(array $theme_list);
/** /**
* Returns a list of currently enabled themes. * Returns a list of currently installed themes.
* *
* @return \Drupal\Core\Extension\Extension[] * @return \Drupal\Core\Extension\Extension[]
* An associative array of the currently enabled themes. The keys are the * An associative array of the currently installed themes. The keys are the
* themes' machine names and the values are objects having the following * themes' machine names and the values are objects having the following
* properties: * properties:
* - filename: The filepath and name of the .info.yml file. * - filename: The filepath and name of the .info.yml file.
* - name: The machine name of the theme. * - name: The machine name of the theme.
* - status: 1 for enabled, 0 for disabled themes. * - status: 1 for installed, 0 for uninstalled themes.
* - info: The contents of the .info.yml file. * - info: The contents of the .info.yml file.
* - stylesheets: A two dimensional array, using the first key for the * - stylesheets: A two dimensional array, using the first key for the
* media attribute (e.g. 'all'), the second for the name of the file * media attribute (e.g. 'all'), the second for the name of the file
...@@ -83,7 +88,7 @@ public function disable(array $theme_list); ...@@ -83,7 +88,7 @@ public function disable(array $theme_list);
public function listInfo(); public function listInfo();
/** /**
* Refreshes the theme info data of currently enabled themes. * Refreshes the theme info data of currently installed themes.
* *
* Modules can alter theme info, so this is typically called after a module * Modules can alter theme info, so this is typically called after a module
* has been installed or uninstalled. * has been installed or uninstalled.
...@@ -140,7 +145,17 @@ public function getName($theme); ...@@ -140,7 +145,17 @@ public function getName($theme);
public function getDefault(); public function getDefault();
/** /**
* Returns an array of directories for all enabled themes. * Sets a new default theme.
*
* @param string $theme
* The new default theme.
*
* @return $this
*/
public function setDefault($theme);
/**
* Returns an array of directories for all installed themes.
* *
* Useful for tasks such as finding a file that exists in all theme * Useful for tasks such as finding a file that exists in all theme
* directories. * directories.
...@@ -150,13 +165,13 @@ public function getDefault(); ...@@ -150,13 +165,13 @@ public function getDefault();
public function getThemeDirectories(); public function getThemeDirectories();
/** /**
* Determines whether a given theme is enabled. * Determines whether a given theme is installed.
* *
* @param string $theme * @param string $theme
* The name of the theme (without the .theme extension). * The name of the theme (without the .theme extension).
* *
* @return bool * @return bool
* TRUE if the theme is both installed and enabled. * TRUE if the theme is installed.
*/ */
public function themeExists($theme); public function themeExists($theme);
......
...@@ -30,13 +30,13 @@ public function access($theme) { ...@@ -30,13 +30,13 @@ public function access($theme) {
} }
/** /**
* Indicates whether the theme is accessible based on whether it is enabled. * Indicates whether the theme is accessible based on whether it is installed.
* *
* @param string $theme * @param string $theme
* The name of a theme. * The name of a theme.
* *
* @return bool * @return bool
* TRUE if the theme is enabled, FALSE otherwise. * TRUE if the theme is installed, FALSE otherwise.
*/ */
public function checkAccess($theme) { public function checkAccess($theme) {
$themes = list_themes(); $themes = list_themes();
......
...@@ -64,15 +64,15 @@ public function getActiveThemeByName($theme_name) { ...@@ -64,15 +64,15 @@ public function getActiveThemeByName($theme_name) {
$themes = $this->themeHandler->listInfo(); $themes = $this->themeHandler->listInfo();
// If no theme could be negotiated, or if the negotiated theme is not within // If no theme could be negotiated, or if the negotiated theme is not within
// the list of enabled themes, fall back to the default theme output of core // the list of installed themes, fall back to the default theme output of
// and modules (like Stark, but without a theme extension at all). This is // core and modules (like Stark, but without a theme extension at all). This
// possible, because loadActiveTheme() always loads the Twig theme engine. // is possible, because loadActiveTheme() always loads the Twig theme
// This is desired, because missing or malformed theme configuration should // engine. This is desired, because missing or malformed theme configuration
// not leave the application in a broken state. By falling back to default // should not leave the application in a broken state. By falling back to
// output, the user is able to reconfigure the theme through the UI. // default output, the user is able to reconfigure the theme through the UI.
// Lastly, tests are expected to operate with no theme by default, so as to // Lastly, tests are expected to operate with no theme by default, so as to
// only assert the original theme output of modules (unless a test manually // only assert the original theme output of modules (unless a test manually
// enables a specific theme). // installs a specific theme).
if (empty($themes) || !$theme_name || !isset($themes[$theme_name])) { if (empty($themes) || !$theme_name || !isset($themes[$theme_name])) {
$theme_name = 'core'; $theme_name = 'core';
// /core/core.info.yml does not actually exist, but is required because // /core/core.info.yml does not actually exist, but is required because
......
...@@ -82,7 +82,7 @@ public function postInstall() { ...@@ -82,7 +82,7 @@ public function postInstall() {
*/ */
public function postInstallTasks() { public function postInstallTasks() {
return array( return array(
l(t('Enable newly added themes'), 'admin/appearance'), l(t('Install newly added themes'), 'admin/appearance'),
l(t('Administration pages'), 'admin'), l(t('Administration pages'), 'admin'),
); );
} }
......
...@@ -19,6 +19,10 @@ class ProjectInfo { ...@@ -19,6 +19,10 @@ class ProjectInfo {
/** /**
* Populates an array of project data. * Populates an array of project data.
* *
* @todo https://www.drupal.org/node/2338167 update class since extensions can
* no longer be hidden, enabled or disabled. Additionally, base themes have
* to be installed for sub themes to work.
*
* This iterates over a list of the installed modules or themes and groups * This iterates over a list of the installed modules or themes and groups
* them by project and status. A few parts of this function assume that * them by project and status. A few parts of this function assume that
* enabled modules and themes are always processed first, and if disabled * enabled modules and themes are always processed first, and if disabled
...@@ -51,15 +55,15 @@ function processInfoList(array &$projects, array $list, $project_type, $status, ...@@ -51,15 +55,15 @@ function processInfoList(array &$projects, array $list, $project_type, $status,
// projects list. // projects list.
if ($status && !empty($file->sub_themes)) { if ($status && !empty($file->sub_themes)) {
foreach ($file->sub_themes as $key => $name) { foreach ($file->sub_themes as $key => $name) {
// Build a list of enabled sub-themes. // Build a list of installed sub-themes.
if ($list[$key]->status) { if ($list[$key]->status) {
$file->enabled_sub_themes[$key] = $name; $file->installed_sub_themes[$key] = $name;
} }
} }
// If the theme is disabled and there are no enabled subthemes, we // If the theme is uninstalled and there are no installed subthemes, we
// should ignore this base theme for the enabled case. If the site is // should ignore this base theme for the installed case. If the site is
// trying to display disabled themes, we'll catch it then. // trying to display uninstalled themes, we'll catch it then.
if (!$file->status && empty($file->enabled_sub_themes)) { if (!$file->status && empty($file->installed_sub_themes)) {
continue; continue;
} }
} }
...@@ -73,8 +77,9 @@ function processInfoList(array &$projects, array $list, $project_type, $status, ...@@ -73,8 +77,9 @@ function processInfoList(array &$projects, array $list, $project_type, $status,
continue; continue;
} }
// Skip if it's a hidden module or hidden theme without enabled sub-themes. // Skip if it's a hidden module or hidden theme without installed
if (!empty($file->info['hidden']) && empty($file->enabled_sub_themes)) { // sub-themes.
if (!empty($file->info['hidden']) && empty($file->installed_sub_themes)) {
continue; continue;
} }
...@@ -115,10 +120,10 @@ function processInfoList(array &$projects, array $list, $project_type, $status, ...@@ -115,10 +120,10 @@ function processInfoList(array &$projects, array $list, $project_type, $status,
else { else {
$project_display_type = $project_type; $project_display_type = $project_type;
} }
if (empty($status) && empty($file->enabled_sub_themes)) { if (empty($status) && empty($file->installed_sub_themes)) {
// If we're processing disabled modules or themes, append a suffix. // If we're processing disabled modules or themes, append a suffix.
// However, we don't do this to a a base theme with enabled // However, we don't do this to a base theme with installed
// subthemes, since we treat that case as if it is enabled. // subthemes, since we treat that case as if it is installed.
$project_display_type .= '-disabled'; $project_display_type .= '-disabled';
} }
// Add a list of sub-themes that "depend on" the project and a list of base // Add a list of sub-themes that "depend on" the project and a list of base
...@@ -129,8 +134,8 @@ function processInfoList(array &$projects, array $list, $project_type, $status, ...@@ -129,8 +134,8 @@ function processInfoList(array &$projects, array $list, $project_type, $status,
$base_themes = array(); $base_themes = array();
} }
else { else {
// Add list of enabled sub-themes. // Add list of installed sub-themes.
$sub_themes = !empty($file->enabled_sub_themes) ? $file->enabled_sub_themes : array(); $sub_themes = !empty($file->installed_sub_themes) ? $file->installed_sub_themes : array();
// Add list of base themes. // Add list of base themes.
$base_themes = !empty($file->base_themes) ? $file->base_themes : array(); $base_themes = !empty($file->base_themes) ? $file->base_themes : array();
} }
......
...@@ -27,7 +27,7 @@ function block_help($route_name, RouteMatchInterface $route_match) { ...@@ -27,7 +27,7 @@ function block_help($route_name, RouteMatchInterface $route_match) {
$output .= '<dt>' . t('Demonstrating block regions for a theme') . '</dt>'; $output .= '<dt>' . t('Demonstrating block regions for a theme') . '</dt>';
$output .= '<dd>' . t('You can see which region is where in a theme by clicking an the <em>Demonstrate block regions</em> link on the <a href="!blocks">Block layout page</a>. Regions are specific to each theme, so you need to toggle to a different theme first to demonstrate its block regions.', array('!blocks' => \Drupal::url('block.admin_display'))) . '</dd>'; $output .= '<dd>' . t('You can see which region is where in a theme by clicking an the <em>Demonstrate block regions</em> link on the <a href="!blocks">Block layout page</a>. Regions are specific to each theme, so you need to toggle to a different theme first to demonstrate its block regions.', array('!blocks' => \Drupal::url('block.admin_display'))) . '</dd>';
$output .= '<dt>' . t('Toggling between different themes') . '</dt>'; $output .= '<dt>' . t('Toggling between different themes') . '</dt>';
$output .= '<dd>' . t('Blocks are placed and configured specifically for each theme. The Block layout page opens with the default theme, but you can toggle to other enabled themes.') . '</dd>'; $output .= '<dd>' . t('Blocks are placed and configured specifically for each theme. The Block layout page opens with the default theme, but you can toggle to other installed themes.') . '</dd>';
$output .= '<dt>' . t('Configuring block settings') . '</dt>'; $output .= '<dt>' . t('Configuring block settings') . '</dt>';
$output .= '<dd>' . t('To change the settings of an individual block click on the <em>Configure</em> link on the <a href="!blocks">Block layout page</a>. The available options vary depending on the module that provides the block. For all blocks you can change the block title and toggle whether to display it.', array('!blocks' => Drupal::url('block.admin_display'))) . '</dd>'; $output .= '<dd>' . t('To change the settings of an individual block click on the <em>Configure</em> link on the <a href="!blocks">Block layout page</a>. The available options vary depending on the module that provides the block. For all blocks you can change the block title and toggle whether to display it.', array('!blocks' => Drupal::url('block.admin_display'))) . '</dd>';
$output .= '<dt>' . t('Controlling visibility') . '</dt>'; $output .= '<dt>' . t('Controlling visibility') . '</dt>';
...@@ -139,12 +139,12 @@ function _block_rehash($theme = NULL) {