- Issue created by @kevinquillen
- Assigned to kevinquillen
- Status changed to Needs work
over 1 year ago 5:44pm 27 November 2023 - πΊπΈUnited States kevinquillen
In order to do this, there are two possible options.
One, to enable the features natively, we can implement a new Views display plugin. This would only require the following:
namespace Drupal\views_rest_serializer_extra\Plugin\views\display; use Drupal\rest\Plugin\views\display\RestExport; /** * The plugin that handles Data response callbacks for REST resources with additional metadata. * * @ingroup views_display_plugins * * @ViewsDisplay( * id = "rest_export_extra", * title = @Translation("REST export extra"), * help = @Translation("Create a REST export resource with additional display level features, like header, empty, and footer areas."), * uses_route = TRUE, * admin = @Translation("REST export extra"), * returns_response = TRUE * ) */ class RestExportExtra extends RestExport { /** * {@inheritdoc} */ protected $usesMore = TRUE; /** * {@inheritdoc} */ protected $usesAreas = TRUE; }
That enables extra Views options for Header, Footer, Empty text and More link like other regular views. That adds the following code (which feels kludgy) to the serializer:
if ($this->view->display_handler instanceof RestExportExtra) { $area_properties = [ 'header', 'footer', 'empty' ]; foreach ($area_properties as $area) { if (!empty($this->view->{$area})) { foreach ($this->view->{$area} as $key => $plugin) { if ($plugin instanceof AreaPluginBase) { try { $render_array = $this->view->{$area}[$key]->render(); $rows['system'][$area][$key] = $this->renderer->render($render_array); } catch (\Exception $e) { $rows['system'][$area][$key] = $this->t('Could not render plain value for this view plugin.'); } } } } } if ($this->view->display_handler->getOption('use_more')) { $link = $this->view->display_handler->renderMoreLink(); if (isset($link['#url']) && isset($link['#title'])) { $url = $link['#url']; $title = $link['#title']; $rows['system']['more_link'] = [ 'url' => $url->toString(), 'title' => $title, ]; } } }
The other option is to add these options directly to the style plugin configuration like the others. That would remove the native support Views already has for these, though. Despite the code, I prefer the first method.
One drawback though is not all Area plugins should be supported, we're only expecting text. This addition
$this->view->display_handler instanceof RestExportExtra
would be required to support both REST display types.The result adds the following to a RestExportExtra views display:
Rendered output:
- Merge request !2Add a new display type that allows for areas and a more link to the output. β (Open) created by kevinquillen
- πΊπΈUnited States kevinquillen
It seems that the Facets module won't register any Views using this display as a facet source unless we define a Seach API Display plugin as well:
namespace Drupal\ views_rest_serializer_extra\Plugin\search_api\display; use Drupal\search_api\Plugin\search_api\display\ViewsDisplayBase; /** * Represents a Views REST Extra display. * * @SearchApiDisplay( * id = "views_rest_extra", * views_display_type = "rest_export_extra", * deriver = "Drupal\search_api\Plugin\search_api\display\ViewsDisplayDeriver" * ) */ class ViewsRestExtra extends ViewsDisplayBase {}
I am also seeing a lot of hard coded references to 'rest_export' in code and contrib. Doing this may not be as viable as I first thought.