CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8 by develcuy

View this thread on steempeak.com
· @develcuy · (edited)
$0.03
CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8
| [English](https://steemit.com/drupal/@develcuy/adding-custom-contextual-links-to-a-views-page-in-drupal-8) | Español |

Apoyarse en enlaces contextuales (contextual links) es una excelente estrategia de usabilidad (UX), porque ayudan a que los site builders Drupal puedan interactuar con las diferentes entidades renderizadas, dentro de una vista página (views page).  Por ejemplo, es común encontrar una vista grilla (grid view) en la página de inicio (homepage). Cuando el usuario pasa el mouse encima de la vista grilla, el ícono de enlaces contextuales aparecerá, con un clic es fácil mostrar las opciones disponibles. Por defecto la única opción disponible es editar la configuración de dicha vista grilla:

http://www.steemimg.com/images/2017/02/16/example-grid-view337ae.md.png

¿No cree que hay espacio para más enlaces contextuales?

## Un caso de uso complejo

Las grillas suelen mostrar un cierto numero de elementos, tal vez cada uno con una foto, un título o una pequeña descripción. Son apenas algunos campos de ciertos tipos de contenido. Los usuarios avanzados apreciarán tener una versión de la vista grilla en "modo edición".  Podemos resolver este caso de uso agregando otra vista, con los mismos filtros y ordenamiento, pero con un formato de vista diferente, tal vez una tabla con un formulario de filtros expuestos.

http://www.steemimg.com/images/2017/02/16/example-edit-mode-view81065.md.png

¡Muy útil!

Pero aún ambas vistas no están conectadas y el modo edición no es una opción para todos. Solo ciertos usuarios privilegiados deben tener acceso al modo edición...

## ¡Enlaces contextuales al rescate!

¿Cómo agregar un enlace contextual para acceder al modo edición desde una vista grilla?

http://www.steemimg.com/images/2017/02/16/example-grid-view-contextual-links9f946.md.png

## Enlaces contextuales detrás de cámaras

Los enlaces contextuales se construyen sobre las APIs de Drupal y Symfony, con componentes front-end y back-end. El primer requerimiento es tener una ruta, por diseño Drupal solo renderizará enlaces a rutas Symfony válidas, eso hará feliz a los componentes back-end. Por el lado front-end, Drupal necesita que cada enlace contextual tenga un nombre máquina (machine_name) y el controlador es responsable de agregarlos a la página solicitada. ¡Las cosas se han complicado, lo sé! Acostúmbrese a eso porque Drupal es tan poderoso como difícil.

En buen cristiano, los enlaces contextuales son objectos que dependen de otros objectos, los cuales requieren ser declarados antes de ser agregados a la página deseada. Ahora puede leer el párrafo anterior otra vez y la documentación oficial: [Providing module-defined contextual links in Drupal 8](https://www.drupal.org/docs/8/api/menu-api/providing-module-defined-contextual-links) (Inglés).

## Declarando enlaces contextuales

El módulo <code>mimodulo</code> es el namespace de ahora en adelante. Agregue el archivo YAML <code>mimodulo.links.contextual.yml</code> dentro de la carpeta del módulo con el siguiente contenido: 

```yml
mimodulo.contextual_links:
  title: 'Edit mode (power users only)'
  route_name: view.view_id.display_id
  group: mimodulo.contextual_links
```

Note que <code>mimodulo.contextual_links</code> es exactamente el mismo para el ID y el grupo. Además la <code>route_name</code> es un objeto ruta que ya existe. Olvídese de esto y no habrá magia.

## Averiguando la <code>route_name</code> para cada vista página

Es requisito que data vista página tengan una ruta exclusiva, por ejemplo: <code>/ruta-a-mivista</code>. Además, el módulo vistas se encarga de crear la correspondiente <code>route_name</code> que terminará en algo como esto: <code>view.mivista.page_1</code> y <code>view.mivista.page_2</code>. Los nombres de ruta podrían ser simple código arbitrario, pero Drupal tiene una convención para nombramiento:

- <code>view</code>: es el prefijo para todas las rutas generadas con vistas
- <code>view_id</code>: es el machine_name de la vista deseada
- <code>display_id</code>: page_1, page_2, block_1, attachment_2, etc. No es difícil de entender.

Asumamos que nuestra página grilla tiene <code>view.mivista.page_1</code> como route_name y que <code>view.mivista.page_2</code> pertenece al modo edición (Nótese page_1 != page_2).

Este caso de uso consiste en enlazar dos vistas, pero usted podría querer agregar enlaces contextuales a otro tipo de ruta, tal vez a un nodo o a un formulario personalizado, así que tiene algo de tarea pendiente.

## Reemplazando el controlador de la vista

Cada página servida por Drupal tiene una clase controlador designada, las vistan hacen uso de <code>ViewPageController</code> en nuestro caso de uso particular. Ya que las rutas Drupal son en realidad rutas Symfony, es necesario reemplazar al controlador para poder agregar los enlaces contextuales ya declarados. ¡No se asuste! el controlador es apenas una clase extendida de <code>ViewPageController</code> y hay documentación oficial: [altering existing routes and adding new routes based on dynamic ones](https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones).

Agregue un archivo YAML <code>mimodulo.services.yml</code> dentro de la carpeta del módulo con el siguiente contenido: 
```yml
services:
  mimodulo.route_subscriber:
    class: Drupal\mimodulo\Routing\MiModuloRouteSubscriber
    tags:
      - { name: event_subscriber }
```

Lo único que debe preocuparle aquí es la <code>class</code>, que debe estar almacenada dentro del archivo: <code>src/Routing/MiModuloRouteSubscriber.php</code> con el siguiente contenido:

```php
<?php

namespace Drupal\mimodulo\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class MiModuloRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {
    // Busca el objeto ruta por su route_name
    if ($route = $collection->get('view.mivista.page_2')) {
      // Reemplaza el controlador de la vista con una versión extendida de esta
      $route->setDefault(
        '_controller',
        'Drupal\mimodulo\Routing\ViewPageController::handle'
      );
    }
  }

}
```

Si usted lee el código anterior cuidadosamente, tiene comentarios explicando cómo el controlador de la vista es reemplazado.

## Extendiendo el controlador predeterminado de la vista

Ahora que la vista ya no va a usar <code>ViewPageController</code> por defecto, sino una versión extendida, es tiempo de codear un poco más para completar la tarea. Cree el archivo <code>src/Routing/ViewPageController.php</code> con el contenido siguiente:

```php
<?php

namespace Drupal\mimodulo\Routing;

use Drupal\views\Routing\ViewPageController as BaseController;
use Drupal\Core\Routing\RouteMatchInterface;

class ViewPageController extends BaseController {

  /**
   * {@inheritdoc}
   */
  public function handle($view_id, $display_id, RouteMatchInterface $route_match) {
    // Deja que el controlador original haga su parte
    $build = parent::handle($view_id, $display_id, $route_match);

    //  Asegurarse de agregar el enlace contextual a la vista página deseada
    if ($view_id == 'mivista' && $display_id == 'page_1') {
      $build['#contextual_links']['mimodulo.contextual_links'] = [
        'route_parameters' => [
          'view' => $view_id,
        ],
        'metadata' => [
          'location' => 'page',
          'name' => $view_id,
          'display_id' => 'page_2',
        ],
      ];
    }

    return $build;
  }
}
```

## Conclusión

Se requirió apenas dos archivos YAML, dos clases y cero hooks para completar la tarea. Reconozco que no ha sido tan fácil pero aprendí más acerca de Enrutamiento, Controladores, Symfony, Drupal 8 y Conceptos de POO en el proceso ¡valió la pena!

-- @develCuy
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 65 others
👎  
properties (23)
post_id2,127,954
authordevelcuy
permlinkcomo-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8
categorydrupal
json_metadata"{"format": "markdown", "links": ["https://steemit.com/drupal/@develcuy/adding-custom-contextual-links-to-a-views-page-in-drupal-8", "https://www.drupal.org/docs/8/api/menu-api/providing-module-defined-contextual-links", "https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones"], "app": "steemit/0.1", "tags": ["drupal", "drupal-8", "symfony", "oop", "spanish"], "users": ["develcuy"], "image": ["http://www.steemimg.com/images/2017/02/16/example-grid-view337ae.md.png"]}"
created2017-03-11 22:16:39
last_update2017-03-18 23:37:24
depth0
children3
net_rshares623,521,006,427
last_payout2017-04-11 22:53:42
cashout_time1969-12-31 23:59:59
total_payout_value0.027 SBD
curator_payout_value0.005 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length7,910
author_reputation4,847,921,239,423
root_title"CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars0
author_curate_reward""
vote details (130)
@screenname ·
Re: CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8
<p>This post has been ranked within the top 50 most undervalued posts in the first half of Mar 12. We estimate that this post is undervalued by $1.66 as compared to a scenario in which every voter had an equal say.</p> 
<p>See the full rankings and details in <a href="https://steemit.com/curation/@screenname/the-daily-tribune-most-undervalued-posts-of-mar-12---part-i">The Daily Tribune: Mar 12 - Part I</a>. You can also read about some of our methodology, data analysis and technical details in <a href="https://steemit.com/curation/@screenname/introducing-the-daily-tribune-most-undervalued-posts-of-nov-04---part-i">our initial post</a>.</p>
<p>If you are the author and would prefer not to receive these comments, simply reply "Stop" to this comment.</p>
👍  
properties (23)
post_id2,130,961
authorscreenname
permlinkre-como-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8-20170312t131904
categorydrupal
json_metadata"{"replyto": "@develcuy/como-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8"}"
created2017-03-12 13:19:03
last_update2017-03-12 13:19:03
depth1
children0
net_rshares445,460,732
last_payout2017-04-11 22:53:42
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length762
author_reputation46,297,288,412,649
root_title"CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)
@wisbeech ·
Great guide, thanks for the info.
properties (22)
post_id2,809,537
authorwisbeech
permlinkre-develcuy-como-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8-20170517t184426615z
categorydrupal
json_metadata"{"app": "steemit/0.1", "tags": ["drupal"]}"
created2017-05-17 18:44:24
last_update2017-05-17 18:44:24
depth1
children0
net_rshares0
last_payout2017-05-24 18:44:24
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length33
author_reputation1,910,341,943,259
root_title"CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@steemitboard ·
Congratulations @develcuy! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

[![](https://steemitimages.com/70x80/http://steemitboard.com/notifications/votes.png)](http://steemitboard.com/@develcuy) Award for the number of upvotes

Click on any badge to view your own Board of Honnor on SteemitBoard.
For more information about SteemitBoard, click [here](https://steemit.com/steemitboard/@arcange/steemitboard-com-introducing-the-first-steemit-game-experience)

If you no longer want to receive notifications, reply to this comment with the word `STOP`

If you want to support the SteemitBoard project, your upvote for this notification is welcome!
properties (22)
post_id2,880,221
authorsteemitboard
permlinksteemitboard-notify-develcuy-20170520t043551000z
categorydrupal
json_metadata"{"image": ["https://steemitboard.com/img/notifications.png"]}"
created2017-05-20 02:36:09
last_update2017-05-20 02:36:09
depth1
children0
net_rshares0
last_payout2017-05-27 02:36:09
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length689
author_reputation38,705,954,145,809
root_title"CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000