| [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
post_id | 2,127,954 |
---|---|
author | develcuy |
permlink | como-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8 |
category | drupal |
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"]}" |
created | 2017-03-11 22:16:39 |
last_update | 2017-03-18 23:37:24 |
depth | 0 |
children | 3 |
net_rshares | 623,521,006,427 |
last_payout | 2017-04-11 22:53:42 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 0.027 SBD |
curator_payout_value | 0.005 SBD |
pending_payout_value | 0.000 SBD |
promoted | 0.000 SBD |
body_length | 7,910 |
author_reputation | 4,847,921,239,423 |
root_title | "CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 SBD |
percent_steem_dollars | 0 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
pairmike | 0 | 3,737,028,687 | 1% | ||
pfunk10 | 0 | 157,073,196 | 10% | ||
pheonike | 0 | 22,526,219,357 | 10.19% | ||
proctologic | 0 | 4,025,815,932 | 1% | ||
konelectric | 0 | 611,195,201 | 1% | ||
acidsun | 0 | 6,934,879,435 | 25.5% | ||
forrestwillie | 0 | 597,810,210 | 1% | ||
juanmiguelsalas | 0 | 19,143,225,111 | 100% | ||
ratel | 0 | 12,916,482,135 | 51% | ||
andrei | 0 | 245,748,982 | 1% | ||
grandpere | 0 | 25,315,451,844 | 51% | ||
tyler-fletcher | 0 | 2,431,641,696 | 51% | ||
fyrstikken | 0 | 52,492,632,369 | 2% | ||
clement | 0 | 711,802,314 | 51% | ||
isteemit | 0 | 19,566,912,903 | 51% | ||
skapaneas | 0 | 15,583,911,310 | 51% | ||
grey580 | 0 | 374,596,944 | 1% | ||
nerdlab | 0 | 519,969,451 | 51% | ||
lehard | 0 | 113,849,940 | 51% | ||
on0tole | 0 | 6,771,597,984 | 51% | ||
anasya | 0 | 8,836,452,570 | 51% | ||
vl248 | 0 | 5,168,794,492 | 51% | ||
sveokla | 0 | 2,962,448,485 | 51% | ||
marinabogumil | 0 | 5,032,152,493 | 51% | ||
anmuravjev | 0 | 208,715,046 | 51% | ||
jamesjarman | 0 | 1,705,590,335 | 1% | ||
juvyjabian | 0 | 870,898,813 | 1% | ||
raymondspeaks | 0 | 6,514,772,926 | 51% | ||
kell234 | 0 | 1,201,801,375 | 51% | ||
karenmckersie | 0 | 2,145,555,133 | 1% | ||
hyiparena | 0 | 2,742,445,816 | 51% | ||
cryptojoy.com | 0 | 363,522,298 | 51% | ||
konti | 0 | 3,292,981,207 | 51% | ||
phenom | 0 | 13,218,242,559 | 51% | ||
bitcoiner | 0 | 26,523,429,189 | 51% | ||
bola | 0 | 22,918,051,489 | 40% | ||
sharker | 0 | 5,944,974,101 | 51% | ||
zaebars | 0 | 33,893,444,243 | 51% | ||
crypto.owl | 0 | 4,129,046,082 | 51% | ||
nelu.ceban | 0 | 1,283,664,749 | 51% | ||
bkkshadow | 0 | 22,460,763,170 | 35.7% | ||
smailer | 0 | 31,427,216,082 | 51% | ||
youngkim | 0 | 436,933,114 | 1% | ||
dmilash | 0 | 11,435,255,632 | 51% | ||
dirty.hera | 0 | 95,444,376 | 51% | ||
gomeravibz | 0 | 17,653,964,264 | 51% | ||
litrbooh | 0 | 1,635,638,085 | 51% | ||
nekromarinist | 0 | 9,334,040,211 | 51% | ||
always1success | 0 | 3,470,349,376 | 51% | ||
asdes | 0 | 51,461,901 | 51% | ||
timelapse | 0 | 463,210,498 | 1% | ||
mama-steem | 0 | 939,808,274 | 51% | ||
uuuhha | 0 | 7,754,762,198 | 51% | ||
romancs | 0 | 1,799,592,475 | 51% | ||
ipumba | 0 | 1,923,068,475 | 51% | ||
riosparada | 0 | 16,220,631,867 | 51% | ||
bigsambucca | 0 | 66,958,788 | 51% | ||
steemradio | 0 | 447,004,280 | 51% | ||
krishtopa | 0 | 26,974,230,353 | 51% | ||
darthnava | 0 | 416,822,914 | 1% | ||
villainblack | 0 | 2,975,003,472 | 51% | ||
numberone | 0 | 1,882,190,787 | 51% | ||
sarita | 0 | 0 | 33% | ||
seraph | 0 | 850,709,018 | 10% | ||
wisbeech | 0 | 0 | 100% | ||
lasseehlers | 0 | 350,721,944 | 1% | ||
imag1ne | 0 | 591,754,841 | 51% | ||
leno4ek | 0 | 970,942,875 | 51% | ||
barrydutton | 0 | 1,650,364,865 | 1% | ||
jlufer | 0 | 9,037,872,189 | 100% | ||
steemitguide | 0 | 579,846,085 | 1% | ||
richardcrill | 0 | 1,456,898,549 | 1% | ||
nadin3 | 0 | 3,625,255,866 | 51% | ||
xanoxt | 0 | 13,708,406,333 | 51% | ||
victoriart | 0 | 5,893,168,969 | 51% | ||
maryfromsochi | 0 | 660,019,603 | 51% | ||
tatianka | 0 | 1,312,832,332 | 51% | ||
zettar | 0 | 760,909,471 | 51% | ||
jacobts | 0 | 275,154,051 | 1% | ||
mindhunter | 0 | 1,405,711,515 | 1% | ||
elena-singer | 0 | 3,803,784,544 | 51% | ||
patelincho | 0 | 205,711,393 | 1% | ||
burnin | 0 | 6,363,758,688 | 51% | ||
anton333 | 0 | 3,469,726,983 | 51% | ||
ekaterinka | 0 | 1,207,545,979 | 51% | ||
develcuy | 0 | 4,645,149,008 | 100% | ||
borishaifa | 0 | 4,735,133,978 | 51% | ||
mapalatv | 0 | 416,238,980 | 51% | ||
htyfn | 0 | 1,291,982,372 | 51% | ||
rusteemitblog | 0 | 4,437,301,677 | 51% | ||
dianargenti | 0 | 206,902,280 | 1% | ||
orenshani7 | 0 | 2,897,854,502 | 51% | ||
marel | 0 | 817,828,927 | 51% | ||
steemlift | 0 | 1,751,287,697 | 51% | ||
giantbear | 0 | 1,308,649,159 | 1% | ||
stray | 0 | 443,327,040 | 1% | ||
ianboil | 0 | 2,231,672,142 | 51% | ||
max-max | 0 | 1,914,386,296 | 51% | ||
daisyd | 0 | 324,266,774 | 1% | ||
garvofe | 0 | 628,403,447 | 5.09% | ||
sqube | 0 | 2,975,634,022 | 1% | ||
whatageek | 0 | 898,377,111 | 1% | ||
trans-juanmi | 0 | 6,116,061,261 | 60% | ||
chiliec | 0 | 6,250,762,186 | 51% | ||
seablue | 0 | 1,025,000,284 | 1% | ||
gildar | 0 | 1,269,271,495 | 51% | ||
killuminatic | 0 | 164,938,366 | 51% | ||
juliosalas | 0 | 968,316,730 | 60% | ||
meysam | 0 | 550,064,464 | 1% | ||
stmdxrafi | 0 | 61,435,477 | 51% | ||
steemnews24 | 0 | 70,502,081 | 51% | ||
driptorchpress | 0 | 86,890,426 | 1% | ||
roma-nt | 0 | 591,854,838 | 51% | ||
kostaslou | 0 | 714,497,317 | 51% | ||
riskdebonair | 0 | 995,683,940 | 1% | ||
fbechstein | 0 | 2,428,372,645 | 51% | ||
thedeplorable1 | 0 | 600,832,658 | 1% | ||
blockained | 0 | 93,935,168 | 51% | ||
blockchained | 0 | 3,381,812,555 | 51% | ||
marco.world | 0 | 93,932,009 | 51% | ||
tonylondon | 0 | 450,326,374 | 51% | ||
vrezh | 0 | 73,454,301 | 51% | ||
asshole | 0 | -513,891,771 | -10% | ||
benjiparler | 0 | 206,990,676 | 51% | ||
denmarkguy | 0 | 458,395,490 | 1% | ||
steemstock | 0 | 124,448,100 | 51% | ||
mestyz | 0 | 60,773,544 | 51% | ||
ambyr00 | 0 | 3,015,664,476 | 1% | ||
blckchnd | 0 | 93,760,917 | 51% | ||
evildeathcore | 0 | 382,249,921 | 51% |
<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>
post_id | 2,130,961 |
---|---|
author | screenname |
permlink | re-como-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8-20170312t131904 |
category | drupal |
json_metadata | "{"replyto": "@develcuy/como-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8"}" |
created | 2017-03-12 13:19:03 |
last_update | 2017-03-12 13:19:03 |
depth | 1 |
children | 0 |
net_rshares | 445,460,732 |
last_payout | 2017-04-11 22:53:42 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 0.000 SBD |
curator_payout_value | 0.000 SBD |
pending_payout_value | 0.000 SBD |
promoted | 0.000 SBD |
body_length | 762 |
author_reputation | 46,297,288,412,649 |
root_title | "CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 SBD |
percent_steem_dollars | 10,000 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
matrixdweller | 0 | 445,460,732 | 1% |
Great guide, thanks for the info.
post_id | 2,809,537 |
---|---|
author | wisbeech |
permlink | re-develcuy-como-agregar-enlaces-contextuales-personalizados-a-una-vista-pagina-en-drupal-8-20170517t184426615z |
category | drupal |
json_metadata | "{"app": "steemit/0.1", "tags": ["drupal"]}" |
created | 2017-05-17 18:44:24 |
last_update | 2017-05-17 18:44:24 |
depth | 1 |
children | 0 |
net_rshares | 0 |
last_payout | 2017-05-24 18:44:24 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 0.000 SBD |
curator_payout_value | 0.000 SBD |
pending_payout_value | 0.000 SBD |
promoted | 0.000 SBD |
body_length | 33 |
author_reputation | 1,910,341,943,259 |
root_title | "CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 SBD |
percent_steem_dollars | 10,000 |
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!
post_id | 2,880,221 |
---|---|
author | steemitboard |
permlink | steemitboard-notify-develcuy-20170520t043551000z |
category | drupal |
json_metadata | "{"image": ["https://steemitboard.com/img/notifications.png"]}" |
created | 2017-05-20 02:36:09 |
last_update | 2017-05-20 02:36:09 |
depth | 1 |
children | 0 |
net_rshares | 0 |
last_payout | 2017-05-27 02:36:09 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 0.000 SBD |
curator_payout_value | 0.000 SBD |
pending_payout_value | 0.000 SBD |
promoted | 0.000 SBD |
body_length | 689 |
author_reputation | 38,705,954,145,809 |
root_title | "CÓMO agregar enlaces contextuales personalizados a una vista página en Drupal 8" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 SBD |
percent_steem_dollars | 10,000 |