menu_manipulator.module in Menu Manipulator 8
Same filename and directory in other branches
Contains menu_manipulator.module.
File
menu_manipulator.moduleView source
<?php
/**
* @file
* Contains menu_manipulator.module.
*/
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Routing\CurrentRouteMatch;
/**
* Implements hook_help().
*
* @inheritdoc
*/
function menu_manipulator_help($route_name, CurrentRouteMatch $route_match) {
if ($route_name == 'help.page.menu_manipulator') {
$text = file_get_contents(dirname(__FILE__) . '/README.md');
if (!\Drupal::moduleHandler()
->moduleExists('markdown')) {
return '<pre>' . $text . '</pre>';
}
else {
// Use the Markdown filter to render the README.
$filter_manager = \Drupal::service('plugin.manager.filter');
$settings = \Drupal::configFactory()
->get('markdown.settings')
->getRawData();
$config = [
'settings' => $settings,
];
$filter = $filter_manager
->createInstance('markdown', $config);
return $filter
->process($text, 'en');
}
}
return NULL;
}
/**
* Get a menu tree filtered by the current language.
*
* Based on our custom MenuTreeManipulators services.
* This is pretty useful as of now (8.4.x) as Drupal doesn't
* provide a way to filer MenuLinkContent entity by their language.
*
* @param string $menu_name
* The menu machine name.
*
* @return array
* The filtered MenuTree renderable array.
*
* @code
* // Implements theme_preprocess_menu().
* function yourtheme_preprocess_menu(&$variables, $hook) {
* if (isset($variables['menu_name']) && $menu_name = $variables['menu_name']) {
* $moduleHandler = \Drupal::service('module_handler');
* if ($moduleHandler->moduleExists('menu_manipulator')) {
* $menu_tree_translated = menu_manipulator_get_multilingual_menu($menu_name);
* $variables['items'] = isset($menu_tree_translated['#items']) ? $menu_tree_translated['#items'] : [];
* }
* }
* }
* @endcode
*/
function menu_manipulator_get_multilingual_menu(string $menu_name) {
$menu_tree = \Drupal::menuTree();
$manipulators = [
[
'callable' => 'menu.default_tree_manipulators:checkAccess',
],
[
'callable' => 'menu.default_tree_manipulators:generateIndexAndSort',
],
[
'callable' => 'menu_manipulator.menu_tree_manipulators:filterByCurrentLanguage',
],
];
if ($menu_name == 'admin') {
// Specific manipulation for the "Admin Toolbar" menu.
// See admin_toolbar_prerender_toolbar_administration_tray()
// in admin_toolbar.module.
$parameters = new MenuTreeParameters();
$parameters
->setRoot('system.admin')
->excludeRoot()
->setMaxDepth(4)
->onlyEnabledLinks();
}
else {
// Default method to retrieve menu items.
// See MenuLinkTreeInteface::getCurrentRouteMenuTreeParameters().
$parameters = $menu_tree
->getCurrentRouteMenuTreeParameters($menu_name);
}
// Manipulate the menu tree to filter by current language.
$menu = $menu_tree
->load($menu_name, $parameters);
$menu = $menu_tree
->transform($menu, $manipulators);
return $menu_tree
->build($menu);
}
/**
* Implements theme_preprocess_menu().
*/
function menu_manipulator_preprocess_menu(&$variables, $hook) {
$config = \Drupal::config('menu_manipulator.settings');
if ($config
->get('preprocess_menus_title')) {
// Populate menu title variable for Twig.
if (isset($variables['menu_name'])) {
$menu = \Drupal::service('entity_type.manager')
->getStorage('menu')
->load($variables['menu_name']);
if (NULL != $menu) {
$variables['menu_title'] = [
'#markup' => \Drupal::translation()
->translate('@label', [
'@label' => $menu
->label(),
]),
];
}
}
}
if ($config
->get('preprocess_menus_language')) {
if (isset($variables['menu_name'])) {
// Automatically filter menu by language.
$do_filter = TRUE;
// Check if this menu has to be filtered.
if (is_array($config
->get('preprocess_menus_language_list'))) {
$do_filter = array_intersect([
$variables['menu_name'],
], $config
->get('preprocess_menus_language_list'));
}
// Actually filter menu by language.
if ($do_filter) {
$menu_tree_translated = menu_manipulator_get_multilingual_menu($variables['menu_name']);
$variables['items'] = isset($menu_tree_translated['#items']) ? $menu_tree_translated['#items'] : [];
}
}
}
if ($config
->get('preprocess_menus_icon')) {
if (isset($variables['menu_name'])) {
// Do not process icons variable by default.
$do_filter = FALSE;
// Check if this menu is selected has been selected by user.
if (is_array($config
->get('preprocess_menus_icon_list'))) {
$do_filter = array_intersect([
$variables['menu_name'],
], $config
->get('preprocess_menus_icon_list'));
}
// Filter menu to display icons.
if ($do_filter) {
foreach ($variables['items'] as $key => $item) {
$item_options = $item['original_link']
->getOptions();
if (isset($item_options['icon']) && ($icon = $item_options['icon'])) {
$variables['items'][$key]['icon'] = $icon;
}
}
}
}
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter() for the Menu Link Content form.
*
* @todo make $icon_list administrable.
*/
function menu_manipulator_form_menu_link_content_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
$menu_link = $form_state
->getFormObject()
->getEntity();
$menu_link_options = $menu_link->link ? $menu_link->link
->first()->options : [];
$config = \Drupal::config('menu_manipulator.settings');
// Hide icon options by default.
$do_filter = FALSE;
// Check if this menu is selected has been selected by user.
if (is_array($config
->get('preprocess_menus_icon_list'))) {
$do_filter = array_intersect([
$menu_link
->getMenuName(),
], $config
->get('preprocess_menus_icon_list'));
}
// Stop now if not allowing Icons processing for this menu.
if (!$do_filter) {
return;
}
$icon_list_value = $config
->get('menu_link_icon_list') ?: '';
$icon_list = menu_manipulator_prepare_associative_list($icon_list_value);
$form['menu_link_icon'] = [
'#type' => 'select',
'#title' => t('Icon'),
'#description' => t('Select icon for this menu link.'),
'#weight' => -2,
'#tree' => TRUE,
'#access' => \Drupal::currentUser()
->hasPermission('use menu link icon'),
'#empty_option' => t('- Select -'),
'#options' => $icon_list,
'#default_value' => isset($menu_link_options['icon']) ? $menu_link_options['icon'] : NULL,
];
$form['actions']['submit']['#submit'][] = 'menu_manipulator_menu_link_content_form_submit';
}
/**
* Submit function for menu add / edit form.
*/
function menu_manipulator_menu_link_content_form_submit($form, FormStateInterface $form_state) {
$menu_link = $form_state
->getFormObject()
->getEntity();
if (!$menu_link->link) {
return;
}
$menu_link_options = $menu_link->link
->first()->options ?: [];
// Attach extra options to Menu Link Content entity.
$menu_link_options = $menu_link->link
->first()->options ?: [];
$menu_link_options['icon'] = $form_state
->getValue('menu_link_icon');
$menu_link->link
->first()->options = $menu_link_options;
$menu_link
->save();
}
/**
* Helper function to filter the associative key|label configuration.
*
* @param string $string
* The original value.
*
* @return array
* An associative array of values.
*
* @see Drupal\options\Plugin\Field\FieldType\ListItemBase::extractedAllowedValues();
*/
function menu_manipulator_prepare_associative_list($string) {
$values = [];
$list = explode("\n", $string);
$list = array_map('trim', $list);
$list = array_filter($list, 'strlen');
$generated_keys = $explicit_keys = FALSE;
foreach ($list as $text) {
// Check for an explicit key.
$matches = [];
if (preg_match('/(.*)\\|(.*)/', $text, $matches)) {
// Trim key and value to avoid unwanted spaces issues.
$key = trim($matches[1]);
$value = trim($matches[2]);
$explicit_keys = TRUE;
}
$values[$key] = $value;
}
// We generate keys only if the list contains no explicit key at all.
if ($explicit_keys && $generated_keys) {
return [];
}
return $values;
}
Functions
Name | Description |
---|---|
menu_manipulator_form_menu_link_content_form_alter | Implements hook_form_BASE_FORM_ID_alter() for the Menu Link Content form. |
menu_manipulator_get_multilingual_menu | Get a menu tree filtered by the current language. |
menu_manipulator_help | Implements hook_help(). |
menu_manipulator_menu_link_content_form_submit | Submit function for menu add / edit form. |
menu_manipulator_prepare_associative_list | Helper function to filter the associative key|label configuration. |
menu_manipulator_preprocess_menu | Implements theme_preprocess_menu(). |