Menu http://lobsterr.me/ en How to add local tasks dynamically in Drupal 8? http://lobsterr.me/post/how-add-local-tasks-dynamically-drupal-8 <span class="field field--name-title field--type-string field--label-hidden">How to add local tasks dynamically in Drupal 8?</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">09/16/2019</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><p>In some cases we want to generate local task based on some data. In our example we want to provide custom settings per node type for it we will provide local tasks based on node types. </p> <p>As usual full example you can find here: <a href="https://github.com/LOBsTerr/drupal-modules-examples">https://github.com/LOBsTerr/drupal-modules-examples</a></p> <p>First we need to define deriver plugin, which will expose the local tasks dynamically for us.</p> <p>We will setup a route, which will accept a parameter "type" and we will just print it in order to see that it is a different page.</p> <pre> <code class="language-php">local_tasks.dynamic_tasks: path: '/dynamic-tasks/{type}' defaults: _controller: '\Drupal\local_tasks\Controller\LocalTasksController::dynamicTasks' _title: 'Dynamic tasks' type: '' requirements: _permission: 'access content'</code></pre> <p>and controller method</p> <pre> <code class="language-php">public function dynamicTasks($type = NULL) { return [ '#markup' =&gt; $this-&gt;t('This is an example : @type', [ '@type' =&gt; $type ]), ]; }</code></pre> <p>Then we add in your file <strong>[your_module_name].links.task.yml </strong>(in our case local_tasks.links.task.yml), we set a deriver class</p> <pre> <code class="language-yaml"># Dynamically add local tasks. local_tasks.dynamic_tasks: route_name: 'local_tasks.dynamic_tasks' title: 'Dynamic tasks' base_route: 'local_tasks.dynamic_tasks' deriver: Drupal\local_tasks\Plugin\Derivative\NodeTypeLocalTask # We set derive class, which will provide local tasks dynamically.</code></pre> <p> </p> <p>Now we can add a class Drupal\local_tasks\Plugin\Derivative\NodeTypeLocalTask.php</p> <pre> <code class="language-php">&lt;?php namespace Drupal\local_tasks\Plugin\Derivative; use Drupal\Component\Plugin\Derivative\DeriverBase; /** * Provides dynamic tabs based on node types. */ class NodeTypeLocalTask extends DeriverBase { /** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { // Get node types. $node_types = \Drupal::entityTypeManager() -&gt;getStorage('node_type') -&gt;loadMultiple(); foreach ($node_types as $node_type_name =&gt; $node_type) { $this-&gt;derivatives[$node_type_name] = $base_plugin_definition; $this-&gt;derivatives[$node_type_name]['title'] = $node_type-&gt;label(); $this-&gt;derivatives[$node_type_name]['route_parameters'] = ['type' =&gt; $node_type_name]; } return $this-&gt;derivatives; } } </code></pre> <p> </p> <p>As you can see above, we get list of node types and pass title and route parameters. The route name comes from <strong>local_tasks.links.task.yml</strong></p> <p>The only thin left is to clean the cache and open <strong>/dynamic-tasks/</strong>, you should see the list of node types as tabs.</p> <p>Like this you can easily add local tasks dynamically on your custom page applying more complicated logic in Drupal.</p> <p> </p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/menu" hreflang="en">Menu</a></div> <div class="field__item btn btn-secondary"><a href="/tags/plugin" hreflang="en">Plugin</a></div> <div class="field__item btn btn-secondary"><a href="/tags/drupal-9" hreflang="en">Drupal 9</a></div> </div> <div class="field field--name-f-related-items field--type-entity-reference field--label-above list-group list-group-flush"> <div class="field__label">Related items</div> <ul class="field field--name-f-related-items field--type-entity-reference field--label-above list-group list-group-flush field__items"> <li class="field__item list-group-item"><a href="/post/how-add-local-task-tab-drupal" hreflang="en">How to add a local task (tab) in Drupal?</a></li> <li class="field__item list-group-item"><a href="/post/how-add-local-task-custom-page-drupal" hreflang="en">How to add a local task to custom page in Drupal?</a></li> <li class="field__item list-group-item"><a href="/post/how-hide-local-task-tab-drupal" hreflang="en">How to hide a local task (tab) in Drupal?</a></li> </ul> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Mon, 16 Sep 2019 12:04:07 +0000 LOBsTerr 16 at http://lobsterr.me How to hide a local task (tab) in Drupal? http://lobsterr.me/post/how-hide-local-task-tab-drupal <span class="field field--name-title field--type-string field--label-hidden">How to hide a local task (tab) in Drupal?</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">09/13/2019</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><p>Quite often we want to have a parent tab to be selected, but the sublevel tasks are not displayed or we just want remove completely some tabs for user of specific roles. </p> <p>There are two ways to do it:</p> <p>The first option is to use <strong>hook_menu_local_tasks_alter</strong></p> <pre> <code class="language-php">function your_module_local_tasks_alter(&amp;$local_tasks) { unset($local_tasks['id_of_local_tasks']); }</code></pre> <p>This code will remove your tab completely from the system, it means it will not be displayed anywhere, but sometimes we want to hide the tab only on the specific pages</p> <p>The second option is to use <strong>hook_menu_local_tasks_alter</strong></p> <pre> <code class="language-php">function your_module_menu_local_tasks_alter(&amp;$data, $route_name) { $routes = ['entity.node.canonical']; // add your routes to this array and your tab will be hidden for this routes if (in_array($route_name, $routes)) { unset($data['tabs'][0]['id_of_local_task']); } }</code></pre> <p> </p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/menu" hreflang="en">Menu</a></div> <div class="field__item btn btn-secondary"><a href="/tags/drupal-9" hreflang="en">Drupal 9</a></div> <div class="field__item btn btn-secondary"><a href="/tags/hook" hreflang="en">Hook</a></div> </div> <div class="field field--name-f-related-items field--type-entity-reference field--label-above list-group list-group-flush"> <div class="field__label">Related items</div> <ul class="field field--name-f-related-items field--type-entity-reference field--label-above list-group list-group-flush field__items"> <li class="field__item list-group-item"><a href="/post/how-add-local-task-tab-drupal" hreflang="en">How to add a local task (tab) in Drupal?</a></li> <li class="field__item list-group-item"><a href="/post/how-add-local-task-custom-page-drupal" hreflang="en">How to add a local task to custom page in Drupal?</a></li> </ul> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Fri, 13 Sep 2019 09:25:22 +0000 LOBsTerr 14 at http://lobsterr.me How to add a local task to custom page in Drupal? http://lobsterr.me/post/how-add-local-task-custom-page-drupal <span class="field field--name-title field--type-string field--label-hidden">How to add a local task to custom page in Drupal?</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">09/11/2019</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><p>In the previous post <a href="http://lobsterr.me/post/how-add-local-task-tab-drupal" rel="bookmark">How to add a local task (tab) in Drupal?</a>, we have reviewed how to add a static tab to the page with tabs, but what if we want to add a tab to our custom page?</p> <p>Lets imagine we have a parent page and two child pages</p> <p>E-shop Settings</p> <ul><li>Products settings</li> <li>Categories settings</li> </ul><p>You can find the final result here: <a href="https://github.com/LOBsTerr/drupal-modules-examples/tree/master/local_tasks">https://github.com/LOBsTerr/drupal-modules-examples/tree/master/local_tasks</a></p> <p>First we will add custom pages and routes for them, for this we need to add to your controller (in my case LocalTasksController.php)</p> <pre> <code class="language-php">public function eshopSettings() { return [ '#markup' =&gt; $this-&gt;t('This is a parent settings page. This page has two child pages: &lt;a href="@products_settings_url"&gt;Products settings&lt;/a&gt; and &lt;a href="@categories_settings_url"&gt;Categories settings&lt;/a&gt;', [ '@products_settings_url' =&gt; Url::fromRoute('local_tasks.products_settings')-&gt;toString(), '@categories_settings_url' =&gt; Url::fromRoute('local_tasks.categories_settings')-&gt;toString(), ]), ]; } public function eshopMetaSettings() { return [ '#markup' =&gt; $this-&gt;t('This is a meta settings page'), ]; } public function productsSettings() { return [ '#markup' =&gt; $this-&gt;t('This is a products settings page'), ]; } public function categoriesSettings() { return [ '#markup' =&gt; $this-&gt;t('This is a categories settings page'), ]; }</code></pre> <p>Then we will provide routes for them</p> <pre> <code class="language-yaml"># Routes for custom page (eshop) tabs. local_tasks.eshop_settings: path: '/eshop-settings' defaults: _controller: '\Drupal\local_tasks\Controller\LocalTasksController::eshopSettings' _title: 'E-shop settings' requirements: _permission: 'access content' local_tasks.eshop_meta_settings: path: '/eshop-meta-settings' defaults: _controller: '\Drupal\local_tasks\Controller\LocalTasksController::eshopMetaSettings' _title: 'E-shop meta settings' requirements: _permission: 'access content' local_tasks.products_settings: path: '/eshop-settings/products-settings' defaults: _controller: '\Drupal\local_tasks\Controller\LocalTasksController::productsSettings' _title: 'Products settings' requirements: _permission: 'access content' local_tasks.categories_settings: path: '/eshop-settings/categories-settings' defaults: _controller: '\Drupal\local_tasks\Controller\LocalTasksController::categoriesSettings' _title: 'Categories settings' requirements: _permission: 'access content'</code></pre> <p>Once it is done, you can check these pages.</p> <p>/eshop-settings</p> <p>/eshop-meta-settings</p> <p>/eshop-settings/products-settings</p> <p>/eshop-settings/categories-settings</p> <p>The next step to add tabs. First we define the default tab. For the default tab the <strong>base_route </strong>should be equal <strong>route_name </strong></p> <pre> <code class="language-yaml"># in this example we add tabs for custom page. local_tasks.eshop_settings: # The ID of local task is the same as route, to make it easier to control. route_name: 'local_tasks.eshop_settings' # A route for e-shop settings, provided in local_tasks.routing.yml. title: 'Eshop settings' # This string will be displayed as a title of a tab. base_route: 'local_tasks.eshop_settings' # !!!important For default tab the base_route should be the same as route_name. weight: 10 local_tasks.eshop_meta_settings: # The ID of local task is the same as route, to make it easier to control. route_name: 'local_tasks.eshop_meta_settings' # A route for e-shop settings, provided in local_tasks.routing.yml. title: 'Eshop meta settings' # This string will be displayed as a title of a tab. base_route: 'local_tasks.eshop_settings' # This will allow to display it in the same level with "E-shop settings" weight: 20 local_tasks.products_settings: # The ID of local task is the same as route, to make it easier to control. route_name: 'local_tasks.products_settings' # A route for e-shop settings, provided in local_tasks.routing.yml. title: 'Products settings' # This string will be displayed as a title of a tab. base_route: 'local_tasks.eshop_settings' # Because we want to group tabs we should set to default one, in our case E-shop settings. parent_id: 'local_tasks.eshop_settings' # This will display item under "Eshop settings" tab. weight: 10 local_tasks.categories_settings: # The ID of local task is the same as route, to make it easier to control. route_name: 'local_tasks.categories_settings' # A route for e-shop settings, provided in local_tasks.routing.yml. title: 'Categories settings' # This string will be displayed as a title of a tab. base_route: 'local_tasks.eshop_settings' # Because we want to group tabs we should set to default one, in our case E-shop settings. parent_id: 'local_tasks.eshop_settings' # This will display item under "Eshop settings" tab. weight: 20</code></pre> <p>Clean the cache and open /eshop-settings, you will see your tabs. At that moment all tabs are in the same level, but we want them displayed as a sublevel. For these we need to define <strong>parent_id </strong>and set it to <strong>local_tasks.eshop_settings</strong> in order to display them as under "E-shop settings".</p> <p>Keep in mind that there should be at least two tabs in the level. In other case the tabs will be hidden.</p> <p> </p> <p> </p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/menu" hreflang="en">Menu</a></div> <div class="field__item btn btn-secondary"><a href="/tags/drupal-9" hreflang="en">Drupal 9</a></div> </div> <div class="field field--name-f-related-items field--type-entity-reference field--label-above list-group list-group-flush"> <div class="field__label">Related items</div> <ul class="field field--name-f-related-items field--type-entity-reference field--label-above list-group list-group-flush field__items"> <li class="field__item list-group-item"><a href="/post/how-add-local-task-tab-drupal" hreflang="en">How to add a local task (tab) in Drupal?</a></li> </ul> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Wed, 11 Sep 2019 11:34:37 +0000 LOBsTerr 12 at http://lobsterr.me How to add a local task (tab) in Drupal? http://lobsterr.me/post/how-add-local-task-tab-drupal <span class="field field--name-title field--type-string field--label-hidden">How to add a local task (tab) in Drupal?</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">09/05/2019</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><p>In Drupal we can display secondary menu as tabs. If you don't know what it is open any content item (node) as administrator and on the top you can see:</p> <ul><li>View </li> <li>Edit</li> <li>Delete</li> </ul><p>and so on</p> <p>In this post we will review how to add a static local task</p> <p>In order to have a new tab you need to create a new YML file in the root of your module. This file has a specific name <strong>your_module_name.links.task.yml</strong>. You have to replace <strong>your_module_name </strong>with the name of your module</p> <p>Then you can define the local task you want to provide in the next format  </p> <pre> <code class="language-yaml">your_module.admin: # Unique id of your tasks normally prefixed with route name or entity name route_name: your_module.custom_settings # Route which will be opened, when we click on the tab title: 'Settings' #Title of your tab base_route: entity.node.canonical #Parent route (the default tab) parent_id: entity.node.canonical # Optional: We define the parent tab id here weight: 100 # Defines the order for the tab</code></pre> <p>Let's review a simple example. I have module <strong>local_tasks. </strong>You can find it here  <a href="https://github.com/LOBsTerr/drupal-modules-examples/tree/master/local_tasks">https://github.com/LOBsTerr/drupal-modules-examples/tree/master/local_tasks</a> or create your own.</p> <p>I have a custom page, which will provide the extra settings for nodes, in fact it will just display the title of a node for a sake of simplicity. This a route for which we are going to add a tab. You need to add it to <strong>local_tasks.routing.yml</strong></p> <p> </p> <pre> <code class="language-yaml">local_tasks.node_extra_settings: path: '/node/{node}/extra-settings' defaults: _controller: '\Drupal\local_tasks\Controller\LocalTasksController::nodeExtraSettings' _title: 'Node extra settings' requirements: _permission: 'access content' options: parameters: node: type: 'entity:node'</code></pre> <p> </p> <p>The definition of the tab you need to add to <strong>local_tasks.links.task.yml</strong></p> <pre> <code class="language-yaml"># In this example we add an additional tab to the node page local_tasks.node_extra_settings: # The ID of local task is the same as route, to make it easier to control. route_name: 'local_tasks.node_extra_settings' # The name of our route, provided in local_tasks.routing.yml. title: 'Extra settings' # This string will be displayed as a title of a tab. base_route: 'entity.node.canonical' # We use node entity in order to group tabs together. weight: 100</code></pre> <p>Now, you need install the module <strong>local_tasks </strong>or<strong> </strong>to clean the cache if you do it your own module.</p> <p>Open any node (<strong>node/[NID]</strong>), you should see a new tab "Extra settings". Also, you can open directly the page <strong>node/[NID]/extra-settings</strong></p> <p>In the next posts, we will review how to add sublevels of tabs, to define the default local task and how to add local tasks dynamically</p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/drupal-9" hreflang="en">Drupal 9</a></div> <div class="field__item btn btn-secondary"><a href="/tags/menu" hreflang="en">Menu</a></div> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Thu, 05 Sep 2019 13:54:36 +0000 LOBsTerr 11 at http://lobsterr.me