- Issue created by @cosmicdreams
- πΊπΈUnited States fathershawn New York
We are already providing a service to return a slimmer response: π Provide a means to return a simple html response on routes Fixed
The simple page provided by core only renders any system messages and the main content of the page. If we render and return the entity alone, that will be the main content of the page, and so that feature is solved by this work.We may be able to generalize to a single route, but I would want to be sure that we can account for:
- entity access
- view modes
I know that if we focus an implementation on a particular entity type, that we can hand off access checks back to core. If we have to build an access solution to provide a general route, then I would favor entity specific solutions, with possibly a base controller in the main module.
- πΊπΈUnited States cosmicdreams Minneapolis/St. Paul
This EventSubscriber seems to be responsible for what you're describing above:
<?php declare(strict_types=1); namespace Drupal\htmx\EventSubscriber; use Drupal\Core\Render\PageDisplayVariantSelectionEvent; use Drupal\Core\Render\RenderEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Drupal should return a simple page for any route with our route option set. * * @code * route.name: * ... * options: * _htmx_route: true * @endcode */ class HtmxPageDisplayVariantSubscriber implements EventSubscriberInterface { /** * Selects the simple page display variant. * * @param \Drupal\Core\Render\PageDisplayVariantSelectionEvent $event * The event to process. */ public function onSelectPageDisplayVariant(PageDisplayVariantSelectionEvent $event): void { $routeMatch = $event->getRouteMatch(); $htmxRoute = $routeMatch->getRouteObject()->getOption('_htmx_route') ?? FALSE; if ($htmxRoute) { $event->setPluginId('simple_page'); } } /** * {@inheritdoc} */ public static function getSubscribedEvents(): array { // We want to run after BlockPageDisplayVariantSubscriber. $events[RenderEvents::SELECT_PAGE_DISPLAY_VARIANT][] = ['onSelectPageDisplayVariant', -100]; return $events; } }
The documentation calls out it's function by requiring developers who are aiming to use the route to include a route parameter to opt-into using this logic.
So this appears to be an underlying mechanism one could use to create your own routes that deliver HtmlFragments for entities.
What is the difference between this implementation and what I'm describing in Problem/Motivation section of the original issue description?
In a sub-module that can be optionally turned on, we can provide an example implementation of this service by providing a route that can render an {entity_type}/{entity_id}. That would be a common use case for the service. Perhaps an excessive one.
Better yet, we could find a way to integrate with Views in providing a way to return a result as an HtmlFragment.
- πΊπΈUnited States fathershawn New York
Looks like we can use a dynamic entity based on the docblock from `\Drupal\Core\Entity\EntityAccessCheck`
/** * Checks access to the entity operation on the given route. * * The route's '_entity_access' requirement must follow the pattern * 'slug.operation'. Typically, the slug is an entity type ID, but it can be * any slug defined in the route. The route match parameter corresponding to * the slug is checked to see if it is entity-like, that is: implements * EntityInterface. Available operations are: 'view', 'update', 'create', and * 'delete'. * * For example, this route configuration invokes a permissions check for * 'update' access to entities of type 'node': * @code * pattern: '/foo/{node}/bar' * requirements: * _entity_access: 'node.update' * @endcode * And this will check 'delete' access to a dynamic entity type: * @code * example.route: * path: foo/{entity_type}/{example} * requirements: * _entity_access: example.delete * options: * parameters: * example: * type: entity:{entity_type} * @endcode * * ... */
Route path: `/htmx/{entity_type}/{entity_id}/{view_mode}`
- πΊπΈUnited States fathershawn New York
The best approach I think is a controller that renders using `\Drupal\Core\Entity\EntityViewBuilder` and it's decendents.
- πΊπΈUnited States cosmicdreams Minneapolis/St. Paul
Ah yes, view_mode, that will be important. With the addition of that, the route is what I was thinking of too.
In addition to this, I also think views integration would be awesome and maybe not that hard to implement. If we have a working Renderer of HtmlFragments then we can just call it for the View.
So far our build list includes:
To build
A service that produces HtmlFragments of an entity. Arguments: entity_type, entity_id, view_mode
A controller that accepts our arguments and uses the service, delivers responses
A route that requires arguments of entity_type and entity_id. Optionally includes view_mode (default_value: 'default')Future work
Reuse the service in a Views plugin so we can create a View that delivers an HTMX-compatible response.
- πΊπΈUnited States fathershawn New York
We don't need to build a service. Core has these services and we can use them in our controller. Less to do and maintain is a win!!
- Assigned to fathershawn
- πΊπΈUnited States fathershawn New York
Added with test. All tests passing.
-
FatherShawn β
committed f8d2be34 on 1.0.x
Issue #3437404: Proposal: Entity response service
-
FatherShawn β
committed f8d2be34 on 1.0.x
- Status changed to Fixed
6 months ago 6:24pm 23 May 2024 Automatically closed - issue fixed for 2 weeks with no activity.