http://www.phparch.com \ December 2018 \ 19
The Flexibility of Drupal 8
Putting it All Together
No single method can be considered the “right” method to
customize Drupal. Instead, the right method depends on the
circumstances of the build. Both the skill and the experience
level of the team must be considered, as well as the amount
of time available to make the customization. If skill levels are
high and there is enough time to devote to the customization,
it may well make sense to use a service. However, if time is
short, a better use of time may be to find and install a module
that another Drupal user has created.
Regardless of what customization we seek, the methods
and principles described in this article can be adapted to
accomplish it. For example, content structure, user function-
ality, and display of any element can all be customized using
any of the six methods. It is important to note, however, that
there are even more than six ways to customize a menu or any
other feature, each with their own set of pros and cons. That is
the beauty of working with a flexible framework like Drupal.
Michael Miles has been working with
PHP since 2004. He is the V.P. of Technology
for the digital marketing agency Genuine,
where he helps lead, scope, architect and
build many of the development projects. He
speaks at technology conferences around the
world and is also the host of the development
career focused podcast DevelopingUp.
@mikemiles86
Listing 7
- <?php
- /**
- @file
- This file defines a custom service to be used when generating
- Drupal menus. Replaces the core MenuLinkTree service class
- and overrides the build() method.
- modules/custom/sweet/src/SweetMenuLinkTree.php
- */
- namespace Drupal\sweet;
- use Drupal\Core\Menu\MenuLinkTree;
- use Drupal\Core\Url;
- /**
- Custom implementation of MenuLinkTree Service.
- */
- class SweetMenuLinkTree extends MenuLinkTree {
- // Overrides \Drupal\Core\Menu\MenuLinkTree::build().
- public function build(array $tree) {
- // Call parent build method.
- $build = parent::build($tree);
- // Are there menu items and is this going to be the main menu?
- if (isset($build['#items']) && $build['#theme'] == 'menu__main') {
- // Loop through each build item.
- foreach ($build['#items'] as $key => &$item ) {
- // Pointing to /contact
- if ($item['url']->toString() == '/contact') {
- // Attempt to get a random recipe.
- if ($recipe = $this->getRandomRecipeUrl()) {
- // Alter the title to be 'Mystery Meal'.
- $item['title'] = 'Mystery Meal';
- // Alter the URL attribute.
- $item['url'] = $recipe;
- // Update active trail.
- $item['in_active_trail'] = FALSE;
- // Get current page route name.
- $current_route = \Drupal::routeMatch()->getRouteName();
- // Set active trail attribute to true if active to menu url.
- if ($current_route == $recipe->getRouteName()) {
- $item['in_active_trail'] = TRUE;
- }
- // Save as a new item with a different id.
46. $build['#items']['sweet.mystery'] = $item;
47. // Remove 'Contact' menu item.
48. unset($build['#items'][$key]);
49. }
50. }
51. }
52. }
53.
54. // Return the build array.
55. return $build;
56. }
57.
58. /*
59. Retrieves a random node of type Recipe.
60. */
61. private function getRandomRecipeUrl() {
62. $recipe_url = false;
63.
64. // Build a select query on the node field table
65. $query = \Drupal::database()->select('node_field_data', 'n')
66. // Going to retrieve the node id.
67. ->fields('n', ['nid'])
68. // Only retrieve nodes of type recipe.
69. ->condition('type', 'recipe')
70. // Only published nodes.
71. ->condition('status', 1 )
72. // Only retrieve one result
73. ->range( 0 , 1 )
74. // Sort in a random order.
75. ->orderRandom();
76.
77. $results = $query->execute()->fetchCol();
78.
79. // Found a recipe node?
80. if (!empty($results)) {
81. // Get the nid value
82. $nid = array_pop($results);
83. // Generate URL object.
84. $recipe_url = new Url( 'entity.node.canonical', ['node' => $nid]);
85. }
86.
87. return $recipe_url;
88. }
89. }
Related Reading
- Drupal for Symfony Developers
by Antonio Perić-Mažar. February 2018.
https://www.phparch.com/magazine/2018-2/february/ - Drupal 8 Module Development
by Nicola Pignatelli. April 2016.
https://www.phparch.com/magazine/2016-2/april/